• 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 "SamplerJS.h"
17 
18 #include <meta/api/make_callback.h>
19 #include <meta/api/util.h>
20 #include <meta/interface/intf_task_queue.h>
21 #include <meta/interface/intf_task_queue_registry.h>
22 #include <meta/interface/property/property_events.h>
23 #include <scene/interface/intf_node.h>
24 #include <scene/interface/intf_postprocess.h>
25 #include <scene/interface/intf_scene.h>
26 #include <scene/interface/intf_texture.h>
27 #include <render/intf_render_context.h>
28 
29 using IntfPtr = BASE_NS::shared_ptr<CORE_NS::IInterface>;
30 using IntfWeakPtr = BASE_NS::weak_ptr<CORE_NS::IInterface>;
31 
RegisterEnums(NapiApi::Object exports)32 void SamplerJS::RegisterEnums(NapiApi::Object exports)
33 {
34     napi_value v;
35     auto env = exports.GetEnv();
36     NapiApi::Object SceneFilter(env);
37     NapiApi::Object SceneSamplerAddressMode(env);
38 
39     using SCENE_NS::SamplerFilter;
40     using SCENE_NS::SamplerAddressMode;
41 
42 #define DECL_ENUM(enu, type, value)                                                 \
43     {                                                                               \
44         napi_create_uint32(enu.GetEnv(), static_cast<uint32_t>(type::value), &v);   \
45         enu.Set(#value, v);                                                         \
46     }
47     DECL_ENUM(SceneFilter, SamplerFilter, NEAREST);
48     DECL_ENUM(SceneFilter, SamplerFilter, LINEAR);
49 
50     DECL_ENUM(SceneSamplerAddressMode, SamplerAddressMode, REPEAT);
51     DECL_ENUM(SceneSamplerAddressMode, SamplerAddressMode, MIRRORED_REPEAT);
52     DECL_ENUM(SceneSamplerAddressMode, SamplerAddressMode, CLAMP_TO_EDGE);
53     // Do not declare CLAMP_TO_BORDER or MIRROR_CLAMP_TO_EDGE as they are not part of SamplerAddressMode in
54     // sceneResources.d.ts
55 #undef DECL_ENUM
56     exports.Set("SamplerFilter", SceneFilter);
57     exports.Set("SamplerAddressMode", SceneSamplerAddressMode);
58 }
59 
60 constexpr auto DEFAULT_FILTER = SCENE_NS::SamplerFilter::NEAREST;
61 constexpr auto DEFAULT_ADDESS_MODE = SCENE_NS::SamplerAddressMode::REPEAT;
62 
ConvertToFilter(uint32_t value)63 SCENE_NS::SamplerFilter SamplerJS::ConvertToFilter(uint32_t value)
64 {
65     static constexpr auto MAX_FILTER = static_cast<uint32_t>(SCENE_NS::SamplerFilter::LINEAR);
66     if (value <= MAX_FILTER) {
67         return static_cast<SCENE_NS::SamplerFilter>(value);
68     }
69     return DEFAULT_FILTER;
70 }
71 
ConvertFromFilter(SCENE_NS::SamplerFilter value)72 uint32_t SamplerJS::ConvertFromFilter(SCENE_NS::SamplerFilter value)
73 {
74     return static_cast<uint32_t>(value);
75 }
76 
ConvertToAddressMode(uint32_t value)77 SCENE_NS::SamplerAddressMode SamplerJS::ConvertToAddressMode(uint32_t value)
78 {
79     static constexpr auto MAX_ADDRESS_MDOE = static_cast<uint32_t>(SCENE_NS::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE);
80     if (value <= MAX_ADDRESS_MDOE) {
81         return static_cast<SCENE_NS::SamplerAddressMode>(value);
82     }
83     return DEFAULT_ADDESS_MODE;
84 }
85 
ConvertFromAddressMode(SCENE_NS::SamplerAddressMode value)86 uint32_t SamplerJS::ConvertFromAddressMode(SCENE_NS::SamplerAddressMode value)
87 {
88     return static_cast<uint32_t>(value);
89 }
90 
Init(napi_env env,napi_value exports)91 void SamplerJS::Init(napi_env env, napi_value exports)
92 {
93     using namespace NapiApi;
94 
95     BASE_NS::vector<napi_property_descriptor> node_props;
96 
97     node_props.emplace_back(
98         GetSetProperty<uint32_t, SamplerJS, &SamplerJS::GetMagFilter, &SamplerJS::SetMagFilter>("magFilter"));
99     node_props.emplace_back(
100         GetSetProperty<uint32_t, SamplerJS, &SamplerJS::GetMinFilter, &SamplerJS::SetMinFilter>("minFilter"));
101     node_props.emplace_back(
102         GetSetProperty<uint32_t, SamplerJS, &SamplerJS::GetMipMapMode, &SamplerJS::SetMipMapMode>("mipMapMode"));
103     node_props.emplace_back(
104         GetSetProperty<uint32_t, SamplerJS, &SamplerJS::GetAddressModeU, &SamplerJS::SetAddressModeU>("addressModeU"));
105     node_props.emplace_back(
106         GetSetProperty<uint32_t, SamplerJS, &SamplerJS::GetAddressModeV, &SamplerJS::SetAddressModeV>("addressModeV"));
107     node_props.emplace_back(
108         GetSetProperty<uint32_t, SamplerJS, &SamplerJS::GetAddressModeW, &SamplerJS::SetAddressModeW>("addressModeW"));
109 
110     node_props.push_back(MakeTROMethod<NapiApi::FunctionContext<>, SamplerJS, &SamplerJS::Dispose>("destroy"));
111 
112     napi_value func;
113     auto status = napi_define_class(env, "Sampler", NAPI_AUTO_LENGTH, BaseObject::ctor<SamplerJS>(),
114         nullptr, node_props.size(), node_props.data(), &func);
115 
116     NapiApi::MyInstanceState* mis;
117     NapiApi::MyInstanceState::GetInstance(env, reinterpret_cast<void**>(&mis));
118     if (mis) {
119         mis->StoreCtor("Sampler", func);
120     }
121 
122     NapiApi::Object exp1(env, exports);
123     napi_value eType1, v1;
124     napi_create_object(env, &eType1);
125 }
126 
Dispose(NapiApi::FunctionContext<> & ctx)127 napi_value SamplerJS::Dispose(NapiApi::FunctionContext<>& ctx)
128 {
129     LOG_V("SamplerJS::Dispose");
130     DisposeNative(nullptr);
131     return {};
132 }
DisposeNative(void *)133 void SamplerJS::DisposeNative(void*)
134 {
135     if (!disposed_) {
136         disposed_ = true;
137         LOG_V("SamplerJS::DisposeNative");
138         UnsetNativeObject();
139     }
140 }
Finalize(napi_env env)141 void SamplerJS::Finalize(napi_env env)
142 {
143     DisposeNative(nullptr);
144     BaseObject::Finalize(env);
145 }
GetInstanceImpl(uint32_t id)146 void* SamplerJS::GetInstanceImpl(uint32_t id)
147 {
148     if (id == SamplerJS::ID)
149         return this;
150     return nullptr;
151 }
152 
CreateRawJsObject(napi_env env)153 napi_value SamplerJS::CreateRawJsObject(napi_env env)
154 {
155     // Ei ky tmmnen. Sit ku tn assignaa kohdilleen, ni joo se tekee jotain vissiin.
156     // mutta tn kautta ei voi en muuttaa mitn. Tytyy tehd sama bind ja unbind ku postproc-kamoissa.
157     auto sampler = NapiApi::Object { env };
158     for (auto&& propName : { "magFilter", "minFilter", "mipMapMode" }) {
159         sampler.Set(propName, NapiApi::Value<uint32_t>(env, static_cast<uint32_t>(DEFAULT_FILTER)));
160     }
161     for (auto&& propName : { "addressModeU", "addressModeV", "addressModeW" }) {
162         sampler.Set(propName, NapiApi::Value<uint32_t>(env, static_cast<uint32_t>(DEFAULT_ADDESS_MODE)));
163     }
164 
165     // According to the API, Sampler isn't a SceneResource, so it shouldn't have destroy (or other props).
166     // Add it anyway, to remain compatible with SamplerJS.
167     napi_value destroyFunc;
168     // If nullptr isn't ok for cb, use this no-op: [](napi_env, napi_callback_info) { return napi_value {}; }
169     napi_create_function(
170         env, "destroy", NAPI_AUTO_LENGTH, [](napi_env, napi_callback_info) { return napi_value {}; }, nullptr,
171         &destroyFunc);
172     sampler.Set("destroy", destroyFunc);
173     return sampler.ToNapiValue();
174 }
175 
SamplerJS(napi_env e,napi_callback_info i)176 SamplerJS::SamplerJS(napi_env e, napi_callback_info i) : BaseObject(e, i)
177 {
178     LOG_V("Sampler ++");
179     if (!GetSampler()) {
180         LOG_E("Cannot finish creating a texture sampler: Native sampler object missing");
181         assert(false);
182     }
183 }
184 
~SamplerJS()185 SamplerJS::~SamplerJS()
186 {
187     LOG_V("Sampler --");
188     DisposeNative(nullptr);
189 }
190 
GetSampler() const191 SCENE_NS::ISampler::Ptr SamplerJS::GetSampler() const
192 {
193     return GetNativeObject<SCENE_NS::ISampler>();
194 }
195 
GetMagFilter(NapiApi::FunctionContext<> & ctx)196 napi_value SamplerJS::GetMagFilter(NapiApi::FunctionContext<>& ctx)
197 {
198     auto sampler = GetSampler();
199     auto filter = sampler ? META_NS::GetValue(sampler->MagFilter()) : DEFAULT_FILTER;
200     return ctx.GetNumber(ConvertFromFilter(filter));
201 }
202 
SetMagFilter(NapiApi::FunctionContext<uint32_t> & ctx)203 void SamplerJS::SetMagFilter(NapiApi::FunctionContext<uint32_t>& ctx)
204 {
205     if (auto sampler = GetSampler()) {
206         auto value = ConvertToFilter(ctx.Arg<0>());
207         META_NS::SetValue(sampler->MagFilter(), value);
208     }
209 }
210 
GetMinFilter(NapiApi::FunctionContext<> & ctx)211 napi_value SamplerJS::GetMinFilter(NapiApi::FunctionContext<>& ctx)
212 {
213     auto sampler = GetSampler();
214     auto filter = sampler ? META_NS::GetValue(sampler->MinFilter()) : DEFAULT_FILTER;
215     return ctx.GetNumber(ConvertFromFilter(filter));
216 }
217 
SetMinFilter(NapiApi::FunctionContext<uint32_t> & ctx)218 void SamplerJS::SetMinFilter(NapiApi::FunctionContext<uint32_t>& ctx)
219 {
220     if (auto sampler = GetSampler()) {
221         auto value = ConvertToFilter(ctx.Arg<0>());
222         META_NS::SetValue(sampler->MinFilter(), value);
223     }
224 }
225 
GetMipMapMode(NapiApi::FunctionContext<> & ctx)226 napi_value SamplerJS::GetMipMapMode(NapiApi::FunctionContext<>& ctx)
227 {
228     auto sampler = GetSampler();
229     auto filter = sampler ? META_NS::GetValue(sampler->MipMapMode()) : DEFAULT_FILTER;
230     return ctx.GetNumber(ConvertFromFilter(filter));
231 }
232 
SetMipMapMode(NapiApi::FunctionContext<uint32_t> & ctx)233 void SamplerJS::SetMipMapMode(NapiApi::FunctionContext<uint32_t>& ctx)
234 {
235     if (auto sampler = GetSampler()) {
236         auto value = ConvertToFilter(ctx.Arg<0>());
237         META_NS::SetValue(sampler->MipMapMode(), value);
238     }
239 }
240 
GetAddressModeU(NapiApi::FunctionContext<> & ctx)241 napi_value SamplerJS::GetAddressModeU(NapiApi::FunctionContext<>& ctx)
242 {
243     auto sampler = GetSampler();
244     auto mode = sampler ? META_NS::GetValue(sampler->AddressModeU()) : DEFAULT_ADDESS_MODE;
245     return ctx.GetNumber(ConvertFromAddressMode(mode));
246 }
247 
SetAddressModeU(NapiApi::FunctionContext<uint32_t> & ctx)248 void SamplerJS::SetAddressModeU(NapiApi::FunctionContext<uint32_t>& ctx)
249 {
250     if (auto sampler = GetSampler()) {
251         auto value = ConvertToAddressMode(ctx.Arg<0>());
252         META_NS::SetValue(sampler->AddressModeU(), value);
253     }
254 }
255 
GetAddressModeV(NapiApi::FunctionContext<> & ctx)256 napi_value SamplerJS::GetAddressModeV(NapiApi::FunctionContext<>& ctx)
257 {
258     auto sampler = GetSampler();
259     auto mode = sampler ? META_NS::GetValue(sampler->AddressModeV()) : DEFAULT_ADDESS_MODE;
260     return ctx.GetNumber(ConvertFromAddressMode(mode));
261 }
262 
SetAddressModeV(NapiApi::FunctionContext<uint32_t> & ctx)263 void SamplerJS::SetAddressModeV(NapiApi::FunctionContext<uint32_t>& ctx)
264 {
265     if (auto sampler = GetSampler()) {
266         auto value = ConvertToAddressMode(ctx.Arg<0>());
267         META_NS::SetValue(sampler->AddressModeV(), value);
268     }
269 }
270 
GetAddressModeW(NapiApi::FunctionContext<> & ctx)271 napi_value SamplerJS::GetAddressModeW(NapiApi::FunctionContext<>& ctx)
272 {
273     auto sampler = GetSampler();
274     auto mode = sampler ? META_NS::GetValue(sampler->AddressModeW()) : DEFAULT_ADDESS_MODE;
275     return ctx.GetNumber(ConvertFromAddressMode(mode));
276 }
277 
SetAddressModeW(NapiApi::FunctionContext<uint32_t> & ctx)278 void SamplerJS::SetAddressModeW(NapiApi::FunctionContext<uint32_t>& ctx)
279 {
280     if (auto sampler = GetSampler()) {
281         auto value = ConvertToAddressMode(ctx.Arg<0>());
282         META_NS::SetValue(sampler->AddressModeW(), value);
283     }
284 }
285