1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "render_resource_manager.h"
16
17 #include <scene/ext/util.h>
18
19 #include <core/image/intf_image_loader_manager.h>
20 #include <core/intf_engine.h>
21 #include <render/device/intf_gpu_resource_manager.h>
22
23 #include <meta/interface/resource/intf_resource.h>
24
SCENE_BEGIN_NAMESPACE()25 SCENE_BEGIN_NAMESPACE()
26
27 bool RenderResourceManager::Build(const META_NS::IMetadata::Ptr& d)
28 {
29 bool res = Super::Build(d);
30 if (res) {
31 context_ = GetInterfaceBuildArg<IRenderContext>(d, "RenderContext");
32 if (!context_) {
33 CORE_LOG_E("Invalid arguments to construct RenderResourceManager");
34 return false;
35 }
36 }
37 return res;
38 }
39
SetImageInfoFlags(const ImageInfo & info,RENDER_NS::GpuImageDesc & desc)40 static RENDER_NS::GpuImageDesc SetImageInfoFlags(const ImageInfo& info, RENDER_NS::GpuImageDesc& desc)
41 {
42 desc.usageFlags |= static_cast<uint32_t>(info.usageFlags);
43 desc.memoryPropertyFlags |= static_cast<uint32_t>(info.memoryFlags);
44 desc.engineCreationFlags |= static_cast<uint32_t>(info.creationFlags);
45 return desc;
46 }
47
ConvertToImageDesc(const ImageCreateInfo & info)48 static RENDER_NS::GpuImageDesc ConvertToImageDesc(const ImageCreateInfo& info)
49 {
50 RENDER_NS::GpuImageDesc desc;
51
52 desc.width = info.size.x;
53 desc.height = info.size.y;
54 desc.format = info.format;
55
56 return SetImageInfoFlags(info.info, desc);
57 }
58
ConstructImage(const IRenderContext::Ptr & context,RENDER_NS::RenderHandleReference handle)59 static IImage::Ptr ConstructImage(const IRenderContext::Ptr& context, RENDER_NS::RenderHandleReference handle)
60 {
61 auto image = META_NS::GetObjectRegistry().Create<IImage>(ClassId::Image, CreateRenderContextArg(context));
62 if (auto i = interface_cast<IRenderResource>(image)) {
63 i->SetRenderHandle(BASE_NS::move(handle));
64 }
65 return image;
66 }
67
CreateImage(const ImageCreateInfo & info,BASE_NS::vector<uint8_t> d)68 Future<IImage::Ptr> RenderResourceManager::CreateImage(const ImageCreateInfo& info, BASE_NS::vector<uint8_t> d)
69 {
70 return context_->AddTask([=, desc = ConvertToImageDesc(info), data = BASE_NS::move(d)] {
71 auto& gpuResMan = context_->GetRenderer()->GetDevice().GetGpuResourceManager();
72 RENDER_NS::RenderHandleReference handle;
73 if (data.empty()) {
74 handle = gpuResMan.Create(desc);
75 } else {
76 handle = gpuResMan.Create(desc, data);
77 }
78 return ConstructImage(context_, BASE_NS::move(handle));
79 });
80 }
LoadImage(BASE_NS::string_view uri,const ImageLoadInfo & info)81 Future<IImage::Ptr> RenderResourceManager::LoadImage(BASE_NS::string_view uri, const ImageLoadInfo& info)
82 {
83 return context_->AddTask([=, path = BASE_NS::string(uri)] {
84 auto& gpuResMan = context_->GetRenderer()->GetDevice().GetGpuResourceManager();
85 auto& loader = context_->GetRenderer()->GetEngine().GetImageLoaderManager();
86 auto loadResult = loader.LoadImage(path, static_cast<uint32_t>(info.loadFlags));
87 if (!loadResult.success) {
88 CORE_LOG_E("Failed to load image (%s): %s", path.c_str(), loadResult.error);
89 return IImage::Ptr {};
90 }
91 auto gpuDesc = gpuResMan.CreateGpuImageDesc(loadResult.image->GetImageDesc());
92 SetImageInfoFlags(info.info, gpuDesc);
93 auto handle = gpuResMan.Create(uri, gpuDesc, std::move(loadResult.image));
94 return ConstructImage(context_, BASE_NS::move(handle));
95 });
96 }
97
ConstructShader(const IRenderContext::Ptr & context,RENDER_NS::RenderHandleReference handle)98 static IShader::Ptr ConstructShader(const IRenderContext::Ptr& context, RENDER_NS::RenderHandleReference handle)
99 {
100 auto shader = META_NS::GetObjectRegistry().Create<IShader>(ClassId::Shader, CreateRenderContextArg(context));
101 if (auto i = interface_cast<IShaderState>(shader)) {
102 auto& man = context->GetRenderer()->GetDevice().GetShaderManager();
103 i->SetShaderState(handle, man.GetGraphicsStateHandleByShaderHandle(handle));
104 }
105 return shader;
106 }
107
LoadShader(BASE_NS::string_view uri)108 Future<IShader::Ptr> RenderResourceManager::LoadShader(BASE_NS::string_view uri)
109 {
110 if (uri.empty()) {
111 CORE_LOG_E("Cannot load shader from empty URI");
112 return {};
113 }
114 return context_->AddTask([=, path = BASE_NS::string(uri)] {
115 auto& man = context_->GetRenderer()->GetDevice().GetShaderManager();
116 man.LoadShaderFile(path);
117 IShader::Ptr res;
118 if (auto handle = man.GetShaderHandle(path)) {
119 res = ConstructShader(context_, BASE_NS::move(handle));
120 }
121 return res;
122 });
123 }
124
125 SCENE_END_NAMESPACE()
126