• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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_context.h"
17 
18 #include <base/containers/fixed_string.h>
19 #include <base/containers/vector.h>
20 #include <core/intf_engine.h>
21 #include <core/io/intf_file_manager.h>
22 #include <core/plugin/intf_class_register.h>
23 
24 #if (RENDER_PERF_ENABLED == 1)
25 #include <core/perf/intf_performance_data_manager.h>
26 #endif
27 
28 #include "datastore/render_data_store_default_acceleration_structure_staging.h"
29 #include "datastore/render_data_store_default_gpu_resource_data_copy.h"
30 #include "datastore/render_data_store_default_staging.h"
31 #include "datastore/render_data_store_fullscreen_shader.h"
32 #include "datastore/render_data_store_manager.h"
33 #include "datastore/render_data_store_pod.h"
34 #include "default_engine_constants.h"
35 #include "device/device.h"
36 #include "device/shader_manager.h"
37 #include "loader/render_data_loader.h"
38 #include "node/core_render_node_factory.h"
39 #include "nodecontext/render_node_graph_manager.h"
40 #include "nodecontext/render_node_graph_node_store.h"
41 #include "nodecontext/render_node_manager.h"
42 #include "renderer.h"
43 #include "util/render_util.h"
44 
45 #if RENDER_HAS_VULKAN_BACKEND
46 #include "vulkan/device_vk.h"
47 #endif
48 
49 #if (RENDER_HAS_GL_BACKEND) || (RENDER_HAS_GLES_BACKEND)
50 #include "gles/device_gles.h"
51 #include "gles/swapchain_gles.h"
52 #endif
53 
54 #include <algorithm>
55 
56 using namespace BASE_NS;
57 using namespace CORE_NS;
58 
59 RENDER_BEGIN_NAMESPACE()
60 namespace {
61 struct RegisterPathStrings {
62     string_view protocol;
63     string_view uri;
64 };
65 static constexpr RegisterPathStrings RENDER_DATA_PATHS[] = {
66     { "rendershaders", "rofsRndr://shaders/" },
67     { "rendershaderstates", "rofsRndr://shaderstates/" },
68     { "rendervertexinputdeclarations", "rofsRndr://vertexinputdeclarations/" },
69     { "renderpipelinelayouts", "rofsRndr://pipelinelayouts/" },
70     { "renderrenderdataconfigurations", "rofsRndr://renderdataconfigurations/" },
71     { "renderrendernodegraphs", "rofsRndr://rendernodegraphs/" },
72 };
73 
74 #if (RENDER_EMBEDDED_ASSETS_ENABLED == 1)
75 // Core Rofs Data.
76 extern "C" const uint64_t SIZEOFDATAFORRENDER;
77 extern "C" const void* const BINARYDATAFORRENDER[];
78 #endif
79 
80 // This is defined in the CMake generated version.cpp
LogRenderBuildInfo()81 void LogRenderBuildInfo()
82 {
83 #define RENDER_TO_STRING_INTERNAL(x) #x
84 #define RENDER_TO_STRING(x) RENDER_TO_STRING_INTERNAL(x)
85 
86     PLUGIN_LOG_I("Build info:");
87     PLUGIN_LOG_I("  RENDER_VALIDATION_ENABLED=" RENDER_TO_STRING(RENDER_VALIDATION_ENABLED));
88     PLUGIN_LOG_I("  RENDER_DEV_ENABLED=" RENDER_TO_STRING(RENDER_DEV_ENABLED));
89 }
90 
91 template<class RenderDataStoreType>
FillRenderDataStoreTypeInfo()92 RenderDataStoreTypeInfo FillRenderDataStoreTypeInfo()
93 {
94     return {
95         { RenderDataStoreTypeInfo::UID },
96         RenderDataStoreType::UID,
97         RenderDataStoreType::TYPE_NAME,
98         RenderDataStoreType::Create,
99         RenderDataStoreType::Destroy,
100     };
101 }
102 
RegisterCoreRenderDataStores(RenderDataStoreManager & renderDataStoreManager)103 void RegisterCoreRenderDataStores(RenderDataStoreManager& renderDataStoreManager)
104 {
105     renderDataStoreManager.AddRenderDataStoreFactory(FillRenderDataStoreTypeInfo<RenderDataStorePod>());
106     renderDataStoreManager.AddRenderDataStoreFactory(
107         FillRenderDataStoreTypeInfo<RenderDataStoreDefaultAccelerationStructureStaging>());
108     renderDataStoreManager.AddRenderDataStoreFactory(FillRenderDataStoreTypeInfo<RenderDataStoreDefaultStaging>());
109     renderDataStoreManager.AddRenderDataStoreFactory(
110         FillRenderDataStoreTypeInfo<RenderDataStoreDefaultGpuResourceDataCopy>());
111     renderDataStoreManager.AddRenderDataStoreFactory(FillRenderDataStoreTypeInfo<RenderDataStoreFullscreenShader>());
112 }
113 
114 template<typename DataStoreType>
CreateDataStore(IRenderDataStoreManager & renderDataStoreManager,const string_view name)115 IRenderDataStore* CreateDataStore(IRenderDataStoreManager& renderDataStoreManager, const string_view name)
116 {
117     IRenderDataStore* renderDataStore = renderDataStoreManager.Create(DataStoreType::UID, name.data());
118     PLUGIN_ASSERT(renderDataStore);
119     return renderDataStore;
120 }
121 
CreateDefaultRenderDataStores(IRenderDataStoreManager & renderDataStoreManager,RenderDataLoader & renderDataLoader)122 void CreateDefaultRenderDataStores(IRenderDataStoreManager& renderDataStoreManager, RenderDataLoader& renderDataLoader)
123 {
124     // add pod store
125     {
126         auto renderDataStorePod = CreateDataStore<RenderDataStorePod>(renderDataStoreManager, "RenderDataStorePod");
127         if (renderDataStorePod) {
128             IRenderDataStorePod* renderDataStorePodTyped = static_cast<IRenderDataStorePod*>(renderDataStorePod);
129 
130             NodeGraphBackBufferConfiguration backBufferConfig {};
131             const auto len =
132                 DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER.copy(backBufferConfig.backBufferName,
133                     NodeGraphBackBufferConfiguration::CORE_MAX_BACK_BUFFER_NAME_LENGTH - 1);
134             backBufferConfig.backBufferName[len] = '\0';
135             renderDataStorePodTyped->CreatePod(
136                 "NodeGraphConfiguration", "NodeGraphBackBufferConfiguration", arrayviewU8(backBufferConfig));
137 
138             // load and store configurations
139             renderDataLoader.Load("render", *renderDataStorePodTyped);
140         }
141     }
142 
143     CreateDataStore<RenderDataStoreDefaultAccelerationStructureStaging>(
144         renderDataStoreManager, "RenderDataStoreDefaultAccelerationStructureStaging");
145     CreateDataStore<RenderDataStoreDefaultStaging>(renderDataStoreManager, "RenderDataStoreDefaultStaging");
146     CreateDataStore<RenderDataStoreDefaultGpuResourceDataCopy>(
147         renderDataStoreManager, "RenderDataStoreDefaultGpuResourceDataCopy");
148     CreateDataStore<RenderDataStoreFullscreenShader>(renderDataStoreManager, "RenderDataStoreFullscreenShader");
149 }
150 
CreateDefaultBuffers(IGpuResourceManager & gpuResourceMgr,vector<RenderHandleReference> & defaultGpuResources)151 void CreateDefaultBuffers(IGpuResourceManager& gpuResourceMgr, vector<RenderHandleReference>& defaultGpuResources)
152 {
153     defaultGpuResources.push_back(gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_GPU_BUFFER,
154         GpuBufferDesc { CORE_BUFFER_USAGE_TRANSFER_SRC_BIT | CORE_BUFFER_USAGE_TRANSFER_DST_BIT |
155                             CORE_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | CORE_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
156                             CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT | CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT |
157                             CORE_BUFFER_USAGE_INDEX_BUFFER_BIT | CORE_BUFFER_USAGE_VERTEX_BUFFER_BIT |
158                             CORE_BUFFER_USAGE_INDIRECT_BUFFER_BIT | CORE_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT |
159                             CORE_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT,
160             (CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT), 0u, 1024u }));
161 }
162 
CreateDefaultTextures(IGpuResourceManager & gpuResourceMgr,vector<RenderHandleReference> & defaultGpuResources)163 void CreateDefaultTextures(IGpuResourceManager& gpuResourceMgr, vector<RenderHandleReference>& defaultGpuResources)
164 {
165     GpuImageDesc desc { ImageType::CORE_IMAGE_TYPE_2D, ImageViewType::CORE_IMAGE_VIEW_TYPE_2D,
166         Format::BASE_FORMAT_R8G8B8A8_SRGB, ImageTiling::CORE_IMAGE_TILING_OPTIMAL,
167         ImageUsageFlagBits::CORE_IMAGE_USAGE_SAMPLED_BIT | ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSFER_DST_BIT,
168         MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
169         0, // ImageCreateFlags
170         0, // EngineImageCreationFlags
171         2, 2, 1, 1, 1, SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT, {} };
172 
173     constexpr uint32_t sizeOfUint32 = sizeof(uint32_t);
174     constexpr const uint32_t rgbData[4u] = { 0x0, 0x0, 0x0, 0x0 };
175     const auto rgbDataView = array_view(reinterpret_cast<const uint8_t*>(rgbData), sizeOfUint32 * countof(rgbData));
176     defaultGpuResources.push_back(
177         gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_GPU_IMAGE, desc, rgbDataView));
178     constexpr const uint32_t rgbDataWhite[4u] = { 0xff, 0xff, 0xff, 0xff };
179     const auto rgbDataViewWhite =
180         array_view(reinterpret_cast<const uint8_t*>(rgbDataWhite), sizeOfUint32 * countof(rgbDataWhite));
181     defaultGpuResources.push_back(
182         gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_GPU_IMAGE_WHITE, desc, rgbDataViewWhite));
183 }
184 
CreateDefaultTargets(IGpuResourceManager & gpuResourceMgr,vector<RenderHandleReference> & defaultGpuResources)185 void CreateDefaultTargets(IGpuResourceManager& gpuResourceMgr, vector<RenderHandleReference>& defaultGpuResources)
186 {
187     {
188         // hard-coded default backbuffer
189         // all presentations and swapchain semaphore syncs are done automatically for this client handle
190         GpuImageDesc desc {
191             ImageType::CORE_IMAGE_TYPE_2D,
192             ImageViewType::CORE_IMAGE_VIEW_TYPE_2D,
193             Format::BASE_FORMAT_R8G8B8A8_UNORM,
194             ImageTiling::CORE_IMAGE_TILING_OPTIMAL,
195             ImageUsageFlagBits::CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
196             MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
197             0, // ImageCreateFlags
198             EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS |
199                 EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, // EngineImageCreationFlags
200             2,
201             2,
202             1,
203             1,
204             1,
205             SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT,
206             {},
207         };
208         defaultGpuResources.push_back(
209             gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER, desc));
210     }
211     {
212         GpuImageDesc desc {
213             ImageType::CORE_IMAGE_TYPE_2D,
214             ImageViewType::CORE_IMAGE_VIEW_TYPE_2D,
215             Format::BASE_FORMAT_D16_UNORM,
216             ImageTiling::CORE_IMAGE_TILING_OPTIMAL,
217             ImageUsageFlagBits::CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
218                 ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
219             MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
220                 MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT,
221             0,                                                                        // ImageCreateFlags
222             EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, // EngineImageCreationFlags
223             2,
224             2,
225             1,
226             1,
227             1,
228             SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT,
229             {},
230         };
231         defaultGpuResources.push_back(
232             gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER_DEPTH, desc));
233     }
234 }
235 
CreateDefaultSamplers(IGpuResourceManager & gpuResourceMgr,vector<RenderHandleReference> & defaultGpuResources)236 void CreateDefaultSamplers(IGpuResourceManager& gpuResourceMgr, vector<RenderHandleReference>& defaultGpuResources)
237 {
238     defaultGpuResources.push_back(
239         gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_NEAREST_REPEAT,
240             GpuSamplerDesc {
241                 Filter::CORE_FILTER_NEAREST,                          // magFilter
242                 Filter::CORE_FILTER_NEAREST,                          // minFilter
243                 Filter::CORE_FILTER_NEAREST,                          // mipMapMode
244                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeU
245                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeV
246                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeW
247             }));
248     defaultGpuResources.push_back(
249         gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_NEAREST_CLAMP,
250             GpuSamplerDesc {
251                 Filter::CORE_FILTER_NEAREST,                                 // magFilter
252                 Filter::CORE_FILTER_NEAREST,                                 // minFilter
253                 Filter::CORE_FILTER_NEAREST,                                 // mipMapMode
254                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
255                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
256                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
257             }));
258 
259     defaultGpuResources.push_back(
260         gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_REPEAT,
261             GpuSamplerDesc {
262                 Filter::CORE_FILTER_LINEAR,                           // magFilter
263                 Filter::CORE_FILTER_LINEAR,                           // minFilter
264                 Filter::CORE_FILTER_LINEAR,                           // mipMapMode
265                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeU
266                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeV
267                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeW
268             }));
269     defaultGpuResources.push_back(
270         gpuResourceMgr.Create(DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP,
271             GpuSamplerDesc {
272                 Filter::CORE_FILTER_LINEAR,                                  // magFilter
273                 Filter::CORE_FILTER_LINEAR,                                  // minFilter
274                 Filter::CORE_FILTER_LINEAR,                                  // mipMapMode
275                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
276                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
277                 SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
278             }));
279 
280     GpuSamplerDesc linearMipmapRepeat {
281         Filter::CORE_FILTER_LINEAR,                           // magFilter
282         Filter::CORE_FILTER_LINEAR,                           // minFilter
283         Filter::CORE_FILTER_LINEAR,                           // mipMapMode
284         SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeU
285         SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeV
286         SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_REPEAT, // addressModeW
287     };
288     linearMipmapRepeat.minLod = 0.0f;
289     linearMipmapRepeat.maxLod = 32.0f;
290     defaultGpuResources.push_back(gpuResourceMgr.Create(
291         DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_REPEAT, linearMipmapRepeat));
292     GpuSamplerDesc linearMipmapClamp {
293         Filter::CORE_FILTER_LINEAR,                                  // magFilter
294         Filter::CORE_FILTER_LINEAR,                                  // minFilter
295         Filter::CORE_FILTER_LINEAR,                                  // mipMapMode
296         SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
297         SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
298         SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
299     };
300     linearMipmapClamp.minLod = 0.0f;
301     linearMipmapClamp.maxLod = 32.0f;
302     defaultGpuResources.push_back(gpuResourceMgr.Create(
303         DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_CLAMP, linearMipmapClamp));
304 }
305 } // namespace
306 
CreateInstance(IEngine & engine)307 IRenderContext* RenderPluginState::CreateInstance(IEngine& engine)
308 {
309     if (!context_) {
310         context_ = IRenderContext::Ptr { new RenderContext(*this, engine) };
311     }
312     return context_.get();
313 }
314 
GetInstance()315 IRenderContext* RenderPluginState::GetInstance()
316 {
317     return context_.get();
318 }
319 
Destroy()320 void RenderPluginState::Destroy()
321 {
322     context_.reset();
323 }
324 
RenderContext(RenderPluginState & pluginState,IEngine & engine)325 RenderContext::RenderContext(RenderPluginState& pluginState, IEngine& engine)
326     : pluginState_(pluginState), engine_(engine), fileManager_(&engine.GetFileManager())
327 {
328     RegisterInterfaceType(interfaceInfo_);
329     LogRenderBuildInfo();
330     RegisterDefaultPaths();
331 }
332 
~RenderContext()333 RenderContext::~RenderContext()
334 {
335     GetPluginRegister().RemoveListener(*this);
336 
337     for (auto& info : plugins_) {
338         if (info.second && info.second->destroyPlugin) {
339             info.second->destroyPlugin(info.first);
340         }
341     }
342 
343     // NOTE: device needs to be active for render resources (e.g. with GLES)
344     if (device_) {
345         device_->Activate();
346     }
347     defaultGpuResources_.clear();
348     renderer_.reset();
349     renderNodeGraphMgr_.reset();
350     renderDataStoreMgr_.reset();
351     if (device_) {
352         device_->Deactivate();
353     }
354 }
355 
Init(const RenderCreateInfo & createInfo)356 RenderResultCode RenderContext::Init(const RenderCreateInfo& createInfo)
357 {
358     PLUGIN_LOG_D("Render init.");
359 
360     device_ = CreateDevice(createInfo.deviceCreateInfo);
361     if (!device_) {
362         PLUGIN_LOG_E("device not created successfully, invalid render interface");
363         return RenderResultCode::RENDER_ERROR;
364     } else {
365         device_->Activate();
366 
367         renderUtil_ = make_unique<RenderUtil>(*this);
368 
369         // set engine file manager with registered paths
370         ShaderManager& shaderMgr = (ShaderManager&)device_->GetShaderManager();
371         shaderMgr.SetFileManager(engine_.GetFileManager());
372 
373         {
374             IShaderManager::ShaderFilePathDesc desc;
375             desc.shaderPath = "rendershaders://";
376             // NOTE: does not have states, pls and vids
377             shaderMgr.LoadShaderFiles(desc);
378         }
379         // make sure shaders found above have been created
380         shaderMgr.HandlePendingAllocations();
381 
382         renderDataStoreMgr_ = make_unique<RenderDataStoreManager>(*this);
383         RegisterCoreRenderDataStores(*renderDataStoreMgr_);
384 
385         // Add render data stores from plugins
386         for (auto info : CORE_NS::GetPluginRegister().GetTypeInfos(RenderDataStoreTypeInfo::UID)) {
387             renderDataStoreMgr_->AddRenderDataStoreFactory(*static_cast<const RenderDataStoreTypeInfo*>(info));
388         }
389 
390         auto loader = RenderDataLoader(*fileManager_);
391         CreateDefaultRenderDataStores(*renderDataStoreMgr_, loader);
392 
393         renderNodeGraphMgr_ = make_unique<RenderNodeGraphManager>(*device_, *fileManager_);
394 
395         auto& renderNodeMgr = renderNodeGraphMgr_->GetRenderNodeManager();
396         RegisterCoreRenderNodes(renderNodeMgr);
397         // Add render nodes from plugins
398         for (auto info : CORE_NS::GetPluginRegister().GetTypeInfos(RenderNodeTypeInfo::UID)) {
399             renderNodeMgr.AddRenderNodeFactory(*static_cast<const RenderNodeTypeInfo*>(info));
400         }
401 
402         renderer_ = make_unique<Renderer>(*this);
403 
404         IGpuResourceManager& gpuResourceMgr = device_->GetGpuResourceManager();
405         CreateDefaultBuffers(gpuResourceMgr, defaultGpuResources_);
406         CreateDefaultTextures(gpuResourceMgr, defaultGpuResources_);
407         CreateDefaultTargets(gpuResourceMgr, defaultGpuResources_);
408         CreateDefaultSamplers(gpuResourceMgr, defaultGpuResources_);
409 
410         device_->Deactivate();
411 
412         GetPluginRegister().AddListener(*this);
413 
414         for (auto info : CORE_NS::GetPluginRegister().GetTypeInfos(IRenderPlugin::UID)) {
415             if (auto renderPlugin = static_cast<const IRenderPlugin*>(info);
416                 renderPlugin && renderPlugin->createPlugin) {
417                 auto token = renderPlugin->createPlugin(*this);
418                 plugins_.push_back({ token, renderPlugin });
419             }
420         }
421 
422         return RenderResultCode::RENDER_SUCCESS;
423     }
424 }
425 
GetDevice() const426 IDevice& RenderContext::GetDevice() const
427 {
428     if (!device_) {
429         PLUGIN_LOG_E("Render Init not called or result was not success");
430     }
431     return *device_;
432 }
433 
GetRenderer() const434 IRenderer& RenderContext::GetRenderer() const
435 {
436     if (!renderer_) {
437         PLUGIN_LOG_E("Render Init not called or result was not success");
438     }
439     return *renderer_;
440 }
441 
GetRenderDataStoreManager() const442 IRenderDataStoreManager& RenderContext::GetRenderDataStoreManager() const
443 {
444     if (!renderDataStoreMgr_) {
445         PLUGIN_LOG_E("Render Init not called or result was not success");
446     }
447     return *renderDataStoreMgr_;
448 }
449 
GetRenderNodeGraphManager() const450 IRenderNodeGraphManager& RenderContext::GetRenderNodeGraphManager() const
451 {
452     if (!renderNodeGraphMgr_) {
453         PLUGIN_LOG_E("Render Init not called or result was not success");
454     }
455     return *renderNodeGraphMgr_;
456 }
457 
GetRenderUtil() const458 IRenderUtil& RenderContext::GetRenderUtil() const
459 {
460     if (!renderUtil_) {
461         PLUGIN_LOG_E("Render Init not called or result was not success");
462     }
463     return *renderUtil_;
464 }
465 
RegisterDefaultPaths()466 void RenderContext::RegisterDefaultPaths()
467 {
468     // Already handeled during plugin registration. If own filemanager instance is used then these are needed.
469 #if (RENDER_EMBEDDED_ASSETS_ENABLED == 1)
470     // Create engine:// protocol that points to embedded engine asset files.
471     PLUGIN_LOG_I("Registered core asset path: 'rofsRndr://render/'");
472     fileManager_->RegisterPath("render", "rofsRndr://render/", false);
473 #endif
474     for (uint32_t idx = 0; idx < countof(RENDER_DATA_PATHS); ++idx) {
475         fileManager_->RegisterPath(RENDER_DATA_PATHS[idx].protocol, RENDER_DATA_PATHS[idx].uri, false);
476     }
477 }
478 
CreateDevice(const DeviceCreateInfo & createInfo)479 unique_ptr<Device> RenderContext::CreateDevice(const DeviceCreateInfo& createInfo)
480 {
481     switch (createInfo.backendType) {
482         case DeviceBackendType::OPENGL:
483 #if (RENDER_HAS_GL_BACKEND)
484             return CreateDeviceGL(*this, createInfo);
485 #else
486             return nullptr;
487 #endif
488         case DeviceBackendType::OPENGLES:
489 #if (RENDER_HAS_GLES_BACKEND)
490             return CreateDeviceGLES(*this, createInfo);
491 #else
492             return nullptr;
493 #endif
494         case DeviceBackendType::VULKAN:
495 #if (RENDER_HAS_VULKAN_BACKEND)
496             return CreateDeviceVk(*this, createInfo);
497 #else
498             return nullptr;
499 #endif
500         default:
501             break;
502     }
503     return nullptr;
504 }
505 
GetEngine() const506 IEngine& RenderContext::GetEngine() const
507 {
508     return engine_;
509 }
510 
GetVersion()511 string_view RenderContext::GetVersion()
512 {
513     return {};
514 }
515 
GetInterface(const Uid & uid) const516 const IInterface* RenderContext::GetInterface(const Uid& uid) const
517 {
518     if (uid == IRenderContext::UID) {
519         return static_cast<const IRenderContext*>(this);
520     } else if (uid == IClassFactory::UID) {
521         return static_cast<const IClassFactory*>(this);
522     } else if (uid == IClassRegister::UID) {
523         return static_cast<const IClassRegister*>(this);
524     }
525     return nullptr;
526 }
527 
GetInterface(const Uid & uid)528 IInterface* RenderContext::GetInterface(const Uid& uid)
529 {
530     if (uid == IRenderContext::UID) {
531         return static_cast<IRenderContext*>(this);
532     } else if (uid == IClassFactory::UID) {
533         return static_cast<IClassFactory*>(this);
534     } else if (uid == IClassRegister::UID) {
535         return static_cast<IClassRegister*>(this);
536     }
537     return nullptr;
538 }
539 
Ref()540 void RenderContext::Ref()
541 {
542     refCount_++;
543 }
544 
Unref()545 void RenderContext::Unref()
546 {
547     if (--refCount_ == 1) {
548         pluginState_.Destroy();
549         delete this;
550     }
551 }
552 
CreateInstance(const Uid & uid)553 IInterface::Ptr RenderContext::CreateInstance(const Uid& uid)
554 {
555     const auto& data = GetInterfaceMetadata(uid);
556     if (data.createInterface) {
557         return IInterface::Ptr { data.createInterface(*this, data.token) };
558     }
559     return {};
560 }
561 
RegisterInterfaceType(const InterfaceTypeInfo & interfaceInfo)562 void RenderContext::RegisterInterfaceType(const InterfaceTypeInfo& interfaceInfo)
563 {
564     // keep interfaceTypeInfos_ sorted according to UIDs
565     const auto pos = std::upper_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid,
566         [](Uid value, const InterfaceTypeInfo* element) { return value < element->uid; });
567     interfaceTypeInfos_.insert(pos, &interfaceInfo);
568 }
569 
UnregisterInterfaceType(const InterfaceTypeInfo & interfaceInfo)570 void RenderContext::UnregisterInterfaceType(const InterfaceTypeInfo& interfaceInfo)
571 {
572     if (!interfaceTypeInfos_.empty()) {
573         const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid,
574             [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; });
575         if ((*pos)->uid == interfaceInfo.uid) {
576             interfaceTypeInfos_.erase(pos);
577         }
578     }
579 }
580 
GetInterfaceMetadata() const581 array_view<const InterfaceTypeInfo* const> RenderContext::GetInterfaceMetadata() const
582 {
583     return interfaceTypeInfos_;
584 }
585 
GetInterfaceMetadata(const Uid & uid) const586 const InterfaceTypeInfo& RenderContext::GetInterfaceMetadata(const Uid& uid) const
587 {
588     static InterfaceTypeInfo invalidType {};
589 
590     if (!interfaceTypeInfos_.empty()) {
591         const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), uid,
592             [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; });
593         if ((*pos) && (*pos)->uid == uid) {
594             return *(*pos);
595         }
596     }
597     return invalidType;
598 }
599 
GetInstance(const Uid & uid) const600 IInterface* RenderContext::GetInstance(const Uid& uid) const
601 {
602     const auto& data = GetInterfaceMetadata(uid);
603     if (data.getInterface) {
604         return data.getInterface(const_cast<RenderContext&>(*this), data.token);
605     }
606     return nullptr;
607 }
608 
OnTypeInfoEvent(EventType type,array_view<const ITypeInfo * const> typeInfos)609 void RenderContext::OnTypeInfoEvent(EventType type, array_view<const ITypeInfo* const> typeInfos)
610 {
611     auto& renderNodeMgr = renderNodeGraphMgr_->GetRenderNodeManager();
612     if (type == EventType::ADDED) {
613         for (const auto* info : typeInfos) {
614             if (info && info->typeUid == IRenderPlugin::UID && static_cast<const IRenderPlugin*>(info)->createPlugin) {
615                 auto renderPlugin = static_cast<const IRenderPlugin*>(info);
616                 if (std::none_of(plugins_.begin(), plugins_.end(),
617                         [renderPlugin](const pair<PluginToken, const IRenderPlugin*>& pluginData) {
618                             return pluginData.second == renderPlugin;
619                         })) {
620                     auto token = renderPlugin->createPlugin(*this);
621                     plugins_.push_back({ token, renderPlugin });
622                 }
623             } else if (info && info->typeUid == RenderDataStoreTypeInfo::UID) {
624                 renderDataStoreMgr_->AddRenderDataStoreFactory(*static_cast<const RenderDataStoreTypeInfo*>(info));
625             } else if (info && info->typeUid == RenderNodeTypeInfo::UID) {
626                 renderNodeMgr.AddRenderNodeFactory(*static_cast<const RenderNodeTypeInfo*>(info));
627             }
628         }
629     } else if (type == EventType::REMOVED) {
630         for (const auto* info : typeInfos) {
631             if (info && info->typeUid == IRenderPlugin::UID) {
632                 auto renderPlugin = static_cast<const IRenderPlugin*>(info);
633                 if (auto pos = std::find_if(plugins_.begin(), plugins_.end(),
634                         [renderPlugin](const pair<PluginToken, const IRenderPlugin*>& pluginData) {
635                             return pluginData.second == renderPlugin;
636                         });
637                     pos != plugins_.end()) {
638                     if (renderPlugin->destroyPlugin) {
639                         renderPlugin->destroyPlugin(pos->first);
640                     }
641                     plugins_.erase(pos);
642                 }
643             } else if (info && info->typeUid == RenderDataStoreTypeInfo::UID) {
644                 renderDataStoreMgr_->RemoveRenderDataStoreFactory(*static_cast<const RenderDataStoreTypeInfo*>(info));
645             } else if (info && info->typeUid == RenderNodeTypeInfo::UID) {
646                 renderNodeGraphMgr_->Destroy(static_cast<const RenderNodeTypeInfo*>(info)->typeName);
647                 renderNodeMgr.RemoveRenderNodeFactory(*static_cast<const RenderNodeTypeInfo*>(info));
648             }
649         }
650     }
651 }
652 
653 RENDER_END_NAMESPACE()
654