• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "ToneMapJS.h"
17 
18 #include <meta/api/make_callback.h>
19 #include <meta/interface/intf_task_queue.h>
20 #include <meta/interface/intf_task_queue_registry.h>
21 #include <meta/interface/property/property_events.h>
22 #include <scene/interface/intf_node.h>
23 #include <scene/interface/intf_postprocess.h>
24 #include <scene/interface/intf_scene.h>
25 
26 #include <render/intf_render_context.h>
27 
28 using IntfPtr = BASE_NS::shared_ptr<CORE_NS::IInterface>;
29 using IntfWeakPtr = BASE_NS::weak_ptr<CORE_NS::IInterface>;
30 using namespace SCENE_NS;
ConvertTo(ToneMapJS::ToneMappingType typeI)31 SCENE_NS::TonemapType ConvertTo(ToneMapJS::ToneMappingType typeI)
32 {
33     SCENE_NS::TonemapType type;
34     switch (typeI) {
35         case ToneMapJS::ToneMappingType::ACES:
36             type = SCENE_NS::TonemapType::ACES;
37             break;
38         case ToneMapJS::ToneMappingType::ACES_2020:
39             type = SCENE_NS::TonemapType::ACES_2020;
40             break;
41         case ToneMapJS::ToneMappingType::FILMIC:
42             type = SCENE_NS::TonemapType::FILMIC;
43             break;
44         default:
45             // default from lowlev..
46             type = SCENE_NS::TonemapType::ACES;
47             break;
48     }
49     return type;
50 }
ConvertFrom(SCENE_NS::TonemapType typeI)51 ToneMapJS::ToneMappingType ConvertFrom(SCENE_NS::TonemapType typeI)
52 {
53     ToneMapJS::ToneMappingType type;
54     switch (typeI) {
55         case SCENE_NS::TonemapType::ACES:
56             type = ToneMapJS::ToneMappingType::ACES;
57             break;
58         case SCENE_NS::TonemapType::ACES_2020:
59             type = ToneMapJS::ToneMappingType::ACES_2020;
60             break;
61         case SCENE_NS::TonemapType::FILMIC:
62             type = ToneMapJS::ToneMappingType ::FILMIC;
63             break;
64         default:
65             // default from lowlev..
66             type = ToneMapJS::ToneMappingType ::ACES;
67             break;
68     }
69     return type;
70 }
71 
ConvertTo(uint32_t typeI)72 SCENE_NS::TonemapType ConvertTo(uint32_t typeI)
73 {
74     return ConvertTo(static_cast<ToneMapJS::ToneMappingType>(typeI));
75 }
Init(napi_env env,napi_value exports)76 void ToneMapJS::Init(napi_env env, napi_value exports)
77 {
78     using namespace NapiApi;
79 
80     BASE_NS::vector<napi_property_descriptor> node_props;
81     // clang-format off
82     node_props.emplace_back(GetSetProperty<uint32_t, ToneMapJS, &ToneMapJS::GetType, &ToneMapJS::SetType>("type"));
83     node_props.emplace_back(
84         GetSetProperty<float, ToneMapJS, &ToneMapJS::GetExposure, &ToneMapJS::SetExposure>("exposure"));
85     node_props.push_back(MakeTROMethod<NapiApi::FunctionContext<>, ToneMapJS, &ToneMapJS::Dispose>("destroy"));
86     // clang-format on
87 
88     napi_value func;
89     auto status = napi_define_class(env, "ToneMappingSettings", NAPI_AUTO_LENGTH, BaseObject::ctor<ToneMapJS>(),
90         nullptr, node_props.size(), node_props.data(), &func);
91 
92     NapiApi::MyInstanceState* mis;
93     GetInstanceData(env, (void**)&mis);
94     mis->StoreCtor("ToneMappingSettings", func);
95 
96     NapiApi::Object exp(env, exports);
97 
98     napi_value eType;
99     napi_value v;
100     napi_create_object(env, &eType);
101 #define DECL_ENUM(enu, x)                            \
102     napi_create_uint32(env, ToneMappingType::x, &v); \
103     napi_set_named_property(env, enu, #x, v);
104 
105     DECL_ENUM(eType, ACES);
106     DECL_ENUM(eType, ACES_2020);
107     DECL_ENUM(eType, FILMIC);
108 #undef DECL_ENUM
109     exp.Set("ToneMappingType", eType);
110 }
111 
Dispose(NapiApi::FunctionContext<> & ctx)112 napi_value ToneMapJS::Dispose(NapiApi::FunctionContext<>& ctx)
113 {
114     LOG_V("ToneMapJS::Dispose");
115     DisposeNative(nullptr);
116     return {};
117 }
DisposeNative(void *)118 void ToneMapJS::DisposeNative(void*)
119 {
120     if (!disposed_) {
121         disposed_ = true;
122         LOG_V("ToneMapJS::DisposeNative");
123         if (auto tmp = interface_pointer_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
124             // reset the native object refs
125             SetNativeObject(nullptr, false);
126             SetNativeObject(nullptr, true);
127         }
128     }
129 }
GetInstanceImpl(uint32_t id)130 void* ToneMapJS::GetInstanceImpl(uint32_t id)
131 {
132     if (id == ToneMapJS::ID)
133         return this;
134     return nullptr;
135 }
Finalize(napi_env env)136 void ToneMapJS::Finalize(napi_env env)
137 {
138     DisposeNative(nullptr);
139     BaseObject<ToneMapJS>::Finalize(env);
140 }
141 
ToneMapJS(napi_env e,napi_callback_info i)142 ToneMapJS::ToneMapJS(napi_env e, napi_callback_info i) : BaseObject<ToneMapJS>(e, i)
143 {
144     LOG_V("ToneMapJS ++");
145     NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
146     if (!fromJs) {
147         // no arguments. so internal create.
148         // expecting caller to finish
149         return;
150     }
151 
152     // postprocess that we bind to..
153     NapiApi::Object postProcJS = fromJs.Arg<0>();
154     auto postproc = GetNativeMeta<SCENE_NS::IPostProcess>(postProcJS);
155 
156     NapiApi::Object toneMapArgs = fromJs.Arg<1>();
157 
158     // now, based on parameters, initialize the object
159     // so it is a tonemap
160     float exposure = toneMapArgs.Get<float>("exposure").valueOrDefault(0.7);
161     SCENE_NS::TonemapType type =
162         ConvertTo(toneMapArgs.Get<uint32_t>("type").valueOrDefault(ToneMappingType::ACES));
163 
164     auto tonemap = GetNativeObjectParam<SCENE_NS::ITonemap>(toneMapArgs);
165     if (!tonemap) {
166         tonemap = META_NS::GetObjectRegistry().Create<SCENE_NS::ITonemap>(SCENE_NS::ClassId::Tonemap);
167     }
168     tonemap->Type()->SetValue(type);
169     tonemap->Exposure()->SetValue(exposure);
170     tonemap->Enabled()->SetValue(true);
171     postproc->Tonemap()->SetValue(tonemap);
172     auto obj = interface_pointer_cast<META_NS::IObject>(tonemap);
173     //  process constructor args..
174     NapiApi::Object meJs(fromJs.This());
175     // weak ref, due to the ToneMap class being owned by the postprocess.
176     SetNativeObject(obj, false);
177     StoreJsObj(obj, meJs);
178 }
179 
~ToneMapJS()180 ToneMapJS::~ToneMapJS()
181 {
182     LOG_V("ToneMapJS --");
183     DisposeNative(nullptr);
184     if (!GetNativeObject()) {
185         return;
186     }
187 }
188 
GetType(NapiApi::FunctionContext<> & ctx)189 napi_value ToneMapJS::GetType(NapiApi::FunctionContext<>& ctx)
190 {
191     SCENE_NS::TonemapType type = SCENE_NS::TonemapType::ACES; // default
192     if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
193         type = toneMap->Type()->GetValue();
194     }
195 
196     auto typeI = ConvertFrom(type);
197     return ctx.GetNumber(static_cast<uint32_t>(typeI));
198 }
SetType(NapiApi::FunctionContext<uint32_t> & ctx)199 void ToneMapJS::SetType(NapiApi::FunctionContext<uint32_t>& ctx)
200 {
201     auto type = ConvertTo(ctx.Arg<0>());
202 
203     if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
204         toneMap->Type()->SetValue(type);
205     }
206 }
207 
GetExposure(NapiApi::FunctionContext<> & ctx)208 napi_value ToneMapJS::GetExposure(NapiApi::FunctionContext<>& ctx)
209 {
210     float exp = 0.0;
211     if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
212         exp = toneMap->Exposure()->GetValue();
213     }
214 
215     return ctx.GetNumber(exp);
216 }
217 
SetExposure(NapiApi::FunctionContext<float> & ctx)218 void ToneMapJS::SetExposure(NapiApi::FunctionContext<float>& ctx)
219 {
220     float exp = ctx.Arg<0>();
221     if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
222         toneMap->Exposure()->SetValue(exp);
223     }
224 }
225