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 168bf80f4bSopenharmony_ci#include "scene_adapter/scene_adapter.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <dlfcn.h> 198bf80f4bSopenharmony_ci#include <memory> 208bf80f4bSopenharmony_ci#include <string_view> 218bf80f4bSopenharmony_ci 228bf80f4bSopenharmony_ci#include "napi/native_api.h" 238bf80f4bSopenharmony_ci#include "napi/native_node_api.h" 248bf80f4bSopenharmony_ci 258bf80f4bSopenharmony_ci#include <base/containers/array_view.h> 268bf80f4bSopenharmony_ci 278bf80f4bSopenharmony_ci#include <core/intf_engine.h> 288bf80f4bSopenharmony_ci#include <core/ecs/intf_system_graph_loader.h> 298bf80f4bSopenharmony_ci#include <core/engine_info.h> 308bf80f4bSopenharmony_ci#include <core/implementation_uids.h> 318bf80f4bSopenharmony_ci#include <core/io/intf_file_manager.h> 328bf80f4bSopenharmony_ci#include <core/namespace.h> 338bf80f4bSopenharmony_ci#include <core/os/intf_platform.h> 348bf80f4bSopenharmony_ci#include <core/plugin/intf_plugin_register.h> 358bf80f4bSopenharmony_ci#include <core/property/intf_property_handle.h> 368bf80f4bSopenharmony_ci 378bf80f4bSopenharmony_ci#include <meta/interface/intf_meta_object_lib.h> 388bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue_registry.h> 398bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue.h> 408bf80f4bSopenharmony_ci#include <meta/interface/intf_object.h> 418bf80f4bSopenharmony_ci#include <meta/interface/intf_object_registry.h> 428bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue.h> 438bf80f4bSopenharmony_ci#include <meta/base/shared_ptr.h> 448bf80f4bSopenharmony_ci#include <meta/base/interface_macros.h> 458bf80f4bSopenharmony_ci#include <meta/api/make_callback.h> 468bf80f4bSopenharmony_ci#include <meta/ext/object.h> 478bf80f4bSopenharmony_ci 488bf80f4bSopenharmony_ci#include <scene_plugin/namespace.h> 498bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_scene.h> 508bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_ecs_scene.h> 518bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_mesh.h> 528bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_material.h> 538bf80f4bSopenharmony_ci#include <scene_plugin/api/scene_uid.h> 548bf80f4bSopenharmony_ci 558bf80f4bSopenharmony_ci#include "ability.h" 568bf80f4bSopenharmony_ci#include "data_ability_helper.h" 578bf80f4bSopenharmony_ci#include "napi_base_context.h" 588bf80f4bSopenharmony_ci 598bf80f4bSopenharmony_ci#include <render/implementation_uids.h> 608bf80f4bSopenharmony_ci#include <render/gles/intf_device_gles.h> 618bf80f4bSopenharmony_ci#include <render/intf_renderer.h> 628bf80f4bSopenharmony_ci#include <render/intf_render_context.h> 638bf80f4bSopenharmony_ci 648bf80f4bSopenharmony_ci#include "3d_widget_adapter_log.h" 658bf80f4bSopenharmony_ci#include "widget_trace.h" 668bf80f4bSopenharmony_ci#include "ohos/texture_layer.h" 678bf80f4bSopenharmony_ci 688bf80f4bSopenharmony_cinamespace OHOS::Render3D { 698bf80f4bSopenharmony_ciHapInfo GetHapInfo() 708bf80f4bSopenharmony_ci{ 718bf80f4bSopenharmony_ci std::shared_ptr<AbilityRuntime::ApplicationContext> context = 728bf80f4bSopenharmony_ci AbilityRuntime::ApplicationContext::GetApplicationContext(); 738bf80f4bSopenharmony_ci if (!context) { 748bf80f4bSopenharmony_ci WIDGET_LOGE("Failed to get application context."); 758bf80f4bSopenharmony_ci return {}; 768bf80f4bSopenharmony_ci } 778bf80f4bSopenharmony_ci auto resourceManager = context->GetResourceManager(); 788bf80f4bSopenharmony_ci if (!resourceManager) { 798bf80f4bSopenharmony_ci WIDGET_LOGE("Failed to get resource manager."); 808bf80f4bSopenharmony_ci return {}; 818bf80f4bSopenharmony_ci } 828bf80f4bSopenharmony_ci HapInfo hapInfo; 838bf80f4bSopenharmony_ci hapInfo.bundleName_ = resourceManager->bundleInfo.first; 848bf80f4bSopenharmony_ci hapInfo.moduleName_ = resourceManager->bundleInfo.second; 858bf80f4bSopenharmony_ci 868bf80f4bSopenharmony_ci // hapPath 878bf80f4bSopenharmony_ci std::string hapPath = context->GetBundleCodeDir(); 888bf80f4bSopenharmony_ci hapInfo.hapPath_ = hapPath + "/" + hapInfo.moduleName_ + ".hap"; 898bf80f4bSopenharmony_ci WIDGET_LOGD("bundle %s, module %s, hapPath %s", 908bf80f4bSopenharmony_ci hapInfo.bundleName_.c_str(), 918bf80f4bSopenharmony_ci hapInfo.moduleName_.c_str(), 928bf80f4bSopenharmony_ci hapInfo.hapPath_.c_str()); 938bf80f4bSopenharmony_ci 948bf80f4bSopenharmony_ci return hapInfo; 958bf80f4bSopenharmony_ci} 968bf80f4bSopenharmony_ci 978bf80f4bSopenharmony_ciusing IntfPtr = META_NS::SharedPtrIInterface; 988bf80f4bSopenharmony_ciusing IntfWeakPtr = META_NS::WeakPtrIInterface; 998bf80f4bSopenharmony_ci 1008bf80f4bSopenharmony_cistruct EngineInstance { 1018bf80f4bSopenharmony_ci void *libHandle_ = nullptr; 1028bf80f4bSopenharmony_ci BASE_NS::shared_ptr<RENDER_NS::IRenderContext> renderContext_; 1038bf80f4bSopenharmony_ci BASE_NS::shared_ptr<CORE_NS::IEngine> engine_; 1048bf80f4bSopenharmony_ci}; 1058bf80f4bSopenharmony_ci 1068bf80f4bSopenharmony_cistatic EngineInstance engineInstance_; 1078bf80f4bSopenharmony_cistatic std::mutex mute; 1088bf80f4bSopenharmony_ciMETA_NS::ITaskQueue::Ptr engineThread; 1098bf80f4bSopenharmony_ciMETA_NS::ITaskQueue::Ptr ioThread; 1108bf80f4bSopenharmony_ci 1118bf80f4bSopenharmony_civoid LockCompositor() 1128bf80f4bSopenharmony_ci{ 1138bf80f4bSopenharmony_ci mute.lock(); 1148bf80f4bSopenharmony_ci} 1158bf80f4bSopenharmony_ci 1168bf80f4bSopenharmony_civoid UnlockCompositor() 1178bf80f4bSopenharmony_ci{ 1188bf80f4bSopenharmony_ci mute.unlock(); 1198bf80f4bSopenharmony_ci} 1208bf80f4bSopenharmony_ci 1218bf80f4bSopenharmony_cistatic constexpr BASE_NS::Uid ENGINE_THREAD { "2070e705-d061-40e4-bfb7-90fad2c280af" }; 1228bf80f4bSopenharmony_cistatic constexpr BASE_NS::Uid APP_THREAD { "b2e8cef3-453a-4651-b564-5190f8b5190d" }; 1238bf80f4bSopenharmony_cistatic constexpr BASE_NS::Uid IO_QUEUE { "be88e9a0-9cd8-45ab-be48-937953dc258f" }; 1248bf80f4bSopenharmony_ci 1258bf80f4bSopenharmony_citemplate<typename T> 1268bf80f4bSopenharmony_cibool LoadFunc(T &fn, const char *fName, void* handle) 1278bf80f4bSopenharmony_ci{ 1288bf80f4bSopenharmony_ci fn = reinterpret_cast<T>(dlsym(handle, fName)); 1298bf80f4bSopenharmony_ci if (fn == nullptr) { 1308bf80f4bSopenharmony_ci WIDGET_LOGE("%s open %s", __func__, dlerror()); 1318bf80f4bSopenharmony_ci return false; 1328bf80f4bSopenharmony_ci } 1338bf80f4bSopenharmony_ci return true; 1348bf80f4bSopenharmony_ci} 1358bf80f4bSopenharmony_ci 1368bf80f4bSopenharmony_ciSceneAdapter::~SceneAdapter() 1378bf80f4bSopenharmony_ci{ 1388bf80f4bSopenharmony_ci} 1398bf80f4bSopenharmony_ci 1408bf80f4bSopenharmony_ciSceneAdapter::SceneAdapter() 1418bf80f4bSopenharmony_ci{ 1428bf80f4bSopenharmony_ci WIDGET_LOGD("scene adapter Impl create"); 1438bf80f4bSopenharmony_ci} 1448bf80f4bSopenharmony_ci 1458bf80f4bSopenharmony_cibool SceneAdapter::LoadEngineLib() 1468bf80f4bSopenharmony_ci{ 1478bf80f4bSopenharmony_ci if (engineInstance_.libHandle_ != nullptr) { 1488bf80f4bSopenharmony_ci WIDGET_LOGD("%s, already loaded", __func__); 1498bf80f4bSopenharmony_ci return true; 1508bf80f4bSopenharmony_ci } 1518bf80f4bSopenharmony_ci 1528bf80f4bSopenharmony_ci #define TO_STRING(name) #name 1538bf80f4bSopenharmony_ci #define LIB_NAME(name) TO_STRING(name) 1548bf80f4bSopenharmony_ci constexpr std::string_view lib { LIB_NAME(LIB_ENGINE_CORE)".so" }; 1558bf80f4bSopenharmony_ci engineInstance_.libHandle_ = dlopen(lib.data(), RTLD_LAZY); 1568bf80f4bSopenharmony_ci 1578bf80f4bSopenharmony_ci if (engineInstance_.libHandle_ == nullptr) { 1588bf80f4bSopenharmony_ci WIDGET_LOGE("%s, open lib fail %s", __func__, dlerror()); 1598bf80f4bSopenharmony_ci } 1608bf80f4bSopenharmony_ci #undef TO_STRING 1618bf80f4bSopenharmony_ci #undef LIB_NAME 1628bf80f4bSopenharmony_ci 1638bf80f4bSopenharmony_ci #define LOAD_FUNC(fn, name) LoadFunc<decltype(fn)>(fn, name, engineInstance_.libHandle_) 1648bf80f4bSopenharmony_ci if (!(LOAD_FUNC(CORE_NS::CreatePluginRegistry, 1658bf80f4bSopenharmony_ci "_ZN4Core20CreatePluginRegistryERKNS_18PlatformCreateInfoE") 1668bf80f4bSopenharmony_ci && LOAD_FUNC(CORE_NS::GetPluginRegister, "_ZN4Core17GetPluginRegisterEv") 1678bf80f4bSopenharmony_ci && LOAD_FUNC(CORE_NS::IsDebugBuild, "_ZN4Core12IsDebugBuildEv") 1688bf80f4bSopenharmony_ci && LOAD_FUNC(CORE_NS::GetVersion, "_ZN4Core13GetVersionRevEv"))) { 1698bf80f4bSopenharmony_ci return false; 1708bf80f4bSopenharmony_ci } 1718bf80f4bSopenharmony_ci #undef LOAD_FUNC 1728bf80f4bSopenharmony_ci 1738bf80f4bSopenharmony_ci return true; 1748bf80f4bSopenharmony_ci} 1758bf80f4bSopenharmony_ci 1768bf80f4bSopenharmony_cibool SceneAdapter::LoadPlugins(const CORE_NS::PlatformCreateInfo& platformCreateInfo) 1778bf80f4bSopenharmony_ci{ 1788bf80f4bSopenharmony_ci if (engineInstance_.engine_) { 1798bf80f4bSopenharmony_ci return true; 1808bf80f4bSopenharmony_ci } 1818bf80f4bSopenharmony_ci if (!LoadEngineLib()) { 1828bf80f4bSopenharmony_ci return false; 1838bf80f4bSopenharmony_ci } 1848bf80f4bSopenharmony_ci WIDGET_LOGD("load engine success!"); 1858bf80f4bSopenharmony_ci const BASE_NS::Uid DefaultPluginList[] { SCENE_NS::UID_SCENE_PLUGIN }; 1868bf80f4bSopenharmony_ci 1878bf80f4bSopenharmony_ci CORE_NS::CreatePluginRegistry(platformCreateInfo); 1888bf80f4bSopenharmony_ci if (!CORE_NS::GetPluginRegister().LoadPlugins(DefaultPluginList)) { 1898bf80f4bSopenharmony_ci WIDGET_LOGE("fail to load scene widget plugin"); 1908bf80f4bSopenharmony_ci return false; 1918bf80f4bSopenharmony_ci } 1928bf80f4bSopenharmony_ci WIDGET_LOGD("load plugin success"); 1938bf80f4bSopenharmony_ci return true; 1948bf80f4bSopenharmony_ci} 1958bf80f4bSopenharmony_ci 1968bf80f4bSopenharmony_cibool SceneAdapter::InitEngine(CORE_NS::PlatformCreateInfo platformCreateInfo) 1978bf80f4bSopenharmony_ci{ 1988bf80f4bSopenharmony_ci if (engineInstance_.engine_) { 1998bf80f4bSopenharmony_ci return true; 2008bf80f4bSopenharmony_ci } 2018bf80f4bSopenharmony_ci auto& tr = META_NS::GetTaskQueueRegistry(); 2028bf80f4bSopenharmony_ci auto& obr = META_NS::GetObjectRegistry(); 2038bf80f4bSopenharmony_ci 2048bf80f4bSopenharmony_ci engineThread = tr.GetTaskQueue(ENGINE_THREAD); 2058bf80f4bSopenharmony_ci if (!engineThread) { 2068bf80f4bSopenharmony_ci engineThread = obr.Create<META_NS::ITaskQueue>(META_NS::ClassId::ThreadedTaskQueue); 2078bf80f4bSopenharmony_ci tr.RegisterTaskQueue(engineThread, ENGINE_THREAD); 2088bf80f4bSopenharmony_ci } 2098bf80f4bSopenharmony_ci ioThread = tr.GetTaskQueue(IO_QUEUE); 2108bf80f4bSopenharmony_ci if (!ioThread) { 2118bf80f4bSopenharmony_ci ioThread = obr.Create<META_NS::ITaskQueue>(META_NS::ClassId::ThreadedTaskQueue); 2128bf80f4bSopenharmony_ci tr.RegisterTaskQueue(ioThread, IO_QUEUE); 2138bf80f4bSopenharmony_ci } 2148bf80f4bSopenharmony_ci 2158bf80f4bSopenharmony_ci auto engineInit = META_NS::MakeCallback<META_NS::ITaskQueueWaitableTask>([platformCreateInfo]() { 2168bf80f4bSopenharmony_ci auto& obr = META_NS::GetObjectRegistry(); 2178bf80f4bSopenharmony_ci // Initialize lumeengine/render etc 2188bf80f4bSopenharmony_ci CORE_NS::EngineCreateInfo engineCreateInfo { platformCreateInfo, {}, {} }; 2198bf80f4bSopenharmony_ci if (auto factory = CORE_NS::GetInstance<CORE_NS::IEngineFactory>(CORE_NS::UID_ENGINE_FACTORY)) { 2208bf80f4bSopenharmony_ci engineInstance_.engine_.reset(factory->Create(engineCreateInfo).get()); 2218bf80f4bSopenharmony_ci } 2228bf80f4bSopenharmony_ci 2238bf80f4bSopenharmony_ci if (!engineInstance_.engine_) { 2248bf80f4bSopenharmony_ci WIDGET_LOGE("get engine fail"); 2258bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 2268bf80f4bSopenharmony_ci } 2278bf80f4bSopenharmony_ci engineInstance_.engine_->Init(); 2288bf80f4bSopenharmony_ci 2298bf80f4bSopenharmony_ci engineInstance_.renderContext_.reset( 2308bf80f4bSopenharmony_ci CORE_NS::CreateInstance<RENDER_NS::IRenderContext>(*engineInstance_.engine_, RENDER_NS::UID_RENDER_CONTEXT) 2318bf80f4bSopenharmony_ci .get()); 2328bf80f4bSopenharmony_ci 2338bf80f4bSopenharmony_ci RENDER_NS::RenderCreateInfo renderCreateInfo; 2348bf80f4bSopenharmony_ci // this context needs to be "not busy" (not selected current in any thread) for creation to succeed. 2358bf80f4bSopenharmony_ci std::string backendProp = "gles"; 2368bf80f4bSopenharmony_ci if (backendProp == "vulkan") { 2378bf80f4bSopenharmony_ci } else { 2388bf80f4bSopenharmony_ci Render::DeviceCreateInfo deviceCreateInfo; 2398bf80f4bSopenharmony_ci RENDER_NS::BackendExtraGLES glExtra; 2408bf80f4bSopenharmony_ci glExtra.depthBits = 24; // 24 : bit size 2418bf80f4bSopenharmony_ci glExtra.sharedContext = EGL_NO_CONTEXT; 2428bf80f4bSopenharmony_ci deviceCreateInfo.backendType = RENDER_NS::DeviceBackendType::OPENGLES; 2438bf80f4bSopenharmony_ci deviceCreateInfo.backendConfiguration = &glExtra; 2448bf80f4bSopenharmony_ci renderCreateInfo.applicationInfo = {}; 2458bf80f4bSopenharmony_ci renderCreateInfo.deviceCreateInfo = deviceCreateInfo; 2468bf80f4bSopenharmony_ci } 2478bf80f4bSopenharmony_ci 2488bf80f4bSopenharmony_ci auto rrc = engineInstance_.renderContext_->Init(renderCreateInfo); 2498bf80f4bSopenharmony_ci if (rrc != RENDER_NS::RenderResultCode::RENDER_SUCCESS) { 2508bf80f4bSopenharmony_ci WIDGET_LOGE("Failed to create render context"); 2518bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 2528bf80f4bSopenharmony_ci } 2538bf80f4bSopenharmony_ci 2548bf80f4bSopenharmony_ci // Save the stuff to the default object context. 2558bf80f4bSopenharmony_ci auto engineThread = META_NS::GetTaskQueueRegistry().GetTaskQueue(ENGINE_THREAD); 2568bf80f4bSopenharmony_ci // thats the javascript thread... 2578bf80f4bSopenharmony_ci auto appThread = engineThread; 2588bf80f4bSopenharmony_ci auto doc = interface_cast<META_NS::IMetadata>(obr.GetDefaultObjectContext()); 2598bf80f4bSopenharmony_ci auto flags = META_NS::ObjectFlagBits::INTERNAL | META_NS::ObjectFlagBits::NATIVE; 2608bf80f4bSopenharmony_ci 2618bf80f4bSopenharmony_ci doc->AddProperty(META_NS::ConstructProperty<IntfPtr>("RenderContext", nullptr, flags)); 2628bf80f4bSopenharmony_ci doc->AddProperty(META_NS::ConstructProperty<IntfPtr>("EngineQueue", nullptr, flags)); 2638bf80f4bSopenharmony_ci doc->AddProperty(META_NS::ConstructProperty<IntfPtr>("AppQueue", nullptr, flags)); 2648bf80f4bSopenharmony_ci doc->AddProperty(META_NS::ConstructArrayProperty<IntfWeakPtr>("Scenes", {}, flags)); 2658bf80f4bSopenharmony_ci 2668bf80f4bSopenharmony_ci doc->GetPropertyByName<META_NS::SharedPtrIInterface>("EngineQueue")->SetValue(engineThread); 2678bf80f4bSopenharmony_ci doc->GetPropertyByName<META_NS::SharedPtrIInterface>("AppQueue")->SetValue(appThread); 2688bf80f4bSopenharmony_ci doc->GetPropertyByName<META_NS::SharedPtrIInterface>("RenderContext")->SetValue(engineInstance_.renderContext_); 2698bf80f4bSopenharmony_ci 2708bf80f4bSopenharmony_ci WIDGET_LOGD("register shader path"); 2718bf80f4bSopenharmony_ci static constexpr const RENDER_NS::IShaderManager::ShaderFilePathDesc desc { "shaders://" }; 2728bf80f4bSopenharmony_ci engineInstance_.engine_->GetFileManager().RegisterPath("shaders", "OhosRawFile://shaders", false); 2738bf80f4bSopenharmony_ci engineInstance_.renderContext_->GetDevice().GetShaderManager().LoadShaderFiles(desc); 2748bf80f4bSopenharmony_ci 2758bf80f4bSopenharmony_ci engineInstance_.engine_->GetFileManager().RegisterPath("appshaders", "OhosRawFile://shaders", false); 2768bf80f4bSopenharmony_ci static constexpr const RENDER_NS::IShaderManager::ShaderFilePathDesc desc1 { "appshaders://" }; 2778bf80f4bSopenharmony_ci engineInstance_.renderContext_->GetDevice().GetShaderManager().LoadShaderFiles(desc1); 2788bf80f4bSopenharmony_ci 2798bf80f4bSopenharmony_ci WIDGET_LOGD("init engine success"); 2808bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 2818bf80f4bSopenharmony_ci }); 2828bf80f4bSopenharmony_ci 2838bf80f4bSopenharmony_ci engineThread->AddWaitableTask(engineInit)->Wait(); 2848bf80f4bSopenharmony_ci 2858bf80f4bSopenharmony_ci return true; 2868bf80f4bSopenharmony_ci} 2878bf80f4bSopenharmony_ci 2888bf80f4bSopenharmony_civoid SceneAdapter::SetSceneObj(META_NS::IObject::Ptr pt) 2898bf80f4bSopenharmony_ci{ 2908bf80f4bSopenharmony_ci WIDGET_LOGD("SceneAdapterImpl::SetSceneObj"); 2918bf80f4bSopenharmony_ci sceneWidgetObj_ = pt; 2928bf80f4bSopenharmony_ci} 2938bf80f4bSopenharmony_ci 2948bf80f4bSopenharmony_cistd::shared_ptr<TextureLayer> SceneAdapter::CreateTextureLayer() 2958bf80f4bSopenharmony_ci{ 2968bf80f4bSopenharmony_ci InitRenderThread(); 2978bf80f4bSopenharmony_ci auto cb = META_NS::MakeCallback<META_NS::ITaskQueueWaitableTask>([this]() { 2988bf80f4bSopenharmony_ci textureLayer_ = std::make_shared<TextureLayer>(key_); 2998bf80f4bSopenharmony_ci key_++; 3008bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 3018bf80f4bSopenharmony_ci }); 3028bf80f4bSopenharmony_ci META_NS::GetTaskQueueRegistry().GetTaskQueue(ENGINE_THREAD)->AddWaitableTask(cb)->Wait(); 3038bf80f4bSopenharmony_ci return textureLayer_; 3048bf80f4bSopenharmony_ci} 3058bf80f4bSopenharmony_ci 3068bf80f4bSopenharmony_cibool SceneAdapter::LoadPluginsAndInit() 3078bf80f4bSopenharmony_ci{ 3088bf80f4bSopenharmony_ci WIDGET_LOGD("scene adapter loadPlugins"); 3098bf80f4bSopenharmony_ci hapInfo_ = GetHapInfo(); 3108bf80f4bSopenharmony_ci 3118bf80f4bSopenharmony_ci #define TO_STRING(name) #name 3128bf80f4bSopenharmony_ci #define PLATFORM_PATH_NAME(name) TO_STRING(name) 3138bf80f4bSopenharmony_ci CORE_NS::PlatformCreateInfo platformCreateInfo { 3148bf80f4bSopenharmony_ci PLATFORM_PATH_NAME(PLATFORM_CORE_ROOT_PATH), 3158bf80f4bSopenharmony_ci PLATFORM_PATH_NAME(PLATFORM_APP_ROOT_PATH), 3168bf80f4bSopenharmony_ci PLATFORM_PATH_NAME(PLATFORM_APP_PLUGIN_PATH), 3178bf80f4bSopenharmony_ci hapInfo_.hapPath_.c_str(), 3188bf80f4bSopenharmony_ci hapInfo_.bundleName_.c_str(), 3198bf80f4bSopenharmony_ci hapInfo_.moduleName_.c_str() 3208bf80f4bSopenharmony_ci }; 3218bf80f4bSopenharmony_ci #undef TO_STRING 3228bf80f4bSopenharmony_ci #undef PLATFORM_PATH_NAME 3238bf80f4bSopenharmony_ci if (!LoadPlugins(platformCreateInfo)) { 3248bf80f4bSopenharmony_ci return false; 3258bf80f4bSopenharmony_ci } 3268bf80f4bSopenharmony_ci 3278bf80f4bSopenharmony_ci if (!InitEngine(platformCreateInfo)) { 3288bf80f4bSopenharmony_ci return false; 3298bf80f4bSopenharmony_ci } 3308bf80f4bSopenharmony_ci 3318bf80f4bSopenharmony_ci return true; 3328bf80f4bSopenharmony_ci} 3338bf80f4bSopenharmony_ci 3348bf80f4bSopenharmony_civoid SceneAdapter::OnWindowChange(const WindowChangeInfo& windowChangeInfo) 3358bf80f4bSopenharmony_ci{ 3368bf80f4bSopenharmony_ci WIDGET_LOGD("OnWindowchange"); 3378bf80f4bSopenharmony_ci auto cb = META_NS::MakeCallback<META_NS::ITaskQueueWaitableTask>([this, &windowChangeInfo]() { 3388bf80f4bSopenharmony_ci textureLayer_->OnWindowChange(windowChangeInfo); 3398bf80f4bSopenharmony_ci const auto& textureInfo = textureLayer_->GetTextureInfo(); 3408bf80f4bSopenharmony_ci auto& device = engineInstance_.renderContext_->GetDevice(); 3418bf80f4bSopenharmony_ci RENDER_NS::SwapchainCreateInfo swapchainCreateInfo { 3428bf80f4bSopenharmony_ci // reinterpret_cast<uint64_t>(eglSurface_), 3438bf80f4bSopenharmony_ci 0U, 3448bf80f4bSopenharmony_ci RENDER_NS::SwapchainFlagBits::CORE_SWAPCHAIN_COLOR_BUFFER_BIT | 3458bf80f4bSopenharmony_ci RENDER_NS::SwapchainFlagBits::CORE_SWAPCHAIN_DEPTH_BUFFER_BIT | 3468bf80f4bSopenharmony_ci RENDER_NS::SwapchainFlagBits::CORE_SWAPCHAIN_SRGB_BIT, 3478bf80f4bSopenharmony_ci RENDER_NS::ImageUsageFlagBits::CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 3488bf80f4bSopenharmony_ci { 3498bf80f4bSopenharmony_ci reinterpret_cast<uintptr_t>(textureInfo.nativeWindow_), 3508bf80f4bSopenharmony_ci reinterpret_cast<uintptr_t>(static_cast<const RENDER_NS::DevicePlatformDataGLES&>( 3518bf80f4bSopenharmony_ci device.GetPlatformData()).display) 3528bf80f4bSopenharmony_ci } 3538bf80f4bSopenharmony_ci }; 3548bf80f4bSopenharmony_ci swapchainHandle_ = device.CreateSwapchainHandle(swapchainCreateInfo, swapchainHandle_, {}); 3558bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 3568bf80f4bSopenharmony_ci }); 3578bf80f4bSopenharmony_ci 3588bf80f4bSopenharmony_ci META_NS::GetTaskQueueRegistry().GetTaskQueue(ENGINE_THREAD)->AddWaitableTask(cb)->Wait(); 3598bf80f4bSopenharmony_ci} 3608bf80f4bSopenharmony_ci 3618bf80f4bSopenharmony_civoid SceneAdapter::InitRenderThread() 3628bf80f4bSopenharmony_ci{ 3638bf80f4bSopenharmony_ci // Task used for oneshot renders 3648bf80f4bSopenharmony_ci singleFrameAsync = META_NS::MakeCallback<META_NS::ITaskQueueTask>([this]() { 3658bf80f4bSopenharmony_ci RenderFunction(); 3668bf80f4bSopenharmony_ci return 0; 3678bf80f4bSopenharmony_ci }); 3688bf80f4bSopenharmony_ci // Task used for oneshot synchronous renders 3698bf80f4bSopenharmony_ci singleFrameSync = META_NS::MakeCallback<META_NS::ITaskQueueWaitableTask>([this]() { 3708bf80f4bSopenharmony_ci RenderFunction(); 3718bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 3728bf80f4bSopenharmony_ci }); 3738bf80f4bSopenharmony_ci} 3748bf80f4bSopenharmony_ci// where to put this deinit 3758bf80f4bSopenharmony_civoid SceneAdapter::DeinitRenderThread() 3768bf80f4bSopenharmony_ci{ 3778bf80f4bSopenharmony_ci auto ioThread = META_NS::GetTaskQueueRegistry().GetTaskQueue(IO_QUEUE); 3788bf80f4bSopenharmony_ci if (renderTask) { 3798bf80f4bSopenharmony_ci engineThread->CancelTask(renderTask); 3808bf80f4bSopenharmony_ci renderTask = nullptr; 3818bf80f4bSopenharmony_ci } 3828bf80f4bSopenharmony_ci auto engine_deinit = META_NS::MakeCallback<META_NS::ITaskQueueWaitableTask>([]() { 3838bf80f4bSopenharmony_ci // destroy all swapchains 3848bf80f4bSopenharmony_ci auto &obr = META_NS::GetObjectRegistry(); 3858bf80f4bSopenharmony_ci auto doc = interface_cast<META_NS::IMetadata>(obr.GetDefaultObjectContext()); 3868bf80f4bSopenharmony_ci 3878bf80f4bSopenharmony_ci // hmm.. this is somewhat uncool 3888bf80f4bSopenharmony_ci { 3898bf80f4bSopenharmony_ci auto p1 = doc->GetPropertyByName<IntfPtr>("EngineQueue"); 3908bf80f4bSopenharmony_ci doc->RemoveProperty(p1); 3918bf80f4bSopenharmony_ci auto p2 = doc->GetPropertyByName<IntfPtr>("AppQueue"); 3928bf80f4bSopenharmony_ci doc->RemoveProperty(p2); 3938bf80f4bSopenharmony_ci auto p3 = doc->GetPropertyByName<IntfPtr>("RenderContext"); 3948bf80f4bSopenharmony_ci doc->RemoveProperty(p3); 3958bf80f4bSopenharmony_ci } 3968bf80f4bSopenharmony_ci 3978bf80f4bSopenharmony_ci doc->GetArrayPropertyByName<IntfWeakPtr>("Scenes")->Reset(); 3988bf80f4bSopenharmony_ci engineInstance_.renderContext_.reset(); 3998bf80f4bSopenharmony_ci engineInstance_.engine_.reset(); 4008bf80f4bSopenharmony_ci 4018bf80f4bSopenharmony_ci return META_NS::IAny::Ptr{}; 4028bf80f4bSopenharmony_ci }); 4038bf80f4bSopenharmony_ci engineThread->AddWaitableTask(engine_deinit)->Wait(); 4048bf80f4bSopenharmony_ci singleFrameAsync.reset(); 4058bf80f4bSopenharmony_ci auto &tr = META_NS::GetTaskQueueRegistry(); 4068bf80f4bSopenharmony_ci tr.UnregisterTaskQueue(ENGINE_THREAD); 4078bf80f4bSopenharmony_ci engineThread.reset(); 4088bf80f4bSopenharmony_ci tr.UnregisterTaskQueue(IO_QUEUE); 4098bf80f4bSopenharmony_ci ioThread.reset(); 4108bf80f4bSopenharmony_ci} 4118bf80f4bSopenharmony_ci 4128bf80f4bSopenharmony_civoid SceneAdapter::RenderFunction() 4138bf80f4bSopenharmony_ci{ 4148bf80f4bSopenharmony_ci WIDGET_SCOPED_TRACE("SceneAdapter::RenderFunction"); 4158bf80f4bSopenharmony_ci auto &obr = META_NS::GetObjectRegistry(); 4168bf80f4bSopenharmony_ci auto doc = interface_cast<META_NS::IMetadata>(obr.GetDefaultObjectContext()); 4178bf80f4bSopenharmony_ci BASE_NS::shared_ptr<RENDER_NS::IRenderContext> rc; 4188bf80f4bSopenharmony_ci if (auto prp = doc->GetPropertyByName<IntfPtr>("RenderContext")) { 4198bf80f4bSopenharmony_ci rc = interface_pointer_cast<RENDER_NS::IRenderContext>(prp->GetValue()); 4208bf80f4bSopenharmony_ci } 4218bf80f4bSopenharmony_ci LockCompositor(); 4228bf80f4bSopenharmony_ci auto scene = interface_pointer_cast<SCENE_NS::IScene>(sceneWidgetObj_); 4238bf80f4bSopenharmony_ci if (!bitmap_) { 4248bf80f4bSopenharmony_ci auto cams = scene->GetCameras(); 4258bf80f4bSopenharmony_ci if (!cams.empty()) { 4268bf80f4bSopenharmony_ci for (auto c : cams) { 4278bf80f4bSopenharmony_ci AttachSwapchain(interface_pointer_cast<META_NS::IObject>(c), swapchainHandle_); 4288bf80f4bSopenharmony_ci } 4298bf80f4bSopenharmony_ci } 4308bf80f4bSopenharmony_ci } 4318bf80f4bSopenharmony_ci scene->RenderCameras(); 4328bf80f4bSopenharmony_ci rc->GetRenderer().RenderDeferredFrame(); 4338bf80f4bSopenharmony_ci UnlockCompositor(); 4348bf80f4bSopenharmony_ci} 4358bf80f4bSopenharmony_ci 4368bf80f4bSopenharmony_civoid SceneAdapter::RenderFrame(bool needsSyncPaint) 4378bf80f4bSopenharmony_ci{ 4388bf80f4bSopenharmony_ci if (renderTask) { 4398bf80f4bSopenharmony_ci engineThread->CancelTask(renderTask); 4408bf80f4bSopenharmony_ci renderTask = nullptr; 4418bf80f4bSopenharmony_ci } 4428bf80f4bSopenharmony_ci 4438bf80f4bSopenharmony_ci if (!needsSyncPaint) { 4448bf80f4bSopenharmony_ci renderTask = engineThread->AddTask(singleFrameAsync); 4458bf80f4bSopenharmony_ci } else { 4468bf80f4bSopenharmony_ci engineThread->AddWaitableTask(singleFrameSync)->Wait(); 4478bf80f4bSopenharmony_ci } 4488bf80f4bSopenharmony_ci} 4498bf80f4bSopenharmony_ci 4508bf80f4bSopenharmony_cibool SceneAdapter::NeedsRepaint() 4518bf80f4bSopenharmony_ci{ 4528bf80f4bSopenharmony_ci return needsRepaint_; 4538bf80f4bSopenharmony_ci} 4548bf80f4bSopenharmony_ci 4558bf80f4bSopenharmony_civoid SceneAdapter::AttachSwapchain(META_NS::IObject::Ptr cameraObj, RENDER_NS::RenderHandleReference swapchain) 4568bf80f4bSopenharmony_ci{ 4578bf80f4bSopenharmony_ci WIDGET_LOGD("attach swapchain"); 4588bf80f4bSopenharmony_ci auto scene = interface_cast<SCENE_NS::INode>(cameraObj)->GetScene(); 4598bf80f4bSopenharmony_ci auto camera = interface_pointer_cast<SCENE_NS::ICamera>(cameraObj); 4608bf80f4bSopenharmony_ci if (scene->IsCameraActive(camera)) { 4618bf80f4bSopenharmony_ci auto externalBitmapUid = BASE_NS::Uid("77b38a92-8182-4562-bd3f-deab7b40cedc"); 4628bf80f4bSopenharmony_ci bitmap_ = META_NS::GetObjectRegistry().Create<SCENE_NS::IBitmap>(externalBitmapUid); 4638bf80f4bSopenharmony_ci 4648bf80f4bSopenharmony_ci scene->SetBitmap(bitmap_, camera); 4658bf80f4bSopenharmony_ci const auto &info = textureLayer_->GetTextureInfo(); 4668bf80f4bSopenharmony_ci 4678bf80f4bSopenharmony_ci bitmap_->SetRenderHandle(swapchainHandle_, 4688bf80f4bSopenharmony_ci { static_cast<uint32_t>(info.width_ * info.widthScale_), 4698bf80f4bSopenharmony_ci static_cast<uint32_t>(info.height_ * info.heightScale_) }); 4708bf80f4bSopenharmony_ci } 4718bf80f4bSopenharmony_ci} 4728bf80f4bSopenharmony_ci} // namespace OHOS::Render3D 473