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