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 "ToneMapJS.h" 168bf80f4bSopenharmony_ci 178bf80f4bSopenharmony_ci#include <meta/api/make_callback.h> 188bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue.h> 198bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue_registry.h> 208bf80f4bSopenharmony_ci#include <meta/interface/property/property_events.h> 218bf80f4bSopenharmony_ci#include <scene_plugin/api/camera.h> //for the classid... 228bf80f4bSopenharmony_ci#include <scene_plugin/api/node_uid.h> 238bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_ecs_scene.h> 248bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_node.h> 258bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_postprocess.h> 268bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_scene.h> 278bf80f4bSopenharmony_ci 288bf80f4bSopenharmony_ci#include <render/intf_render_context.h> 298bf80f4bSopenharmony_ci 308bf80f4bSopenharmony_ci#include "PostProcJS.h" 318bf80f4bSopenharmony_ciusing IntfPtr = BASE_NS::shared_ptr<CORE_NS::IInterface>; 328bf80f4bSopenharmony_ciusing IntfWeakPtr = BASE_NS::weak_ptr<CORE_NS::IInterface>; 338bf80f4bSopenharmony_ciusing namespace SCENE_NS; 348bf80f4bSopenharmony_ciSCENE_NS::ITonemap::TonemapType ConvertTo(ToneMapJS::ToneMappingType typeI) 358bf80f4bSopenharmony_ci{ 368bf80f4bSopenharmony_ci SCENE_NS::ITonemap::TonemapType type; 378bf80f4bSopenharmony_ci switch (typeI) { 388bf80f4bSopenharmony_ci case ToneMapJS::ToneMappingType::ACES: 398bf80f4bSopenharmony_ci type = SCENE_NS::ITonemap::TonemapType::ACES; 408bf80f4bSopenharmony_ci break; 418bf80f4bSopenharmony_ci case ToneMapJS::ToneMappingType::ACES_2020: 428bf80f4bSopenharmony_ci type = SCENE_NS::ITonemap::TonemapType::ACES_2020; 438bf80f4bSopenharmony_ci break; 448bf80f4bSopenharmony_ci case ToneMapJS::ToneMappingType::FILMIC: 458bf80f4bSopenharmony_ci type = SCENE_NS::ITonemap::TonemapType::FILMIC; 468bf80f4bSopenharmony_ci break; 478bf80f4bSopenharmony_ci default: 488bf80f4bSopenharmony_ci // default from lowlev.. 498bf80f4bSopenharmony_ci type = ITonemap::TonemapType::ACES; 508bf80f4bSopenharmony_ci break; 518bf80f4bSopenharmony_ci } 528bf80f4bSopenharmony_ci return type; 538bf80f4bSopenharmony_ci} 548bf80f4bSopenharmony_ciToneMapJS::ToneMappingType ConvertFrom(SCENE_NS::ITonemap::TonemapType typeI) 558bf80f4bSopenharmony_ci{ 568bf80f4bSopenharmony_ci ToneMapJS::ToneMappingType type; 578bf80f4bSopenharmony_ci switch (typeI) { 588bf80f4bSopenharmony_ci case SCENE_NS::ITonemap::TonemapType::ACES: 598bf80f4bSopenharmony_ci type = ToneMapJS::ToneMappingType::ACES; 608bf80f4bSopenharmony_ci break; 618bf80f4bSopenharmony_ci case SCENE_NS::ITonemap::TonemapType::ACES_2020: 628bf80f4bSopenharmony_ci type = ToneMapJS::ToneMappingType::ACES_2020; 638bf80f4bSopenharmony_ci break; 648bf80f4bSopenharmony_ci case SCENE_NS::ITonemap::TonemapType::FILMIC: 658bf80f4bSopenharmony_ci type = ToneMapJS::ToneMappingType ::FILMIC; 668bf80f4bSopenharmony_ci break; 678bf80f4bSopenharmony_ci default: 688bf80f4bSopenharmony_ci // default from lowlev.. 698bf80f4bSopenharmony_ci type = ToneMapJS::ToneMappingType ::ACES; 708bf80f4bSopenharmony_ci break; 718bf80f4bSopenharmony_ci } 728bf80f4bSopenharmony_ci return type; 738bf80f4bSopenharmony_ci} 748bf80f4bSopenharmony_ci 758bf80f4bSopenharmony_ciSCENE_NS::ITonemap::TonemapType ConvertTo(uint32_t typeI) 768bf80f4bSopenharmony_ci{ 778bf80f4bSopenharmony_ci return ConvertTo(static_cast<ToneMapJS::ToneMappingType>(typeI)); 788bf80f4bSopenharmony_ci} 798bf80f4bSopenharmony_civoid ToneMapJS::Init(napi_env env, napi_value exports) 808bf80f4bSopenharmony_ci{ 818bf80f4bSopenharmony_ci using namespace NapiApi; 828bf80f4bSopenharmony_ci 838bf80f4bSopenharmony_ci BASE_NS::vector<napi_property_descriptor> node_props; 848bf80f4bSopenharmony_ci // clang-format off 858bf80f4bSopenharmony_ci node_props.emplace_back(GetSetProperty<uint32_t, ToneMapJS, &ToneMapJS::GetType, &ToneMapJS::SetType>("type")); 868bf80f4bSopenharmony_ci node_props.emplace_back(GetSetProperty<float, ToneMapJS, &ToneMapJS::GetExposure, 878bf80f4bSopenharmony_ci &ToneMapJS::SetExposure>("exposure")); 888bf80f4bSopenharmony_ci node_props.push_back(MakeTROMethod<NapiApi::FunctionContext<>, ToneMapJS, &ToneMapJS::Dispose>("destroy")); 898bf80f4bSopenharmony_ci // clang-format on 908bf80f4bSopenharmony_ci 918bf80f4bSopenharmony_ci napi_value func; 928bf80f4bSopenharmony_ci auto status = napi_define_class(env, "ToneMappingSettings", NAPI_AUTO_LENGTH, BaseObject::ctor<ToneMapJS>(), 938bf80f4bSopenharmony_ci nullptr, node_props.size(), node_props.data(), &func); 948bf80f4bSopenharmony_ci 958bf80f4bSopenharmony_ci NapiApi::MyInstanceState* mis; 968bf80f4bSopenharmony_ci napi_get_instance_data(env, (void**)&mis); 978bf80f4bSopenharmony_ci mis->StoreCtor("ToneMappingSettings", func); 988bf80f4bSopenharmony_ci 998bf80f4bSopenharmony_ci NapiApi::Object exp(env, exports); 1008bf80f4bSopenharmony_ci 1018bf80f4bSopenharmony_ci napi_value eType; 1028bf80f4bSopenharmony_ci napi_value v; 1038bf80f4bSopenharmony_ci napi_create_object(env, &eType); 1048bf80f4bSopenharmony_ci#define DECL_ENUM(enu, x) \ 1058bf80f4bSopenharmony_ci napi_create_uint32(env, ToneMappingType::x, &v); \ 1068bf80f4bSopenharmony_ci napi_set_named_property(env, enu, #x, v); 1078bf80f4bSopenharmony_ci 1088bf80f4bSopenharmony_ci DECL_ENUM(eType, ACES); 1098bf80f4bSopenharmony_ci DECL_ENUM(eType, ACES_2020); 1108bf80f4bSopenharmony_ci DECL_ENUM(eType, FILMIC); 1118bf80f4bSopenharmony_ci#undef DECL_ENUM 1128bf80f4bSopenharmony_ci exp.Set("ToneMappingType", eType); 1138bf80f4bSopenharmony_ci} 1148bf80f4bSopenharmony_ci 1158bf80f4bSopenharmony_cinapi_value ToneMapJS::Dispose(NapiApi::FunctionContext<>& ctx) 1168bf80f4bSopenharmony_ci{ 1178bf80f4bSopenharmony_ci LOG_F("ToneMapJS::Dispose"); 1188bf80f4bSopenharmony_ci DisposeNative(); 1198bf80f4bSopenharmony_ci return {}; 1208bf80f4bSopenharmony_ci} 1218bf80f4bSopenharmony_civoid ToneMapJS::DisposeNative() 1228bf80f4bSopenharmony_ci{ 1238bf80f4bSopenharmony_ci if (!disposed_) { 1248bf80f4bSopenharmony_ci disposed_ = true; 1258bf80f4bSopenharmony_ci LOG_F("ToneMapJS::DisposeNative"); 1268bf80f4bSopenharmony_ci if (auto tmp = interface_pointer_cast<SCENE_NS::ITonemap>(GetNativeObject())) { 1278bf80f4bSopenharmony_ci // reset the native object refs 1288bf80f4bSopenharmony_ci SetNativeObject(nullptr, false); 1298bf80f4bSopenharmony_ci SetNativeObject(nullptr, true); 1308bf80f4bSopenharmony_ci 1318bf80f4bSopenharmony_ci ExecSyncTask([scn = BASE_NS::move(tmp)]() { return META_NS::IAny::Ptr {}; }); 1328bf80f4bSopenharmony_ci } 1338bf80f4bSopenharmony_ci } 1348bf80f4bSopenharmony_ci} 1358bf80f4bSopenharmony_civoid* ToneMapJS::GetInstanceImpl(uint32_t id) 1368bf80f4bSopenharmony_ci{ 1378bf80f4bSopenharmony_ci if (id == ToneMapJS::ID) { 1388bf80f4bSopenharmony_ci return this; 1398bf80f4bSopenharmony_ci } 1408bf80f4bSopenharmony_ci return nullptr; 1418bf80f4bSopenharmony_ci} 1428bf80f4bSopenharmony_civoid ToneMapJS::Finalize(napi_env env) 1438bf80f4bSopenharmony_ci{ 1448bf80f4bSopenharmony_ci // hmm.. do i need to do something BEFORE the object gets deleted.. 1458bf80f4bSopenharmony_ci DisposeNative(); 1468bf80f4bSopenharmony_ci BaseObject<ToneMapJS>::Finalize(env); 1478bf80f4bSopenharmony_ci} 1488bf80f4bSopenharmony_ci 1498bf80f4bSopenharmony_ciToneMapJS::ToneMapJS(napi_env e, napi_callback_info i) : BaseObject<ToneMapJS>(e, i) 1508bf80f4bSopenharmony_ci{ 1518bf80f4bSopenharmony_ci LOG_F("ToneMapJS ++"); 1528bf80f4bSopenharmony_ci NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i); 1538bf80f4bSopenharmony_ci if (!fromJs) { 1548bf80f4bSopenharmony_ci // no arguments. so internal create. 1558bf80f4bSopenharmony_ci // expecting caller to finish 1568bf80f4bSopenharmony_ci return; 1578bf80f4bSopenharmony_ci } 1588bf80f4bSopenharmony_ci // postprocess that we bind to.. 1598bf80f4bSopenharmony_ci NapiApi::Object postProcJS = fromJs.Arg<0>(); 1608bf80f4bSopenharmony_ci auto postproc = GetNativeMeta<SCENE_NS::IPostProcess>(postProcJS); 1618bf80f4bSopenharmony_ci NapiApi::Object toneMapArgs = fromJs.Arg<1>(); 1628bf80f4bSopenharmony_ci // now, based on parameters, initialize the object 1638bf80f4bSopenharmony_ci // so it is a tonemap 1648bf80f4bSopenharmony_ci float exposure = toneMapArgs.Get<float>("exposure").valueOrDefault(0.7); 1658bf80f4bSopenharmony_ci SCENE_NS::ITonemap::TonemapType type = 1668bf80f4bSopenharmony_ci ConvertTo(toneMapArgs.Get<uint32_t>("type").valueOrDefault(ToneMappingType::ACES)); 1678bf80f4bSopenharmony_ci 1688bf80f4bSopenharmony_ci auto tonemap = GetNativeObjectParam<SCENE_NS::ITonemap>(toneMapArgs); 1698bf80f4bSopenharmony_ci 1708bf80f4bSopenharmony_ci ExecSyncTask([&tonemap, exposure, type, postproc]() -> META_NS::IAny::Ptr { 1718bf80f4bSopenharmony_ci if (!tonemap) { 1728bf80f4bSopenharmony_ci tonemap = META_NS::GetObjectRegistry().Create<SCENE_NS::ITonemap>(SCENE_NS::ClassId::Tonemap); 1738bf80f4bSopenharmony_ci } 1748bf80f4bSopenharmony_ci tonemap->Type()->SetValue(type); 1758bf80f4bSopenharmony_ci tonemap->Exposure()->SetValue(exposure); 1768bf80f4bSopenharmony_ci tonemap->Enabled()->SetValue(true); 1778bf80f4bSopenharmony_ci postproc->Tonemap()->SetValue(tonemap); 1788bf80f4bSopenharmony_ci return {}; 1798bf80f4bSopenharmony_ci }); 1808bf80f4bSopenharmony_ci auto obj = interface_pointer_cast<META_NS::IObject>(tonemap); 1818bf80f4bSopenharmony_ci // process constructor args.. 1828bf80f4bSopenharmony_ci NapiApi::Object meJs(e, fromJs.This()); 1838bf80f4bSopenharmony_ci // weak ref, due to the ToneMap class being owned by the postprocess. 1848bf80f4bSopenharmony_ci SetNativeObject(obj, false); 1858bf80f4bSopenharmony_ci StoreJsObj(obj, meJs); 1868bf80f4bSopenharmony_ci} 1878bf80f4bSopenharmony_ci 1888bf80f4bSopenharmony_ciToneMapJS::~ToneMapJS() 1898bf80f4bSopenharmony_ci{ 1908bf80f4bSopenharmony_ci LOG_F("ToneMapJS --"); 1918bf80f4bSopenharmony_ci DisposeNative(); 1928bf80f4bSopenharmony_ci if (!GetNativeObject()) { 1938bf80f4bSopenharmony_ci return; 1948bf80f4bSopenharmony_ci } 1958bf80f4bSopenharmony_ci} 1968bf80f4bSopenharmony_ci 1978bf80f4bSopenharmony_cinapi_value ToneMapJS::GetType(NapiApi::FunctionContext<>& ctx) 1988bf80f4bSopenharmony_ci{ 1998bf80f4bSopenharmony_ci SCENE_NS::ITonemap::TonemapType type = SCENE_NS::ITonemap::TonemapType::ACES; // default 2008bf80f4bSopenharmony_ci if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) { 2018bf80f4bSopenharmony_ci ExecSyncTask([toneMap, &type]() { 2028bf80f4bSopenharmony_ci type = toneMap->Type()->GetValue(); 2038bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 2048bf80f4bSopenharmony_ci }); 2058bf80f4bSopenharmony_ci } 2068bf80f4bSopenharmony_ci 2078bf80f4bSopenharmony_ci auto typeI = ConvertFrom(type); 2088bf80f4bSopenharmony_ci napi_value value; 2098bf80f4bSopenharmony_ci napi_status status = napi_create_uint32(ctx, static_cast<uint32_t>(typeI), &value); 2108bf80f4bSopenharmony_ci return value; 2118bf80f4bSopenharmony_ci} 2128bf80f4bSopenharmony_civoid ToneMapJS::SetType(NapiApi::FunctionContext<uint32_t>& ctx) 2138bf80f4bSopenharmony_ci{ 2148bf80f4bSopenharmony_ci auto type = ConvertTo(ctx.Arg<0>()); 2158bf80f4bSopenharmony_ci 2168bf80f4bSopenharmony_ci if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) { 2178bf80f4bSopenharmony_ci ExecSyncTask([toneMap, type]() { 2188bf80f4bSopenharmony_ci toneMap->Type()->SetValue(type); 2198bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 2208bf80f4bSopenharmony_ci }); 2218bf80f4bSopenharmony_ci } 2228bf80f4bSopenharmony_ci} 2238bf80f4bSopenharmony_ci 2248bf80f4bSopenharmony_cinapi_value ToneMapJS::GetExposure(NapiApi::FunctionContext<>& ctx) 2258bf80f4bSopenharmony_ci{ 2268bf80f4bSopenharmony_ci float exp = 0.0; 2278bf80f4bSopenharmony_ci if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) { 2288bf80f4bSopenharmony_ci ExecSyncTask([toneMap, &exp]() { 2298bf80f4bSopenharmony_ci exp = toneMap->Exposure()->GetValue(); 2308bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 2318bf80f4bSopenharmony_ci }); 2328bf80f4bSopenharmony_ci } 2338bf80f4bSopenharmony_ci 2348bf80f4bSopenharmony_ci napi_value value; 2358bf80f4bSopenharmony_ci napi_status status = napi_create_double(ctx, exp, &value); 2368bf80f4bSopenharmony_ci return value; 2378bf80f4bSopenharmony_ci} 2388bf80f4bSopenharmony_ci 2398bf80f4bSopenharmony_civoid ToneMapJS::SetExposure(NapiApi::FunctionContext<float>& ctx) 2408bf80f4bSopenharmony_ci{ 2418bf80f4bSopenharmony_ci float exp = ctx.Arg<0>(); 2428bf80f4bSopenharmony_ci if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) { 2438bf80f4bSopenharmony_ci ExecSyncTask([toneMap, exp]() { 2448bf80f4bSopenharmony_ci toneMap->Exposure()->SetValue(exp); 2458bf80f4bSopenharmony_ci return META_NS::IAny::Ptr {}; 2468bf80f4bSopenharmony_ci }); 2478bf80f4bSopenharmony_ci } 2488bf80f4bSopenharmony_ci} 249