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#include <scene_plugin/api/material_uid.h> 168bf80f4bSopenharmony_ci 178bf80f4bSopenharmony_ci#include <meta/ext/concrete_base_object.h> 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include "bind_templates.inl" 208bf80f4bSopenharmony_ci#include "node_impl.h" 218bf80f4bSopenharmony_ci 228bf80f4bSopenharmony_cinamespace { 238bf80f4bSopenharmony_ciclass GraphicsStateImpl : public META_NS::ObjectFwd<GraphicsStateImpl, SCENE_NS::ClassId::GraphicsState, 248bf80f4bSopenharmony_ci META_NS::ClassId::Object, SCENE_NS::IGraphicsState, ISceneHolderRef> { 258bf80f4bSopenharmony_ci META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::IGraphicsState, BASE_NS::string, Uri, "") 268bf80f4bSopenharmony_ci META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::IGraphicsState, BASE_NS::string, Variant, "") 278bf80f4bSopenharmony_ci 288bf80f4bSopenharmony_ci bool Build(const IMetadata::Ptr& data) override 298bf80f4bSopenharmony_ci { 308bf80f4bSopenharmony_ci return true; 318bf80f4bSopenharmony_ci } 328bf80f4bSopenharmony_ci 338bf80f4bSopenharmony_ci RENDER_NS::RenderHandleReference GetRenderHandleReference(RENDER_NS::IShaderManager& shaderManager) override 348bf80f4bSopenharmony_ci { 358bf80f4bSopenharmony_ci if (RENDER_NS::RenderHandleUtil::IsValid(renderHandleReference_.GetHandle())) { 368bf80f4bSopenharmony_ci return renderHandleReference_; 378bf80f4bSopenharmony_ci } 388bf80f4bSopenharmony_ci 398bf80f4bSopenharmony_ci auto uri = GetValue(META_ACCESS_PROPERTY(Uri)); 408bf80f4bSopenharmony_ci auto variant = GetValue(META_ACCESS_PROPERTY(Variant)); 418bf80f4bSopenharmony_ci 428bf80f4bSopenharmony_ci renderHandleReference_ = shaderManager.GetGraphicsStateHandle(uri, variant); 438bf80f4bSopenharmony_ci if (!renderHandleReference_) { 448bf80f4bSopenharmony_ci // presumably we should resolve the state from shader instead trying to create a default our self 458bf80f4bSopenharmony_ci // the problem is, we don't actually know to which shader we are attached to 468bf80f4bSopenharmony_ci // basically the shader should have set its default during the material component set-up, though 478bf80f4bSopenharmony_ci shaderManager.CreateGraphicsState({ uri, {} }, { variant, {} }); 488bf80f4bSopenharmony_ci renderHandleReference_ = shaderManager.GetGraphicsStateHandle(uri, variant); 498bf80f4bSopenharmony_ci } 508bf80f4bSopenharmony_ci 518bf80f4bSopenharmony_ci return renderHandleReference_; 528bf80f4bSopenharmony_ci } 538bf80f4bSopenharmony_ci 548bf80f4bSopenharmony_ci void SetGraphicsState(const RENDER_NS::GraphicsState& state, SCENE_NS::IMaterial::Ptr mat) override 558bf80f4bSopenharmony_ci { 568bf80f4bSopenharmony_ci if (auto sh = SceneHolder()) { 578bf80f4bSopenharmony_ci sh->QueueApplicationTask(META_NS::MakeCallback<META_NS::ITaskQueueTask>( 588bf80f4bSopenharmony_ci [st = state, sh = sh_, material = BASE_NS::weak_ptr(mat), type = ix_]() { 598bf80f4bSopenharmony_ci if (auto sceneHolder = sh.lock()) { 608bf80f4bSopenharmony_ci if (auto mat = interface_cast<SCENE_NS::IEcsObject>(material.lock())) { 618bf80f4bSopenharmony_ci sceneHolder->SetGraphicsState( 628bf80f4bSopenharmony_ci mat->GetEntity(), (SceneHolder::ShaderType)type, st); 638bf80f4bSopenharmony_ci } 648bf80f4bSopenharmony_ci } 658bf80f4bSopenharmony_ci return false; 668bf80f4bSopenharmony_ci }), 678bf80f4bSopenharmony_ci false); 688bf80f4bSopenharmony_ci } 698bf80f4bSopenharmony_ci } 708bf80f4bSopenharmony_ci 718bf80f4bSopenharmony_ci SCENE_NS::IShaderGraphicsState::Ptr GetGraphicsState(SCENE_NS::IMaterial::Ptr mat) override 728bf80f4bSopenharmony_ci { 738bf80f4bSopenharmony_ci auto ret = 748bf80f4bSopenharmony_ci META_NS::GetObjectRegistry().Create<SCENE_NS::IShaderGraphicsState>(SCENE_NS::ClassId::GraphicsState); 758bf80f4bSopenharmony_ci if (auto sh = SceneHolder()) { 768bf80f4bSopenharmony_ci sh->QueueApplicationTask( 778bf80f4bSopenharmony_ci META_NS::MakeCallback<META_NS::ITaskQueueTask>([sh = sh_, material = BASE_NS::weak_ptr(mat), type = ix_, 788bf80f4bSopenharmony_ci ret_w = BASE_NS::weak_ptr(ret)]() { 798bf80f4bSopenharmony_ci if (auto sceneHolder = sh.lock()) { 808bf80f4bSopenharmony_ci if (auto mat = interface_cast<SCENE_NS::IEcsObject>(material.lock())) { 818bf80f4bSopenharmony_ci if (auto ret = ret_w.lock()) { 828bf80f4bSopenharmony_ci sceneHolder->GetGraphicsState(mat->GetEntity(), (SceneHolder::ShaderType)type, ret); 838bf80f4bSopenharmony_ci if (auto typedRet = 848bf80f4bSopenharmony_ci interface_cast<SCENE_NS::IPendingRequestData<RENDER_NS::GraphicsState>>(ret)) { 858bf80f4bSopenharmony_ci typedRet->MarkReady(); 868bf80f4bSopenharmony_ci } 878bf80f4bSopenharmony_ci } 888bf80f4bSopenharmony_ci } 898bf80f4bSopenharmony_ci } 908bf80f4bSopenharmony_ci return false; 918bf80f4bSopenharmony_ci }), 928bf80f4bSopenharmony_ci false); 938bf80f4bSopenharmony_ci } 948bf80f4bSopenharmony_ci 958bf80f4bSopenharmony_ci return ret; 968bf80f4bSopenharmony_ci } 978bf80f4bSopenharmony_ci 988bf80f4bSopenharmony_ci void SetSceneHolder(const SceneHolder::WeakPtr& sh) override 998bf80f4bSopenharmony_ci { 1008bf80f4bSopenharmony_ci sh_ = sh; 1018bf80f4bSopenharmony_ci } 1028bf80f4bSopenharmony_ci 1038bf80f4bSopenharmony_ci SceneHolder::Ptr SceneHolder() override 1048bf80f4bSopenharmony_ci { 1058bf80f4bSopenharmony_ci return sh_.lock(); 1068bf80f4bSopenharmony_ci } 1078bf80f4bSopenharmony_ci 1088bf80f4bSopenharmony_ci void SetIndex(size_t ix) override 1098bf80f4bSopenharmony_ci { 1108bf80f4bSopenharmony_ci ix_ = ix; 1118bf80f4bSopenharmony_ci } 1128bf80f4bSopenharmony_ci 1138bf80f4bSopenharmony_ciprivate: 1148bf80f4bSopenharmony_ci RENDER_NS::RenderHandleReference renderHandleReference_; 1158bf80f4bSopenharmony_ci SceneHolder::WeakPtr sh_; 1168bf80f4bSopenharmony_ci size_t ix_ { 0 }; 1178bf80f4bSopenharmony_ci}; 1188bf80f4bSopenharmony_ci} // namespace 1198bf80f4bSopenharmony_ci 1208bf80f4bSopenharmony_ciSCENE_BEGIN_NAMESPACE() 1218bf80f4bSopenharmony_civoid RegisterGraphicsStateImpl() 1228bf80f4bSopenharmony_ci{ 1238bf80f4bSopenharmony_ci META_NS::GetObjectRegistry().RegisterObjectType<GraphicsStateImpl>(); 1248bf80f4bSopenharmony_ci} 1258bf80f4bSopenharmony_civoid UnregisterGraphicsStateImpl() 1268bf80f4bSopenharmony_ci{ 1278bf80f4bSopenharmony_ci META_NS::GetObjectRegistry().UnregisterObjectType<GraphicsStateImpl>(); 1288bf80f4bSopenharmony_ci} 1298bf80f4bSopenharmony_ciSCENE_END_NAMESPACE()