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 #include "BloomJS.h"
16
17 #include "BaseObjectJS.h"
18
19 template<napi_value (BloomConfiguration::*F)(NapiApi::FunctionContext<>&)>
Method(napi_env env,napi_callback_info info)20 napi_value BloomConfiguration::Method(napi_env env, napi_callback_info info)
21 {
22 NapiApi::FunctionContext fc(env, info);
23 if (fc && fc.This()) {
24 BloomConfiguration* impl = nullptr;
25 napi_unwrap(fc.GetEnv(), fc.This().ToNapiValue(), (void**)&impl);
26 if (impl) {
27 return (impl->*F)(fc);
28 }
29 }
30 return fc.GetUndefined();
31 }
32
33 template<napi_value (BloomConfiguration::*F)(NapiApi::FunctionContext<>&)>
Getter(napi_env env,napi_callback_info info)34 napi_value BloomConfiguration::Getter(napi_env env, napi_callback_info info)
35 {
36 NapiApi::FunctionContext fc(env, info);
37 if (fc && fc.This()) {
38 BloomConfiguration* impl = nullptr;
39 napi_unwrap(fc.GetEnv(), fc.This().ToNapiValue(), (void**)&impl);
40 if (impl) {
41 return (impl->*F)(fc);
42 }
43 }
44 return fc.GetUndefined();
45 }
46 template<typename Type, void (BloomConfiguration::*F)(NapiApi::FunctionContext<Type>&)>
Setter(napi_env env,napi_callback_info info)47 inline napi_value BloomConfiguration::Setter(napi_env env, napi_callback_info info)
48 {
49 NapiApi::FunctionContext<Type> fc(env, info);
50 if (fc && fc.This()) {
51 BloomConfiguration* impl = nullptr;
52 napi_unwrap(fc.GetEnv(), fc.This().ToNapiValue(), (void**)&impl);
53 if (impl) {
54 (impl->*F)(fc);
55 }
56 }
57 return fc.GetUndefined();
58 };
59
BloomConfiguration()60 BloomConfiguration::BloomConfiguration() {}
61
Detach()62 void BloomConfiguration::Detach()
63 {
64 if (bloom_ || postproc_) {
65 SCENE_NS::IBloom::WeakPtr tmpb = bloom_;
66 SCENE_NS::IPostProcess::WeakPtr tmpp = postproc_;
67 if (bloom_) {
68 bloom_.reset(); // release it.
69 //* can verify if the object actually died by trying to lock it.
70 if (!tmpb.lock()) {
71 LOG_V("bloom instance destroyed");
72 }
73 }
74 if (postproc_) {
75 postproc_.reset(); // release it.
76 if (!tmpp.lock()) {
77 LOG_V("postprocess instance destroyed");
78 }
79 }
80 }
81 }
~BloomConfiguration()82 BloomConfiguration::~BloomConfiguration()
83 {
84 if (bloom_ || postproc_) {
85 Detach();
86 }
87 }
SetFrom(NapiApi::Object obj)88 void BloomConfiguration::SetFrom(NapiApi::Object obj)
89 {
90 type_ = (Type)obj.Get<uint32_t>("type").valueOrDefault((uint32_t)Type::NORMAL);
91 quality_ = (Quality)obj.Get<uint32_t>("quality").valueOrDefault((uint32_t)Quality::NORMAL);
92 thresholdHard_ = obj.Get<float>("thresholdHard").valueOrDefault(1.0);
93 thresholdSoft_ = obj.Get<float>("thresholdSoft").valueOrDefault(2.0); // 2.0: param
94 scatter_ = obj.Get<float>("scatter").valueOrDefault(1.0);
95 scaleFactor_ = obj.Get<float>("scaleFactor").valueOrDefault(1.0);
96 amountCoefficient_ = obj.Get<float>("amountCoefficient").valueOrDefault(0.25f);
97 }
SetTo(NapiApi::Object obj)98 void BloomConfiguration::SetTo(NapiApi::Object obj)
99 {
100 NapiApi::Env env(obj.GetEnv());
101 obj.Set("type", env.GetNumber((uint32_t)type_));
102 obj.Set("quality", env.GetNumber((uint32_t)quality_));
103 obj.Set("thresholdHard", env.GetNumber(thresholdHard_));
104 obj.Set("thresholdSoft", env.GetNumber(thresholdSoft_));
105 obj.Set("scatter", env.GetNumber(scatter_));
106 obj.Set("scaleFactor", env.GetNumber(scaleFactor_));
107 obj.Set("amountCoefficient", env.GetNumber(amountCoefficient_));
108 }
109
SetFrom(SCENE_NS::IBloom::Ptr bloom)110 void BloomConfiguration::SetFrom(SCENE_NS::IBloom::Ptr bloom)
111 {
112 ExecSyncTask([bloom, this]() {
113 type_ = SetType(bloom->Type()->GetValue());
114 quality_ = SetQuality(bloom->Quality()->GetValue());
115 thresholdHard_ = bloom->ThresholdHard()->GetValue();
116 thresholdSoft_ = bloom->ThresholdSoft()->GetValue();
117 scatter_ = bloom->Scatter()->GetValue();
118 scaleFactor_ = bloom->ScaleFactor()->GetValue();
119 amountCoefficient_ = bloom->AmountCoefficient()->GetValue();
120 return META_NS::IAny::Ptr {};
121 });
122 }
123
SetTo(SCENE_NS::IBloom::Ptr bloom)124 void BloomConfiguration::SetTo(SCENE_NS::IBloom::Ptr bloom)
125 {
126 ExecSyncTask([bloom, this]() {
127 bloom->Enabled()->SetValue(true);
128 bloom->Type()->SetValue(GetType(type_));
129 bloom->Quality()->SetValue(GetQuality(quality_));
130 bloom->ThresholdHard()->SetValue(thresholdHard_);
131 bloom->ThresholdSoft()->SetValue(thresholdSoft_);
132 bloom->Scatter()->SetValue(scatter_);
133 bloom->ScaleFactor()->SetValue(scaleFactor_);
134 bloom->AmountCoefficient()->SetValue(amountCoefficient_);
135 // Poke postProc so that the changes to bloom are updated.
136 return META_NS::IAny::Ptr {};
137 });
138 }
139
Unwrap(NapiApi::Object obj)140 BloomConfiguration* BloomConfiguration::Unwrap(NapiApi::Object obj)
141 {
142 BloomConfiguration* settings = nullptr;
143 napi_unwrap(obj.GetEnv(), obj.ToNapiValue(), (void**)&settings);
144 return settings;
145 }
146
Dispose(NapiApi::FunctionContext<> & ctx)147 napi_value BloomConfiguration::Dispose(NapiApi::FunctionContext<>& ctx)
148 {
149 Detach();
150 return ctx.GetUndefined();
151 }
152
Wrap(NapiApi::Object obj)153 NapiApi::StrongRef BloomConfiguration::Wrap(NapiApi::Object obj)
154 {
155 // wrap it..
156 auto DTOR = [](napi_env env, void* nativeObject, void* finalize) {
157 BloomConfiguration* ptr = static_cast<BloomConfiguration*>(nativeObject);
158 delete ptr;
159 };
160
161 napi_wrap(obj.GetEnv(), obj.ToNapiValue(), this, DTOR, nullptr, nullptr);
162
163 // clang-format off
164 napi_property_descriptor descs[] = {
165 { "type", nullptr, nullptr, Getter<&BloomConfiguration::GetType>,
166 Setter<uint32_t, &BloomConfiguration::SetType>, nullptr, napi_default_jsproperty, this },
167 { "quality", nullptr, nullptr, Getter<&BloomConfiguration::GetQuality>,
168 Setter<uint32_t, &BloomConfiguration::SetQuality>, nullptr, napi_default_jsproperty, this },
169 { "amountCoefficient", nullptr, nullptr, Getter<&BloomConfiguration::GetAmount>,
170 Setter<float, &BloomConfiguration::SetAmount>, nullptr, napi_default_jsproperty, this },
171 { "thresholdSoft", nullptr, nullptr, Getter<&BloomConfiguration::GetThresholdSoft>,
172 Setter<float, &BloomConfiguration::SetThresholdSoft>, nullptr, napi_default_jsproperty, this },
173 { "thresholdHard", nullptr, nullptr, Getter<&BloomConfiguration::GetThresholdHard>,
174 Setter<float, &BloomConfiguration::SetThresholdHard>, nullptr, napi_default_jsproperty, this },
175 { "scatter", nullptr, nullptr, Getter<&BloomConfiguration::GetScatter>,
176 Setter<float, &BloomConfiguration::SetScatter>, nullptr, napi_default_jsproperty, this },
177 { "scaleFactor", nullptr, nullptr, Getter<&BloomConfiguration::GetScaleFactor>,
178 Setter<float, &BloomConfiguration::SetScaleFactor>, nullptr, napi_default_jsproperty, this },
179 { "destroy", nullptr, Method<&BloomConfiguration::Dispose>,
180 nullptr, nullptr, nullptr, napi_default_jsproperty, this }
181 };
182 // clang-format on
183 napi_define_properties(obj.GetEnv(), obj.ToNapiValue(), BASE_NS::countof(descs), descs);
184
185 SetTo(obj);
186 return NapiApi::StrongRef(obj);
187 }
188
GetType(NapiApi::FunctionContext<> & ctx)189 napi_value BloomConfiguration::GetType(NapiApi::FunctionContext<>& ctx)
190 {
191 SCENE_NS::BloomType type = GetType(type_);
192 if (bloom_) {
193 type = bloom_->Type()->GetValue();
194 }
195 uint32_t tp = (uint32_t)SetType(type);
196 return ctx.GetNumber(tp);
197 }
GetQuality(NapiApi::FunctionContext<> & ctx)198 napi_value BloomConfiguration::GetQuality(NapiApi::FunctionContext<>& ctx)
199 {
200 SCENE_NS::EffectQualityType type = GetQuality(quality_);
201 if (bloom_) {
202 type = bloom_->Quality()->GetValue();
203 }
204 uint32_t tp = (uint32_t)SetQuality(type);
205 return ctx.GetNumber(tp);
206 }
207
GetScatter(NapiApi::FunctionContext<> & ctx)208 napi_value BloomConfiguration::GetScatter(NapiApi::FunctionContext<>& ctx)
209 {
210 float amount = scatter_;
211 if (bloom_) {
212 ExecSyncTask([bl = bloom_, &amount]() {
213 amount = bl->Scatter()->GetValue();
214 return META_NS::IAny::Ptr {};
215 });
216 }
217 return ctx.GetNumber(amount);
218 }
219
GetScaleFactor(NapiApi::FunctionContext<> & ctx)220 napi_value BloomConfiguration::GetScaleFactor(NapiApi::FunctionContext<>& ctx)
221 {
222 float amount = scaleFactor_;
223 if (bloom_) {
224 ExecSyncTask([bl = bloom_, &amount]() {
225 amount = bl->ScaleFactor()->GetValue();
226 return META_NS::IAny::Ptr {};
227 });
228 }
229 return ctx.GetNumber(amount);
230 }
231
GetThresholdHard(NapiApi::FunctionContext<> & ctx)232 napi_value BloomConfiguration::GetThresholdHard(NapiApi::FunctionContext<>& ctx)
233 {
234 float amount = thresholdHard_;
235 if (bloom_) {
236 amount = bloom_->ThresholdHard()->GetValue();
237 }
238 return ctx.GetNumber(amount);
239 }
240
GetThresholdSoft(NapiApi::FunctionContext<> & ctx)241 napi_value BloomConfiguration::GetThresholdSoft(NapiApi::FunctionContext<>& ctx)
242 {
243 float amount = thresholdSoft_;
244 if (bloom_) {
245 amount = bloom_->ThresholdSoft()->GetValue();
246 }
247 return ctx.GetNumber(amount);
248 }
249
GetAmount(NapiApi::FunctionContext<> & ctx)250 napi_value BloomConfiguration::GetAmount(NapiApi::FunctionContext<>& ctx)
251 {
252 float amount = amountCoefficient_;
253 if (bloom_) {
254 amount = bloom_->AmountCoefficient()->GetValue();
255 }
256 return ctx.GetNumber(amount);
257 }
SetType(NapiApi::FunctionContext<uint32_t> & ctx)258 void BloomConfiguration::SetType(NapiApi::FunctionContext<uint32_t>& ctx)
259 {
260 type_ = (BloomConfiguration::Type)ctx.Arg<0>().valueOrDefault();
261 if (bloom_) {
262 bloom_->Type()->SetValue(GetType(type_));
263 }
264 }
SetQuality(NapiApi::FunctionContext<uint32_t> & ctx)265 void BloomConfiguration::SetQuality(NapiApi::FunctionContext<uint32_t>& ctx)
266 {
267 quality_ = (BloomConfiguration::Quality)ctx.Arg<0>().valueOrDefault();
268 if (bloom_) {
269 bloom_->Quality()->SetValue(GetQuality(quality_));
270 }
271 }
SetThresholdHard(NapiApi::FunctionContext<float> & ctx)272 void BloomConfiguration::SetThresholdHard(NapiApi::FunctionContext<float>& ctx)
273 {
274 thresholdHard_ = ctx.Arg<0>();
275 if (bloom_) {
276 bloom_->ThresholdHard()->SetValue(thresholdHard_);
277 }
278 }
SetScatter(NapiApi::FunctionContext<float> & ctx)279 void BloomConfiguration::SetScatter(NapiApi::FunctionContext<float>& ctx)
280 {
281 scatter_ = ctx.Arg<0>();
282 if (bloom_) {
283 bloom_->Scatter()->SetValue(scatter_);
284 }
285 }
SetScaleFactor(NapiApi::FunctionContext<float> & ctx)286 void BloomConfiguration::SetScaleFactor(NapiApi::FunctionContext<float>& ctx)
287 {
288 scaleFactor_ = ctx.Arg<0>();
289 if (bloom_) {
290 bloom_->ScaleFactor()->SetValue(scaleFactor_);
291 }
292 }
SetThresholdSoft(NapiApi::FunctionContext<float> & ctx)293 void BloomConfiguration::SetThresholdSoft(NapiApi::FunctionContext<float>& ctx)
294 {
295 thresholdSoft_ = ctx.Arg<0>();
296 if (bloom_) {
297 bloom_->ThresholdSoft()->SetValue(thresholdSoft_);
298 }
299 }
SetAmount(NapiApi::FunctionContext<float> & ctx)300 void BloomConfiguration::SetAmount(NapiApi::FunctionContext<float>& ctx)
301 {
302 amountCoefficient_ = ctx.Arg<0>();
303 if (bloom_) {
304 bloom_->AmountCoefficient()->SetValue(amountCoefficient_);
305 }
306 }
GetPostProc()307 SCENE_NS::IPostProcess::Ptr BloomConfiguration::GetPostProc()
308 {
309 return postproc_;
310 }
311
SetPostProc(SCENE_NS::IPostProcess::Ptr postproc)312 void BloomConfiguration::SetPostProc(SCENE_NS::IPostProcess::Ptr postproc)
313 {
314 if (!postproc) {
315 Detach();
316 return;
317 }
318 if (postproc_ && (postproc != postproc_)) {
319 LOG_F("Invalid state. Can't change the post process of a bloom wrapper if it already has one");
320 return;
321 }
322
323 if (!postproc_) {
324 postproc_ = postproc;
325 bloom_ = postproc_->Bloom()->GetValue();
326 return;
327 }
328
329 bloom_ = postproc_->Bloom()->GetValue();
330 if (bloom_) {
331 postproc_ = postproc;
332 SetTo(bloom_);
333 } else {
334 postproc_ = nullptr;
335 }
336 }
337
GetQuality(BloomConfiguration::Quality bloomQualityType)338 SCENE_NS::EffectQualityType BloomConfiguration::GetQuality(BloomConfiguration::Quality bloomQualityType)
339 {
340 switch (bloomQualityType) {
341 case Quality::LOW:
342 return SCENE_NS::EffectQualityType::LOW;
343 case Quality::HIGH:
344 return SCENE_NS::EffectQualityType::HIGH;
345 case Quality::NORMAL:
346 default:
347 return SCENE_NS::EffectQualityType::NORMAL;
348 };
349 return SCENE_NS::EffectQualityType::NORMAL;
350 }
SetQuality(SCENE_NS::EffectQualityType bloomQualityType)351 BloomConfiguration::Quality BloomConfiguration::SetQuality(SCENE_NS::EffectQualityType bloomQualityType)
352 {
353 switch (bloomQualityType) {
354 case SCENE_NS::EffectQualityType::LOW:
355 return BloomConfiguration::Quality::LOW;
356 case SCENE_NS::EffectQualityType::HIGH:
357 return BloomConfiguration::Quality::HIGH;
358 case SCENE_NS::EffectQualityType::NORMAL:
359 default:
360 return BloomConfiguration::Quality::NORMAL;
361 };
362 return BloomConfiguration::Quality::NORMAL;
363 }
364
GetType(BloomConfiguration::Type bloomType)365 SCENE_NS::BloomType BloomConfiguration::GetType(BloomConfiguration::Type bloomType)
366 {
367 switch (bloomType) {
368 case Type::HORIZONTAL:
369 return SCENE_NS::BloomType::HORIZONTAL;
370 case Type::VERTICAL:
371 return SCENE_NS::BloomType::VERTICAL;
372 case Type::BILATERAL:
373 return SCENE_NS::BloomType::BILATERAL;
374 case Type::NORMAL:
375 default:
376 return SCENE_NS::BloomType::NORMAL;
377 };
378 return SCENE_NS::BloomType::NORMAL;
379 }
SetType(SCENE_NS::BloomType bloomTypeIn)380 BloomConfiguration::Type BloomConfiguration::SetType(SCENE_NS::BloomType bloomTypeIn)
381 {
382 switch (bloomTypeIn) {
383 case SCENE_NS::BloomType::HORIZONTAL:
384 return BloomConfiguration::Type::HORIZONTAL;
385 case SCENE_NS::BloomType::VERTICAL:
386 return BloomConfiguration::Type::VERTICAL;
387 case SCENE_NS::BloomType::BILATERAL:
388 return BloomConfiguration::Type::NORMAL;
389 case SCENE_NS::BloomType::NORMAL:
390 default:
391 return BloomConfiguration::Type::NORMAL;
392 };
393 return BloomConfiguration::Type::NORMAL;
394 }
395