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 <scene_plugin/api/material_uid.h> 16 17#include <meta/ext/concrete_base_object.h> 18 19#include "bind_templates.inl" 20#include "node_impl.h" 21 22namespace { 23class GraphicsStateImpl : public META_NS::ObjectFwd<GraphicsStateImpl, SCENE_NS::ClassId::GraphicsState, 24 META_NS::ClassId::Object, SCENE_NS::IGraphicsState, ISceneHolderRef> { 25 META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::IGraphicsState, BASE_NS::string, Uri, "") 26 META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::IGraphicsState, BASE_NS::string, Variant, "") 27 28 bool Build(const IMetadata::Ptr& data) override 29 { 30 return true; 31 } 32 33 RENDER_NS::RenderHandleReference GetRenderHandleReference(RENDER_NS::IShaderManager& shaderManager) override 34 { 35 if (RENDER_NS::RenderHandleUtil::IsValid(renderHandleReference_.GetHandle())) { 36 return renderHandleReference_; 37 } 38 39 auto uri = GetValue(META_ACCESS_PROPERTY(Uri)); 40 auto variant = GetValue(META_ACCESS_PROPERTY(Variant)); 41 42 renderHandleReference_ = shaderManager.GetGraphicsStateHandle(uri, variant); 43 if (!renderHandleReference_) { 44 // presumably we should resolve the state from shader instead trying to create a default our self 45 // the problem is, we don't actually know to which shader we are attached to 46 // basically the shader should have set its default during the material component set-up, though 47 shaderManager.CreateGraphicsState({ uri, {} }, { variant, {} }); 48 renderHandleReference_ = shaderManager.GetGraphicsStateHandle(uri, variant); 49 } 50 51 return renderHandleReference_; 52 } 53 54 void SetGraphicsState(const RENDER_NS::GraphicsState& state, SCENE_NS::IMaterial::Ptr mat) override 55 { 56 if (auto sh = SceneHolder()) { 57 sh->QueueApplicationTask(META_NS::MakeCallback<META_NS::ITaskQueueTask>( 58 [st = state, sh = sh_, material = BASE_NS::weak_ptr(mat), type = ix_]() { 59 if (auto sceneHolder = sh.lock()) { 60 if (auto mat = interface_cast<SCENE_NS::IEcsObject>(material.lock())) { 61 sceneHolder->SetGraphicsState( 62 mat->GetEntity(), (SceneHolder::ShaderType)type, st); 63 } 64 } 65 return false; 66 }), 67 false); 68 } 69 } 70 71 SCENE_NS::IShaderGraphicsState::Ptr GetGraphicsState(SCENE_NS::IMaterial::Ptr mat) override 72 { 73 auto ret = 74 META_NS::GetObjectRegistry().Create<SCENE_NS::IShaderGraphicsState>(SCENE_NS::ClassId::GraphicsState); 75 if (auto sh = SceneHolder()) { 76 sh->QueueApplicationTask( 77 META_NS::MakeCallback<META_NS::ITaskQueueTask>([sh = sh_, material = BASE_NS::weak_ptr(mat), type = ix_, 78 ret_w = BASE_NS::weak_ptr(ret)]() { 79 if (auto sceneHolder = sh.lock()) { 80 if (auto mat = interface_cast<SCENE_NS::IEcsObject>(material.lock())) { 81 if (auto ret = ret_w.lock()) { 82 sceneHolder->GetGraphicsState(mat->GetEntity(), (SceneHolder::ShaderType)type, ret); 83 if (auto typedRet = 84 interface_cast<SCENE_NS::IPendingRequestData<RENDER_NS::GraphicsState>>(ret)) { 85 typedRet->MarkReady(); 86 } 87 } 88 } 89 } 90 return false; 91 }), 92 false); 93 } 94 95 return ret; 96 } 97 98 void SetSceneHolder(const SceneHolder::WeakPtr& sh) override 99 { 100 sh_ = sh; 101 } 102 103 SceneHolder::Ptr SceneHolder() override 104 { 105 return sh_.lock(); 106 } 107 108 void SetIndex(size_t ix) override 109 { 110 ix_ = ix; 111 } 112 113private: 114 RENDER_NS::RenderHandleReference renderHandleReference_; 115 SceneHolder::WeakPtr sh_; 116 size_t ix_ { 0 }; 117}; 118} // namespace 119 120SCENE_BEGIN_NAMESPACE() 121void RegisterGraphicsStateImpl() 122{ 123 META_NS::GetObjectRegistry().RegisterObjectType<GraphicsStateImpl>(); 124} 125void UnregisterGraphicsStateImpl() 126{ 127 META_NS::GetObjectRegistry().UnregisterObjectType<GraphicsStateImpl>(); 128} 129SCENE_END_NAMESPACE()