• 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;
ToNative(ToneMapJS::ToneMappingType typeI)31 SCENE_NS::TonemapType ToNative(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 }
ToJs(SCENE_NS::TonemapType typeI)51 ToneMapJS::ToneMappingType ToJs(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 
ToNativeType(uint32_t typeI)72 SCENE_NS::TonemapType ToneMapJS::ToNativeType(uint32_t typeI)
73 {
74     return ToNative(static_cast<ToneMapJS::ToneMappingType>(typeI));
75 }
76 
Init(napi_env env,napi_value exports)77 void ToneMapJS::Init(napi_env env, napi_value exports)
78 {
79     using namespace NapiApi;
80 
81     BASE_NS::vector<napi_property_descriptor> node_props;
82     // clang-format off
83     node_props.emplace_back(GetSetProperty<uint32_t, ToneMapJS, &ToneMapJS::GetType, &ToneMapJS::SetType>("type"));
84     node_props.emplace_back(
85         GetSetProperty<float, ToneMapJS, &ToneMapJS::GetExposure, &ToneMapJS::SetExposure>("exposure"));
86     node_props.push_back(MakeTROMethod<NapiApi::FunctionContext<>, ToneMapJS, &ToneMapJS::Dispose>("destroy"));
87     // clang-format on
88 
89     napi_value func;
90     auto status = napi_define_class(env, "ToneMappingSettings", NAPI_AUTO_LENGTH, BaseObject::ctor<ToneMapJS>(),
91         nullptr, node_props.size(), node_props.data(), &func);
92 
93     NapiApi::MyInstanceState* mis;
94     NapiApi::MyInstanceState::GetInstance(env, (void**)&mis);
95     if (mis) {
96         mis->StoreCtor("ToneMappingSettings", func);
97     }
98 
99     NapiApi::Object exp(env, exports);
100 
101     napi_value eType, v;
102     napi_create_object(env, &eType);
103 #define DECL_ENUM(enu, x)                            \
104     napi_create_uint32(env, ToneMappingType::x, &v); \
105     napi_set_named_property(env, enu, #x, v);
106 
107     DECL_ENUM(eType, ACES);
108     DECL_ENUM(eType, ACES_2020);
109     DECL_ENUM(eType, FILMIC);
110 #undef DECL_ENUM
111     exp.Set("ToneMappingType", eType);
112 }
113 
Dispose(NapiApi::FunctionContext<> & ctx)114 napi_value ToneMapJS::Dispose(NapiApi::FunctionContext<>& ctx)
115 {
116     LOG_V("ToneMapJS::Dispose");
117     DisposeNative(nullptr);
118     return {};
119 }
DisposeNative(void *)120 void ToneMapJS::DisposeNative(void*)
121 {
122     if (!disposed_) {
123         disposed_ = true;
124         LOG_V("ToneMapJS::DisposeNative");
125         UnsetNativeObject();
126     }
127 }
UnbindFromNative()128 void ToneMapJS::UnbindFromNative()
129 {
130     // We don't use a property proxy, so update members manually.
131     if (auto toneMap = GetNativeObject<SCENE_NS::ITonemap>()) {
132         type_ = ToJs(toneMap->Type()->GetValue());
133         exposure_ = toneMap->Exposure()->GetValue();
134     }
135     UnsetNativeObject();
136 }
137 
BindToNative(SCENE_NS::ITonemap::Ptr native)138 void ToneMapJS::BindToNative(SCENE_NS::ITonemap::Ptr native)
139 {
140     SetNativeObject(interface_pointer_cast<META_NS::IObject>(native), PtrType::WEAK);
141     if (auto toneMap = GetNativeObject<SCENE_NS::ITonemap>()) {
142         toneMap->Type()->SetValue(ToNative(type_));
143         toneMap->Exposure()->SetValue(exposure_);
144     }
145 }
146 
GetInstanceImpl(uint32_t id)147 void* ToneMapJS::GetInstanceImpl(uint32_t id)
148 {
149     if (id == ToneMapJS::ID)
150         return this;
151     return nullptr;
152 }
Finalize(napi_env env)153 void ToneMapJS::Finalize(napi_env env)
154 {
155     DisposeNative(nullptr);
156     BaseObject::Finalize(env);
157 }
158 
ToneMapJS(napi_env e,napi_callback_info i)159 ToneMapJS::ToneMapJS(napi_env e, napi_callback_info i)
160     : BaseObject(e, i), type_(DEFAULT_TYPE), exposure_(DEFAULT_EXPOSURE)
161 {
162     LOG_V("ToneMapJS ++");
163     auto tonemap = GetNativeObject<SCENE_NS::ITonemap>();
164     if (!tonemap) {
165         LOG_E("Cannot finish creating a tonemap: Native tonemap object missing");
166         assert(false);
167         return;
168     }
169 
170     // We accept 0 and 1 arg calls. If we get 0, do nothing so original tonemap stays unchanged.
171     NapiApi::FunctionContext<NapiApi::Object> ctx(e, i);
172     if (!ctx) {
173         if (ctx.ArgCount() != 0) {
174             LOG_E("Cannot finish creating a tonemap: Invalid args given");
175             assert(false);
176         }
177         return;
178     }
179 
180     NapiApi::Object toneMapArgs = ctx.Arg<0>();
181     exposure_ = toneMapArgs.Get<float>("exposure").valueOrDefault(exposure_);
182     type_ = static_cast<ToneMappingType>(toneMapArgs.Get<uint32_t>("type").valueOrDefault(type_));
183     tonemap->Type()->SetValue(ToNative(type_));
184     tonemap->Exposure()->SetValue(exposure_);
185     tonemap->Enabled()->SetValue(true);
186 }
187 
~ToneMapJS()188 ToneMapJS::~ToneMapJS()
189 {
190     LOG_V("ToneMapJS --");
191     DisposeNative(nullptr);
192     if (!GetNativeObject()) {
193         return;
194     }
195 }
196 
GetType(NapiApi::FunctionContext<> & ctx)197 napi_value ToneMapJS::GetType(NapiApi::FunctionContext<>& ctx)
198 {
199     if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
200         type_ = ToJs(toneMap->Type()->GetValue());
201     }
202 
203     return ctx.GetNumber(static_cast<uint32_t>(type_));
204 }
205 
SetType(NapiApi::FunctionContext<uint32_t> & ctx)206 void ToneMapJS::SetType(NapiApi::FunctionContext<uint32_t>& ctx)
207 {
208     const auto nativeType = ToNativeType(ctx.Arg<0>());
209     type_ = ToJs(nativeType);
210 
211     if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
212         toneMap->Type()->SetValue(nativeType);
213     }
214 }
215 
GetExposure(NapiApi::FunctionContext<> & ctx)216 napi_value ToneMapJS::GetExposure(NapiApi::FunctionContext<>& ctx)
217 {
218     if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
219         exposure_ = toneMap->Exposure()->GetValue();
220     }
221 
222     return ctx.GetNumber(exposure_);
223 }
224 
SetExposure(NapiApi::FunctionContext<float> & ctx)225 void ToneMapJS::SetExposure(NapiApi::FunctionContext<float>& ctx)
226 {
227     exposure_ = ctx.Arg<0>();
228     if (auto toneMap = interface_cast<SCENE_NS::ITonemap>(GetNativeObject())) {
229         toneMap->Exposure()->SetValue(exposure_);
230     }
231 }
232