• 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 #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         if (postproc_) {
136             postproc_->Bloom()->SetValue(bloom);
137         }
138         return META_NS::IAny::Ptr {};
139     });
140 }
141 
Unwrap(NapiApi::Object obj)142 BloomConfiguration* BloomConfiguration::Unwrap(NapiApi::Object obj)
143 {
144     BloomConfiguration* settings = nullptr;
145     napi_unwrap(obj.GetEnv(), obj.ToNapiValue(), (void**)&settings);
146     return settings;
147 }
148 
Dispose(NapiApi::FunctionContext<> & ctx)149 napi_value BloomConfiguration::Dispose(NapiApi::FunctionContext<>& ctx)
150 {
151     Detach();
152     return ctx.GetUndefined();
153 }
154 
Wrap(NapiApi::Object obj)155 NapiApi::StrongRef BloomConfiguration::Wrap(NapiApi::Object obj)
156 {
157     //  wrap it..
158     auto DTOR = [](napi_env env, void* nativeObject, void* finalize) {
159         BloomConfiguration* ptr = static_cast<BloomConfiguration*>(nativeObject);
160         delete ptr;
161     };
162 
163     napi_wrap(obj.GetEnv(), obj.ToNapiValue(), this, DTOR, nullptr, nullptr);
164 
165     // clang-format off
166     napi_property_descriptor descs[] = {
167         { "type", nullptr, nullptr, Getter<&BloomConfiguration::GetType>,
168             Setter<uint32_t, &BloomConfiguration::SetType>, nullptr, napi_default_jsproperty, this },
169         { "quality", nullptr, nullptr, Getter<&BloomConfiguration::GetQuality>,
170             Setter<uint32_t, &BloomConfiguration::SetQuality>, nullptr, napi_default_jsproperty, this },
171         { "amountCoefficient", nullptr, nullptr, Getter<&BloomConfiguration::GetAmount>,
172             Setter<float, &BloomConfiguration::SetAmount>, nullptr, napi_default_jsproperty, this },
173         { "thresholdSoft", nullptr, nullptr, Getter<&BloomConfiguration::GetThresholdSoft>,
174             Setter<float, &BloomConfiguration::SetThresholdSoft>, nullptr, napi_default_jsproperty, this },
175         { "thresholdHard", nullptr, nullptr, Getter<&BloomConfiguration::GetThresholdHard>,
176             Setter<float, &BloomConfiguration::SetThresholdHard>, nullptr, napi_default_jsproperty, this },
177         { "scatter", nullptr, nullptr, Getter<&BloomConfiguration::GetScatter>,
178             Setter<float, &BloomConfiguration::SetScatter>, nullptr, napi_default_jsproperty, this },
179         { "scaleFactor", nullptr, nullptr, Getter<&BloomConfiguration::GetScaleFactor>,
180             Setter<float, &BloomConfiguration::SetScaleFactor>, nullptr, napi_default_jsproperty, this },
181         { "destroy", nullptr, Method<&BloomConfiguration::Dispose>,
182             nullptr, nullptr, nullptr, napi_default_jsproperty, this }
183     };
184     // clang-format on
185     napi_define_properties(obj.GetEnv(), obj.ToNapiValue(), BASE_NS::countof(descs), descs);
186 
187     SetTo(obj);
188     return NapiApi::StrongRef(obj);
189 }
190 
GetType(NapiApi::FunctionContext<> & ctx)191 napi_value BloomConfiguration::GetType(NapiApi::FunctionContext<>& ctx)
192 {
193     SCENE_NS::BloomType type = GetType(type_);
194     if (bloom_) {
195         type = bloom_->Type()->GetValue();
196     }
197     uint32_t tp = (uint32_t)SetType(type);
198     return ctx.GetNumber(tp);
199 }
GetQuality(NapiApi::FunctionContext<> & ctx)200 napi_value BloomConfiguration::GetQuality(NapiApi::FunctionContext<>& ctx)
201 {
202     SCENE_NS::EffectQualityType type = GetQuality(quality_);
203     if (bloom_) {
204         type = bloom_->Quality()->GetValue();
205     }
206     uint32_t tp = (uint32_t)SetQuality(type);
207     return ctx.GetNumber(tp);
208 }
209 
GetScatter(NapiApi::FunctionContext<> & ctx)210 napi_value BloomConfiguration::GetScatter(NapiApi::FunctionContext<>& ctx)
211 {
212     float amount = scatter_;
213     if (bloom_) {
214         ExecSyncTask([bl = bloom_, &amount]() {
215             amount = bl->Scatter()->GetValue();
216             return META_NS::IAny::Ptr {};
217         });
218     }
219     return ctx.GetNumber(amount);
220 }
221 
GetScaleFactor(NapiApi::FunctionContext<> & ctx)222 napi_value BloomConfiguration::GetScaleFactor(NapiApi::FunctionContext<>& ctx)
223 {
224     float amount = scaleFactor_;
225     if (bloom_) {
226         ExecSyncTask([bl = bloom_, &amount]() {
227             amount = bl->ScaleFactor()->GetValue();
228             return META_NS::IAny::Ptr {};
229         });
230     }
231     return ctx.GetNumber(amount);
232 }
233 
GetThresholdHard(NapiApi::FunctionContext<> & ctx)234 napi_value BloomConfiguration::GetThresholdHard(NapiApi::FunctionContext<>& ctx)
235 {
236     float amount = thresholdHard_;
237     if (bloom_) {
238         amount = bloom_->ThresholdHard()->GetValue();
239     }
240     return ctx.GetNumber(amount);
241 }
242 
GetThresholdSoft(NapiApi::FunctionContext<> & ctx)243 napi_value BloomConfiguration::GetThresholdSoft(NapiApi::FunctionContext<>& ctx)
244 {
245     float amount = thresholdSoft_;
246     if (bloom_) {
247         amount = bloom_->ThresholdSoft()->GetValue();
248     }
249     return ctx.GetNumber(amount);
250 }
251 
GetAmount(NapiApi::FunctionContext<> & ctx)252 napi_value BloomConfiguration::GetAmount(NapiApi::FunctionContext<>& ctx)
253 {
254     float amount = amountCoefficient_;
255     if (bloom_) {
256         amount = bloom_->AmountCoefficient()->GetValue();
257     }
258     return ctx.GetNumber(amount);
259 }
SetType(NapiApi::FunctionContext<uint32_t> & ctx)260 void BloomConfiguration::SetType(NapiApi::FunctionContext<uint32_t>& ctx)
261 {
262     type_ = (BloomConfiguration::Type)ctx.Arg<0>().valueOrDefault();
263     if (bloom_) {
264         bloom_->Type()->SetValue(GetType(type_));
265         if (postproc_) {
266             postproc_->Bloom()->SetValue(bloom_);
267         }
268     }
269 }
SetQuality(NapiApi::FunctionContext<uint32_t> & ctx)270 void BloomConfiguration::SetQuality(NapiApi::FunctionContext<uint32_t>& ctx)
271 {
272     quality_ = (BloomConfiguration::Quality)ctx.Arg<0>().valueOrDefault();
273     if (bloom_) {
274         bloom_->Quality()->SetValue(GetQuality(quality_));
275         if (postproc_) {
276             postproc_->Bloom()->SetValue(bloom_);
277         }
278     }
279 }
SetThresholdHard(NapiApi::FunctionContext<float> & ctx)280 void BloomConfiguration::SetThresholdHard(NapiApi::FunctionContext<float>& ctx)
281 {
282     thresholdHard_ = ctx.Arg<0>();
283     if (bloom_) {
284         bloom_->ThresholdHard()->SetValue(thresholdHard_);
285         if (postproc_) {
286             postproc_->Bloom()->SetValue(bloom_);
287         }
288     }
289 }
SetScatter(NapiApi::FunctionContext<float> & ctx)290 void BloomConfiguration::SetScatter(NapiApi::FunctionContext<float>& ctx)
291 {
292     scatter_= ctx.Arg<0>();
293     if (bloom_) {
294         bloom_->Scatter()->SetValue(scatter_);
295         if (postproc_) {
296             postproc_->Bloom()->SetValue(bloom_);
297         }
298     }
299 }
SetScaleFactor(NapiApi::FunctionContext<float> & ctx)300 void BloomConfiguration::SetScaleFactor(NapiApi::FunctionContext<float>& ctx)
301 {
302     scaleFactor_ = ctx.Arg<0>();
303     scaleFactor_ = (scaleFactor_ < 1e-6) ? 1e-6 : scaleFactor_;
304     if (bloom_) {
305         bloom_->ScaleFactor()->SetValue(scaleFactor_);
306         if (postproc_) {
307             postproc_->Bloom()->SetValue(bloom_);
308         }
309     }
310 }
SetThresholdSoft(NapiApi::FunctionContext<float> & ctx)311 void BloomConfiguration::SetThresholdSoft(NapiApi::FunctionContext<float>& ctx)
312 {
313     thresholdSoft_ = ctx.Arg<0>();
314     if (bloom_) {
315         bloom_->ThresholdSoft()->SetValue(thresholdSoft_);
316         if (postproc_) {
317             postproc_->Bloom()->SetValue(bloom_);
318         }
319     }
320 }
SetAmount(NapiApi::FunctionContext<float> & ctx)321 void BloomConfiguration::SetAmount(NapiApi::FunctionContext<float>& ctx)
322 {
323     amountCoefficient_ = ctx.Arg<0>();
324     if (bloom_) {
325         bloom_->AmountCoefficient()->SetValue(amountCoefficient_);
326         if (postproc_) {
327             postproc_->Bloom()->SetValue(bloom_);
328         }
329     }
330 }
GetPostProc()331 SCENE_NS::IPostProcess::Ptr BloomConfiguration::GetPostProc()
332 {
333     return postproc_;
334 }
335 
SetPostProc(SCENE_NS::IPostProcess::Ptr postproc)336 void BloomConfiguration::SetPostProc(SCENE_NS::IPostProcess::Ptr postproc)
337 {
338     if (!postproc) {
339         // detaching.
340         Detach();
341         return;
342     }
343     if ((postproc_) && (postproc != postproc_)) {
344         LOG_F("Invalid state");
345         return;
346     }
347     postproc_ = postproc;
348     auto bloom = postproc_->Bloom()->GetValue();
349     if ((bloom_) && (bloom != bloom_)) {
350         LOG_F("Invalid state");
351         bloom = nullptr;
352     } else {
353         if (!bloom) {
354             bloom = META_NS::GetObjectRegistry().Create<SCENE_NS::IBloom>(SCENE_NS::ClassId::Bloom);
355         }
356         bloom_ = bloom;
357     }
358     if (!bloom_) {
359         postproc_ = nullptr;
360     } else {
361         SetTo(bloom_);
362     }
363 }
364 
GetQuality(BloomConfiguration::Quality bloomQualityType)365 SCENE_NS::EffectQualityType BloomConfiguration::GetQuality(BloomConfiguration::Quality bloomQualityType)
366 {
367     switch (bloomQualityType) {
368         case Quality::LOW:
369             return SCENE_NS::EffectQualityType::LOW;
370         case Quality::HIGH:
371             return SCENE_NS::EffectQualityType::HIGH;
372         case Quality::NORMAL:
373         default:
374             return SCENE_NS::EffectQualityType::NORMAL;
375     };
376     return SCENE_NS::EffectQualityType::NORMAL;
377 }
SetQuality(SCENE_NS::EffectQualityType bloomQualityType)378 BloomConfiguration::Quality BloomConfiguration::SetQuality(SCENE_NS::EffectQualityType bloomQualityType)
379 {
380     switch (bloomQualityType) {
381         case SCENE_NS::EffectQualityType::LOW:
382             return BloomConfiguration::Quality::LOW;
383         case SCENE_NS::EffectQualityType::HIGH:
384             return BloomConfiguration::Quality::HIGH;
385         case SCENE_NS::EffectQualityType::NORMAL:
386         default:
387             return BloomConfiguration::Quality::NORMAL;
388     };
389     return BloomConfiguration::Quality::NORMAL;
390 }
391 
GetType(BloomConfiguration::Type bloomType)392 SCENE_NS::BloomType BloomConfiguration::GetType(BloomConfiguration::Type bloomType)
393 {
394     switch (bloomType) {
395         case Type::HORIZONTAL:
396             return SCENE_NS::BloomType::HORIZONTAL;
397         case Type::VERTICAL:
398             return SCENE_NS::BloomType::VERTICAL;
399         case Type::BILATERAL:
400             return SCENE_NS::BloomType::BILATERAL;
401         case Type::NORMAL:
402         default:
403             return SCENE_NS::BloomType::NORMAL;
404     };
405     return SCENE_NS::BloomType::NORMAL;
406 }
SetType(SCENE_NS::BloomType bloomTypeIn)407 BloomConfiguration::Type BloomConfiguration::SetType(SCENE_NS::BloomType bloomTypeIn)
408 {
409     switch (bloomTypeIn) {
410         case SCENE_NS::BloomType::HORIZONTAL:
411             return BloomConfiguration::Type::HORIZONTAL;
412         case SCENE_NS::BloomType::VERTICAL:
413             return BloomConfiguration::Type::VERTICAL;
414         case SCENE_NS::BloomType::BILATERAL:
415             return BloomConfiguration::Type::NORMAL;
416         case SCENE_NS::BloomType::NORMAL:
417         default:
418             return BloomConfiguration::Type::NORMAL;
419     };
420     return BloomConfiguration::Type::NORMAL;
421 }
422