1 /*
2  * Copyright (c) 2021-2023 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 "context/webgl_rendering_context_base.h"
17 
18 #include "context/webgl2_rendering_context_base.h"
19 #include "context/webgl_context_attributes.h"
20 #include "context/webgl_rendering_context.h"
21 #include "context/webgl_rendering_context_base_impl.h"
22 #include "context/webgl_rendering_context_basic_base.h"
23 #include "napi/n_class.h"
24 #include "napi/n_func_arg.h"
25 #include "util/egl_manager.h"
26 #include "util/log.h"
27 #include "util/util.h"
28 #include "webgl/webgl_active_info.h"
29 #include "webgl/webgl_arg.h"
30 #include "webgl/webgl_buffer.h"
31 #include "webgl/webgl_framebuffer.h"
32 #include "webgl/webgl_program.h"
33 #include "webgl/webgl_renderbuffer.h"
34 #include "webgl/webgl_shader.h"
35 #include "webgl/webgl_shader_precision_format.h"
36 #include "webgl/webgl_texture.h"
37 #include "webgl/webgl_uniform_location.h"
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 namespace OHOS {
43 namespace Rosen {
44 using namespace std;
GetWebGLRenderingContextBase(napi_env env,napi_value thisVar)45 static WebGLRenderingContext* GetWebGLRenderingContextBase(napi_env env, napi_value thisVar)
46 {
47     return static_cast<WebGLRenderingContext*>(Util::GetContextObject(env, thisVar));
48 }
49 
IsHighWebGL(napi_env env,napi_value thisVar)50 static bool IsHighWebGL(napi_env env, napi_value thisVar)
51 {
52     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, thisVar);
53     if (context == nullptr) {
54         return false;
55     }
56     return context->GetWebGLRenderingContextImpl().IsHighWebGL();
57 }
58 
CheckGLenum(napi_env env,napi_value thisVar,GLenum type,const std::vector<GLenum> & glSupport,const std::vector<GLenum> & gl2Support)59 static bool CheckGLenum(napi_env env, napi_value thisVar, GLenum type, const std::vector<GLenum>& glSupport,
60     const std::vector<GLenum>& gl2Support)
61 {
62     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, thisVar);
63     if (context == nullptr) {
64         return false;
65     }
66     return context->GetWebGLRenderingContextImpl().CheckGLenum(type, glSupport, gl2Support);
67 }
68 
GetContextAttributes(napi_env env,napi_callback_info info)69 napi_value WebGLRenderingContextBase::GetContextAttributes(napi_env env, napi_callback_info info)
70 {
71     NFuncArg funcArg(env, info);
72     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
73         return NVal::CreateNull(env).val_;
74     }
75     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
76     if (context == nullptr) {
77         return NVal::CreateNull(env).val_;
78     }
79     return context->GetWebGLRenderingContextImpl().GetContextAttributes(env);
80 }
81 
IsContextLost(napi_env env,napi_callback_info info)82 napi_value WebGLRenderingContextBase::IsContextLost(napi_env env, napi_callback_info info)
83 {
84     bool res = false;
85     if (EglManager::GetInstance().GetEGLContext() == nullptr) {
86         res = true;
87     }
88     return NVal::CreateBool(env, res).val_;
89 }
90 
GetSupportedExtensions(napi_env env,napi_callback_info info)91 napi_value WebGLRenderingContextBase::GetSupportedExtensions(napi_env env, napi_callback_info info)
92 {
93     if (EglManager::GetInstance().GetEGLContext() == nullptr) {
94         return NVal::CreateNull(env).val_;
95     }
96     const char* extensions = eglQueryString(EglManager::GetInstance().GetEGLDisplay(), EGL_EXTENSIONS);
97     string str = extensions;
98     vector<string> vec {};
99     Util::SplitString(str, vec, " ");
100     napi_value result = nullptr;
101     napi_create_array_with_length(env, vec.size(), &result);
102     for (vector<string>::size_type i = 0; i != vec.size(); ++i) {
103         LOGD("WebGL %{public}s", vec[i].c_str());
104         napi_set_element(env, result, i, NVal::CreateUTF8String(env, vec[i]).val_);
105     }
106     return result;
107 }
108 
LoseContext(napi_env env,napi_callback_info info)109 napi_value LoseContext(napi_env env, napi_callback_info info)
110 {
111     return NVal::CreateNull(env).val_;
112 }
113 
GetExtension(napi_env env,napi_callback_info info)114 napi_value WebGLRenderingContextBase::GetExtension(napi_env env, napi_callback_info info)
115 {
116     NFuncArg funcArg(env, info);
117     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
118         return NVal::CreateNull(env).val_;
119     }
120     bool succ = false;
121     unique_ptr<char[]> name = nullptr;
122     uint32_t nameLen = 0;
123     tie(succ, name, nameLen) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String();
124     if (!succ) {
125         return NVal::CreateNull(env).val_;
126     }
127     LOGD("WebGL getExtension %{public}s", name.get());
128 #ifdef SUPPORT_COMPRESSED_RGB_S3TC
129     if (strcmp(name.get(), "WEBGL_compressed_texture_s3tc") == 0 ||
130         strcmp(name.get(), "MOZ_WEBGL_compressed_texture_s3tc") == 0 ||
131         strcmp(name.get(), "WEBKIT_WEBGL_compressed_texture_s3tc") == 0) {
132         NVal res = NVal::CreateObject(env);
133         res.AddProp("COMPRESSED_RGB_S3TC_DXT1_EXT", NVal::CreateInt64(env, GL_COMPRESSED_RGB_S3TC_DXT1_EXT).val_);
134         res.AddProp("COMPRESSED_RGBA_S3TC_DXT1_EXT", NVal::CreateInt64(env, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT).val_);
135         res.AddProp("COMPRESSED_RGBA_S3TC_DXT3_EXT", NVal::CreateInt64(env, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT).val_);
136         res.AddProp("COMPRESSED_RGBA_S3TC_DXT5_EXT", NVal::CreateInt64(env, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT).val_);
137         return res.val_;
138     }
139 #endif
140     if (strcmp(name.get(), "WEBGL_lose_context") == 0) { // WEBGL_lose_context
141         NVal res = NVal::CreateObject(env);
142         vector<napi_property_descriptor> props = {
143             NVal::DeclareNapiFunction("loseContext", LoseContext),
144         };
145         res.AddProp(std::move(props));
146         return res.val_;
147     }
148     return NVal::CreateNull(env).val_;
149 }
150 
ActiveTexture(napi_env env,napi_callback_info info)151 napi_value WebGLRenderingContextBase::ActiveTexture(napi_env env, napi_callback_info info)
152 {
153     NFuncArg funcArg(env, info);
154     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
155         return NVal::CreateNull(env).val_;
156     }
157     bool succ = false;
158     GLenum texture = 0;
159     tie(succ, texture) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
160     if (!succ) {
161         return NVal::CreateNull(env).val_;
162     }
163     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
164     if (context == nullptr) {
165         return NVal::CreateNull(env).val_;
166     }
167     return context->GetWebGLRenderingContextImpl().ActiveTexture(env, texture);
168 }
169 
AttachShader(napi_env env,napi_callback_info info)170 napi_value WebGLRenderingContextBase::AttachShader(napi_env env, napi_callback_info info)
171 {
172     NFuncArg funcArg(env, info);
173     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
174         return NVal::CreateNull(env).val_;
175     }
176 
177     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
178     if (context == nullptr) {
179         return NVal::CreateNull(env).val_;
180     }
181     return context->GetWebGLRenderingContextImpl().AttachShader(
182         env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]);
183 }
184 
BindAttribLocation(napi_env env,napi_callback_info info)185 napi_value WebGLRenderingContextBase::BindAttribLocation(napi_env env, napi_callback_info info)
186 {
187     NFuncArg funcArg(env, info);
188     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
189         return NVal::CreateNull(env).val_;
190     }
191     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
192     if (context == nullptr) {
193         return NVal::CreateNull(env).val_;
194     }
195 
196     bool succ = false;
197     int64_t index = 0;
198     tie(succ, index) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt64();
199     if (!succ || index < 0) {
200         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_VALUE);
201         return NVal::CreateNull(env).val_;
202     }
203     unique_ptr<char[]> name;
204     uint32_t nameLen = 0;
205     tie(succ, name, nameLen) = NVal(env, funcArg[NARG_POS::THIRD]).ToUTF8String();
206     if (!succ) {
207         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_VALUE);
208         return NVal::CreateNull(env).val_;
209     }
210     std::string str(name.get(), nameLen);
211     return context->GetWebGLRenderingContextImpl().BindAttribLocation(
212         env, funcArg[NARG_POS::FIRST], static_cast<GLuint>(index), str);
213 }
214 
BindBuffer(napi_env env,napi_callback_info info)215 napi_value WebGLRenderingContextBase::BindBuffer(napi_env env, napi_callback_info info)
216 {
217     NFuncArg funcArg(env, info);
218     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
219         return NVal::CreateNull(env).val_;
220     }
221     bool succ = false;
222     GLenum target = 0;
223     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
224     if (!succ) {
225         return NVal::CreateNull(env).val_;
226     }
227     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
228     if (context != nullptr) {
229         context->GetWebGLRenderingContextImpl().BindBuffer(env, target, funcArg[NARG_POS::SECOND]);
230     }
231     return NVal::CreateNull(env).val_;
232 }
233 
BindFramebuffer(napi_env env,napi_callback_info info)234 napi_value WebGLRenderingContextBase::BindFramebuffer(napi_env env, napi_callback_info info)
235 {
236     NFuncArg funcArg(env, info);
237     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
238         return NVal::CreateNull(env).val_;
239     }
240     bool succ = false;
241     GLenum target = 0;
242     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
243     if (!succ) {
244         return NVal::CreateNull(env).val_;
245     }
246     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
247     if (context != nullptr) {
248         context->GetWebGLRenderingContextImpl().BindFrameBuffer(env, target, funcArg[NARG_POS::SECOND]);
249     }
250     return NVal::CreateNull(env).val_;
251 }
252 
BindRenderbuffer(napi_env env,napi_callback_info info)253 napi_value WebGLRenderingContextBase::BindRenderbuffer(napi_env env, napi_callback_info info)
254 {
255     NFuncArg funcArg(env, info);
256     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
257         return NVal::CreateNull(env).val_;
258     }
259     bool succ = false;
260     GLenum target = 0;
261     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
262     if (!succ) {
263         return NVal::CreateNull(env).val_;
264     }
265     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
266     return (context == nullptr) ? NVal::CreateNull(env).val_ :
267         context->GetWebGLRenderingContextImpl().BindRenderBuffer(env, target, funcArg[NARG_POS::SECOND]);
268 }
269 
BindTexture(napi_env env,napi_callback_info info)270 napi_value WebGLRenderingContextBase::BindTexture(napi_env env, napi_callback_info info)
271 {
272     NFuncArg funcArg(env, info);
273     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
274         return NVal::CreateNull(env).val_;
275     }
276     bool succ = false;
277     GLenum target = 0;
278     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
279     if (!succ) {
280         return NVal::CreateNull(env).val_;
281     }
282     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
283     return (context == nullptr) ? NVal::CreateNull(env).val_ :
284         context->GetWebGLRenderingContextImpl().BindTexture(env, target, funcArg[NARG_POS::SECOND]);
285 }
286 
BlendColor(napi_env env,napi_callback_info info)287 napi_value WebGLRenderingContextBase::BlendColor(napi_env env, napi_callback_info info)
288 {
289     NFuncArg funcArg(env, info);
290     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
291         return NVal::CreateNull(env).val_;
292     }
293 
294     bool succ = false;
295     double red = 0.0;
296     tie(succ, red) = NVal(env, funcArg[NARG_POS::FIRST]).ToDouble();
297     if (!succ) {
298         return NVal::CreateNull(env).val_;
299     }
300     double green = 0.0;
301     tie(succ, green) = NVal(env, funcArg[NARG_POS::SECOND]).ToDouble();
302     if (!succ) {
303         return NVal::CreateNull(env).val_;
304     }
305     double blue = 0.0;
306     tie(succ, blue) = NVal(env, funcArg[NARG_POS::THIRD]).ToDouble();
307     if (!succ) {
308         return NVal::CreateNull(env).val_;
309     }
310     double alpha = 0.0;
311     tie(succ, alpha) = NVal(env, funcArg[NARG_POS::FOURTH]).ToDouble();
312     if (!succ) {
313         return NVal::CreateNull(env).val_;
314     }
315     LOGD("WebGL blendColor %{public}f %{public}f %{public}f %{public}f ", static_cast<GLclampf>(red),
316         static_cast<GLclampf>(green), static_cast<GLclampf>(blue), static_cast<GLclampf>(alpha));
317     glBlendColor(static_cast<GLclampf>(red), static_cast<GLclampf>(green), static_cast<GLclampf>(blue),
318         static_cast<GLclampf>(alpha));
319     return NVal::CreateNull(env).val_;
320 }
321 
BlendEquation(napi_env env,napi_callback_info info)322 napi_value WebGLRenderingContextBase::BlendEquation(napi_env env, napi_callback_info info)
323 {
324     NFuncArg funcArg(env, info);
325     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
326         return NVal::CreateNull(env).val_;
327     }
328     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
329     if (context == nullptr) {
330         return NVal::CreateNull(env).val_;
331     }
332     bool succ = false;
333     GLenum mode = 0;
334     tie(succ, mode) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
335     if (!succ) {
336         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
337         return NVal::CreateNull(env).val_;
338     }
339     LOGD("WebGL blendEquation mode %{public}u", mode);
340     if (!CheckGLenum(env, funcArg.GetThisVar(), mode,
341         {
342             WebGLRenderingContextBase::FUNC_ADD,
343             WebGLRenderingContextBase::FUNC_SUBTRACT,
344             WebGLRenderingContextBase::FUNC_REVERSE_SUBTRACT
345         },
346         {
347             WebGL2RenderingContextBase::MIN,
348             WebGL2RenderingContextBase::MAX
349         })) {
350         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
351         return NVal::CreateNull(env).val_;
352     }
353     glBlendEquation(mode);
354     return NVal::CreateNull(env).val_;
355 }
356 
BlendEquationSeparate(napi_env env,napi_callback_info info)357 napi_value WebGLRenderingContextBase::BlendEquationSeparate(napi_env env, napi_callback_info info)
358 {
359     NFuncArg funcArg(env, info);
360     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
361         return NVal::CreateNull(env).val_;
362     }
363     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
364     if (context == nullptr) {
365         return NVal::CreateNull(env).val_;
366     }
367     bool succ = false;
368     GLenum modeRGB = 0;
369     tie(succ, modeRGB) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
370     if (!succ) {
371         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
372         return NVal::CreateNull(env).val_;
373     }
374     GLenum modeAlpha = 0;
375     tie(succ, modeAlpha) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
376     if (!succ) {
377         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
378         return NVal::CreateNull(env).val_;
379     }
380     LOGD("WebGL blendEquationSeparate modeRGB %{public}u  %{public}u", modeRGB, modeAlpha);
381     if (!CheckGLenum(env, funcArg.GetThisVar(), modeRGB, {
382         WebGLRenderingContextBase::FUNC_ADD,
383         WebGLRenderingContextBase::FUNC_SUBTRACT,
384         WebGLRenderingContextBase::FUNC_REVERSE_SUBTRACT
385     }, {
386         WebGL2RenderingContextBase::MIN,
387         WebGL2RenderingContextBase::MAX
388     })) {
389         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
390         return NVal::CreateNull(env).val_;
391     }
392     /*
393      * When using the EXT_blend_minmax extension:
394      *   ext.MIN_EXT: Minimum of source and destination,
395      *   ext.MAX_EXT: Maximum of source and destination.
396     */
397     if (!CheckGLenum(env, funcArg.GetThisVar(), modeAlpha, {
398         WebGLRenderingContextBase::FUNC_ADD,
399         WebGLRenderingContextBase::FUNC_SUBTRACT,
400         WebGLRenderingContextBase::FUNC_REVERSE_SUBTRACT
401     }, {
402         WebGL2RenderingContextBase::MIN,
403         WebGL2RenderingContextBase::MAX
404     })) {
405         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
406         return NVal::CreateNull(env).val_;
407     }
408     glBlendEquationSeparate(modeRGB, modeAlpha);
409     return NVal::CreateNull(env).val_;
410 }
411 
CheckBlendFuncFactors(GLenum sFactor,GLenum dFactor)412 static bool CheckBlendFuncFactors(GLenum sFactor, GLenum dFactor)
413 {
414     if (((sFactor == WebGLRenderingContextBase::CONSTANT_COLOR ||
415             sFactor == WebGLRenderingContextBase::ONE_MINUS_CONSTANT_COLOR) &&
416             (dFactor == WebGLRenderingContextBase::CONSTANT_ALPHA ||
417                 dFactor == WebGLRenderingContextBase::ONE_MINUS_CONSTANT_ALPHA)) ||
418         ((dFactor == WebGLRenderingContextBase::CONSTANT_COLOR ||
419             dFactor == WebGLRenderingContextBase::ONE_MINUS_CONSTANT_COLOR) &&
420             (sFactor == WebGLRenderingContextBase::CONSTANT_ALPHA ||
421                 sFactor == WebGLRenderingContextBase::ONE_MINUS_CONSTANT_ALPHA))) {
422         return false;
423     }
424     return true;
425 }
426 
BlendFunc(napi_env env,napi_callback_info info)427 napi_value WebGLRenderingContextBase::BlendFunc(napi_env env, napi_callback_info info)
428 {
429     NFuncArg funcArg(env, info);
430     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
431         return NVal::CreateNull(env).val_;
432     }
433 
434     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
435     if (context == nullptr) {
436         return NVal::CreateNull(env).val_;
437     }
438 
439     bool succ = false;
440     GLenum sFactor = 0;
441     tie(succ, sFactor) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
442     if (!succ) {
443         sFactor = WebGLRenderingContextBase::ONE;
444     }
445     GLenum dFactor = 0;
446     tie(succ, dFactor) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
447     if (!succ) {
448         dFactor = WebGLRenderingContextBase::ZERO;
449     }
450     LOGD("WebGL blendFunc sFactor %{public}u dFactor %{public}u", sFactor, dFactor);
451 
452     if (!CheckBlendFuncFactors(sFactor, dFactor)) {
453         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_OPERATION);
454         return NVal::CreateNull(env).val_;
455     }
456     glBlendFunc(sFactor, dFactor);
457     return NVal::CreateNull(env).val_;
458 }
459 
BlendFuncSeparate(napi_env env,napi_callback_info info)460 napi_value WebGLRenderingContextBase::BlendFuncSeparate(napi_env env, napi_callback_info info)
461 {
462     NFuncArg funcArg(env, info);
463     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
464         return NVal::CreateNull(env).val_;
465     }
466     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
467     if (context == nullptr) {
468         return NVal::CreateNull(env).val_;
469     }
470     bool succ = false;
471     GLenum srcRGB = 0;
472     tie(succ, srcRGB) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
473     if (!succ) {
474         srcRGB = WebGLRenderingContextBase::ONE;
475     }
476     GLenum dstRGB = 0;
477     tie(succ, dstRGB) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
478     if (!succ) {
479         dstRGB = WebGLRenderingContextBase::ZERO;
480     }
481     GLenum srcAlpha = 0;
482     tie(succ, srcAlpha) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
483     if (!succ) {
484         srcAlpha = WebGLRenderingContextBase::ONE;
485     }
486     GLenum dstAlpha = 0;
487     tie(succ, dstAlpha) = NVal(env, funcArg[NARG_POS::FOURTH]).ToGLenum();
488     if (!succ) {
489         dstAlpha = WebGLRenderingContextBase::ZERO;
490     }
491     LOGD("WebGL blendFuncSeparate srcRGB %{public}u, dstAlpha %{public}u, dstRGB %{public}u, srcAlpha %{public}u",
492         srcRGB, dstAlpha, dstRGB, srcAlpha);
493     if (!CheckBlendFuncFactors(srcRGB, dstRGB)) {
494         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_OPERATION);
495         return NVal::CreateNull(env).val_;
496     }
497     glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
498     return NVal::CreateNull(env).val_;
499 }
500 
CheckFramebufferStatus(napi_env env,napi_callback_info info)501 napi_value WebGLRenderingContextBase::CheckFramebufferStatus(napi_env env, napi_callback_info info)
502 {
503     NFuncArg funcArg(env, info);
504     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
505         return NVal::CreateNull(env).val_;
506     }
507     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
508     if (context == nullptr) {
509         return NVal::CreateNull(env).val_;
510     }
511 
512     bool succ = false;
513     GLenum target = 0;
514     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
515     return !succ ? NVal::CreateNull(env).val_ :
516         context->GetWebGLRenderingContextImpl().CheckFrameBufferStatus(env, target);
517 }
518 
Clear(napi_env env,napi_callback_info info)519 napi_value WebGLRenderingContextBase::Clear(napi_env env, napi_callback_info info)
520 {
521     NFuncArg funcArg(env, info);
522     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
523         return NVal::CreateNull(env).val_;
524     }
525 
526     bool succ = false;
527     int64_t mask = 0;
528     tie(succ, mask) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt64();
529     if (!succ) {
530         return NVal::CreateNull(env).val_;
531     }
532     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
533     return (context == nullptr) ? NVal::CreateNull(env).val_ :
534         context->GetWebGLRenderingContextImpl().Clear(env, static_cast<GLbitfield>(mask));
535 }
536 
ClearColor(napi_env env,napi_callback_info info)537 napi_value WebGLRenderingContextBase::ClearColor(napi_env env, napi_callback_info info)
538 {
539     NFuncArg funcArg(env, info);
540     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
541         return NVal::CreateNull(env).val_;
542     }
543     bool succ = false;
544     float red = -1.0;
545     tie(succ, red) = NVal(env, funcArg[NARG_POS::FIRST]).ToFloat();
546     if (!succ || std::isnan(red)) {
547         red = 0.0;
548     }
549     float green = -1.0;
550     tie(succ, green) = NVal(env, funcArg[NARG_POS::SECOND]).ToFloat();
551     if (!succ || std::isnan(green)) {
552         green = 0.0;
553     }
554     float blue = -1.0;
555     tie(succ, blue) = NVal(env, funcArg[NARG_POS::THIRD]).ToFloat();
556     if (!succ || std::isnan(blue)) {
557         blue = 0.0;
558     }
559     float alpha = -1.0;
560     tie(succ, alpha) = NVal(env, funcArg[NARG_POS::FOURTH]).ToFloat();
561     if (!succ || std::isnan(alpha)) {
562         alpha = 0.0;
563     }
564     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
565     return (context == nullptr) ? NVal::CreateNull(env).val_ :
566         context->GetWebGLRenderingContextImpl().ClearColor(env, static_cast<GLclampf>(red),
567         static_cast<GLclampf>(green), static_cast<GLclampf>(blue), static_cast<GLclampf>(alpha));
568 }
569 
ClearDepth(napi_env env,napi_callback_info info)570 napi_value WebGLRenderingContextBase::ClearDepth(napi_env env, napi_callback_info info)
571 {
572     NFuncArg funcArg(env, info);
573     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
574         return NVal::CreateNull(env).val_;
575     }
576     bool succ = false;
577     float depth = -1.0;
578     tie(succ, depth) = NVal(env, funcArg[NARG_POS::FIRST]).ToFloat();
579     if (!succ || std::isnan(depth)) {
580         depth = 0.0;
581     }
582     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
583     return (context == nullptr) ? NVal::CreateNull(env).val_ :
584         context->GetWebGLRenderingContextImpl().ClearDepth(env, depth);
585 }
586 
ClearStencil(napi_env env,napi_callback_info info)587 napi_value WebGLRenderingContextBase::ClearStencil(napi_env env, napi_callback_info info)
588 {
589     NFuncArg funcArg(env, info);
590     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
591         return NVal::CreateNull(env).val_;
592     }
593     bool succ = false;
594     int32_t stenci = -1;
595     tie(succ, stenci) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
596     if (!succ) {
597         stenci = 0;
598     }
599     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
600     return (context == nullptr) ? NVal::CreateNull(env).val_ :
601         context->GetWebGLRenderingContextImpl().ClearStencil(env, stenci);
602 }
603 
ColorMask(napi_env env,napi_callback_info info)604 napi_value WebGLRenderingContextBase::ColorMask(napi_env env, napi_callback_info info)
605 {
606     NFuncArg funcArg(env, info);
607     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
608         return NVal::CreateNull(env).val_;
609     }
610     bool succ = false;
611     bool red = false;
612     tie(succ, red) = NVal(env, funcArg[NARG_POS::FIRST]).ToBool();
613     if (!succ) {
614         red = true;
615     }
616     bool green = false;
617     tie(succ, green) = NVal(env, funcArg[NARG_POS::SECOND]).ToBool();
618     if (!succ) {
619         green = true;
620     }
621     bool blue = false;
622     tie(succ, blue) = NVal(env, funcArg[NARG_POS::THIRD]).ToBool();
623     if (!succ) {
624         blue = true;
625     }
626     bool alpha = false;
627     tie(succ, alpha) = NVal(env, funcArg[NARG_POS::FOURTH]).ToBool();
628     if (!succ) {
629         alpha = true;
630     }
631     LOGD("WebGL colorMask red %{public}d green %{public}d blue %{public}d alpha %{public}d",
632         red, green, blue, alpha);
633     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
634     return (context == nullptr) ? NVal::CreateNull(env).val_ :
635         context->GetWebGLRenderingContextImpl().ColorMask(env, static_cast<GLboolean>(red),
636         static_cast<GLboolean>(green), static_cast<GLboolean>(blue), static_cast<GLboolean>(alpha));
637 }
638 
CompileShader(napi_env env,napi_callback_info info)639 napi_value WebGLRenderingContextBase::CompileShader(napi_env env, napi_callback_info info)
640 {
641     NFuncArg funcArg(env, info);
642     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
643         return NVal::CreateNull(env).val_;
644     }
645     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
646     return (context == nullptr) ? NVal::CreateNull(env).val_ :
647         context->GetWebGLRenderingContextImpl().CompileShader(env, funcArg[NARG_POS::FIRST]);
648 }
649 
CopyTexImage2D(napi_env env,napi_callback_info info)650 napi_value WebGLRenderingContextBase::CopyTexImage2D(napi_env env, napi_callback_info info)
651 {
652     NFuncArg funcArg(env, info);
653     if (!funcArg.InitArgs(NARG_CNT::EIGHT)) {
654         return NVal::CreateNull(env).val_;
655     }
656 
657     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
658     if (context == nullptr) {
659         return NVal::CreateNull(env).val_;
660     }
661     CopyTexImage2DArg imgArg = {};
662     imgArg.func = Impl::IMAGE_COPY_TEX_IMAGE_2D;
663     bool succ = false;
664     tie(succ, imgArg.target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
665     if (!succ) {
666         return NVal::CreateNull(env).val_;
667     }
668     tie(succ, imgArg.level) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32();
669     if (!succ) {
670         return NVal::CreateNull(env).val_;
671     }
672     tie(succ, imgArg.internalFormat) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
673     if (!succ) {
674         return NVal::CreateNull(env).val_;
675     }
676     tie(succ, imgArg.x) = NVal(env, funcArg[NARG_POS::FOURTH]).ToInt32();
677     if (!succ) {
678         return NVal::CreateNull(env).val_;
679     }
680     tie(succ, imgArg.y) = NVal(env, funcArg[NARG_POS::FIFTH]).ToInt32();
681     if (!succ) {
682         return NVal::CreateNull(env).val_;
683     }
684     tie(succ, imgArg.width) = NVal(env, funcArg[NARG_POS::SIXTH]).ToGLsizei();
685     if (!succ) {
686         return NVal::CreateNull(env).val_;
687     }
688     tie(succ, imgArg.height) = NVal(env, funcArg[NARG_POS::SEVENTH]).ToGLsizei();
689     if (!succ) {
690         return NVal::CreateNull(env).val_;
691     }
692     tie(succ, imgArg.border) = NVal(env, funcArg[NARG_POS::EIGHTH]).ToInt32();
693     return !succ ? NVal::CreateNull(env).val_ :
694         context->GetWebGLRenderingContextImpl().CopyTexImage2D(env, imgArg);
695 }
696 
CopyTexSubImage2D(napi_env env,napi_callback_info info)697 napi_value WebGLRenderingContextBase::CopyTexSubImage2D(napi_env env, napi_callback_info info)
698 {
699     NFuncArg funcArg(env, info);
700     if (!funcArg.InitArgs(NARG_CNT::EIGHT)) {
701         return NVal::CreateNull(env).val_;
702     }
703 
704     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
705     if (context == nullptr) {
706         return NVal::CreateNull(env).val_;
707     }
708     CopyTexSubImageArg imgArg = {};
709     imgArg.func = Impl::IMAGE_COPY_TEX_SUB_IMAGE_2D;
710     bool succ = false;
711     tie(succ, imgArg.target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
712     if (!succ) {
713         return NVal::CreateNull(env).val_;
714     }
715     tie(succ, imgArg.level) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32();
716     if (!succ) {
717         return NVal::CreateNull(env).val_;
718     }
719     tie(succ, imgArg.xOffset) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32();
720     if (!succ) {
721         return NVal::CreateNull(env).val_;
722     }
723     tie(succ, imgArg.yOffset) = NVal(env, funcArg[NARG_POS::FOURTH]).ToInt32();
724     if (!succ) {
725         return NVal::CreateNull(env).val_;
726     }
727     tie(succ, imgArg.x) = NVal(env, funcArg[NARG_POS::FIFTH]).ToInt32();
728     if (!succ) {
729         return NVal::CreateNull(env).val_;
730     }
731     tie(succ, imgArg.x) = NVal(env, funcArg[NARG_POS::SIXTH]).ToInt32();
732     if (!succ) {
733         return NVal::CreateNull(env).val_;
734     }
735     tie(succ, imgArg.width) = NVal(env, funcArg[NARG_POS::SEVENTH]).ToGLsizei();
736     if (!succ) {
737         return NVal::CreateNull(env).val_;
738     }
739     tie(succ, imgArg.height) = NVal(env, funcArg[NARG_POS::EIGHTH]).ToGLsizei();
740     return !succ ? NVal::CreateNull(env).val_ :
741         context->GetWebGLRenderingContextImpl().CopyTexSubImage2D(env, imgArg);
742 }
743 
CreateBuffer(napi_env env,napi_callback_info info)744 napi_value WebGLRenderingContextBase::CreateBuffer(napi_env env, napi_callback_info info)
745 {
746     NFuncArg funcArg(env, info);
747     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
748         return NVal::CreateNull(env).val_;
749     }
750     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
751     return (context == nullptr) ? NVal::CreateNull(env).val_ :
752         context->GetWebGLRenderingContextImpl().CreateBuffer(env);
753 }
754 
CreateFramebuffer(napi_env env,napi_callback_info info)755 napi_value WebGLRenderingContextBase::CreateFramebuffer(napi_env env, napi_callback_info info)
756 {
757     NFuncArg funcArg(env, info);
758     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
759         return NVal::CreateNull(env).val_;
760     }
761     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
762     return (context == nullptr) ? NVal::CreateNull(env).val_ :
763         context->GetWebGLRenderingContextImpl().CreateFrameBuffer(env);
764 }
765 
CreateProgram(napi_env env,napi_callback_info info)766 napi_value WebGLRenderingContextBase::CreateProgram(napi_env env, napi_callback_info info)
767 {
768     NFuncArg funcArg(env, info);
769     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
770         return NVal::CreateNull(env).val_;
771     }
772     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
773     return (context == nullptr) ? NVal::CreateNull(env).val_ :
774         context->GetWebGLRenderingContextImpl().CreateProgram(env);
775 }
776 
CreateRenderbuffer(napi_env env,napi_callback_info info)777 napi_value WebGLRenderingContextBase::CreateRenderbuffer(napi_env env, napi_callback_info info)
778 {
779     LOGD("WebGL createRenderbuffer start");
780     NFuncArg funcArg(env, info);
781     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
782         return NVal::CreateNull(env).val_;
783     }
784     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
785     return (context == nullptr) ? NVal::CreateNull(env).val_ :
786         context->GetWebGLRenderingContextImpl().CreateRenderBuffer(env);
787 }
788 
CreateShader(napi_env env,napi_callback_info info)789 napi_value WebGLRenderingContextBase::CreateShader(napi_env env, napi_callback_info info)
790 {
791     NFuncArg funcArg(env, info);
792     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
793         return NVal::CreateNull(env).val_;
794     }
795     bool succ = false;
796     GLenum type = 0;
797     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
798     if (context == nullptr) {
799         return NVal::CreateNull(env).val_;
800     }
801     tie(succ, type) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
802     if (!succ) {
803         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
804         return NVal::CreateNull(env).val_;
805     }
806     return context->GetWebGLRenderingContextImpl().CreateShader(env, type);
807 }
808 
CreateTexture(napi_env env,napi_callback_info info)809 napi_value WebGLRenderingContextBase::CreateTexture(napi_env env, napi_callback_info info)
810 {
811     NFuncArg funcArg(env, info);
812     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
813         return NVal::CreateNull(env).val_;
814     }
815     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
816     return (context == nullptr) ? NVal::CreateNull(env).val_ :
817         context->GetWebGLRenderingContextImpl().CreateTextureObject(env);
818 }
819 
CullFace(napi_env env,napi_callback_info info)820 napi_value WebGLRenderingContextBase::CullFace(napi_env env, napi_callback_info info)
821 {
822     NFuncArg funcArg(env, info);
823     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
824         return NVal::CreateNull(env).val_;
825     }
826     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
827     if (context == nullptr) {
828         return NVal::CreateNull(env).val_;
829     }
830     bool succ = false;
831     GLenum mode = 0;
832     tie(succ, mode) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
833     if (!succ) {
834         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
835         return NVal::CreateNull(env).val_;
836     }
837     LOGD("WebGL cullFace mode %{public}u", mode);
838     switch (mode) {
839         case WebGLRenderingContextBase::FRONT_AND_BACK:
840         case WebGLRenderingContextBase::FRONT:
841         case WebGLRenderingContextBase::BACK:
842             break;
843         default:
844             context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
845             return NVal::CreateNull(env).val_;
846     }
847     glCullFace(static_cast<GLenum>(mode));
848     return NVal::CreateNull(env).val_;
849 }
850 
DeleteBuffer(napi_env env,napi_callback_info info)851 napi_value WebGLRenderingContextBase::DeleteBuffer(napi_env env, napi_callback_info info)
852 {
853     NFuncArg funcArg(env, info);
854     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
855         return NVal::CreateNull(env).val_;
856     }
857 
858     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
859     return (context == nullptr) ? NVal::CreateNull(env).val_ :
860         context->GetWebGLRenderingContextImpl().DeleteBuffer(env, funcArg[NARG_POS::FIRST]);
861 }
862 
DeleteFramebuffer(napi_env env,napi_callback_info info)863 napi_value WebGLRenderingContextBase::DeleteFramebuffer(napi_env env, napi_callback_info info)
864 {
865     NFuncArg funcArg(env, info);
866     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
867         return NVal::CreateNull(env).val_;
868     }
869 
870     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
871     return (context == nullptr) ? NVal::CreateNull(env).val_ :
872         context->GetWebGLRenderingContextImpl().DeleteFrameBuffer(env, funcArg[NARG_POS::FIRST]);
873 }
874 
DeleteProgram(napi_env env,napi_callback_info info)875 napi_value WebGLRenderingContextBase::DeleteProgram(napi_env env, napi_callback_info info)
876 {
877     NFuncArg funcArg(env, info);
878     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
879         return NVal::CreateNull(env).val_;
880     }
881 
882     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
883     return (context == nullptr) ? NVal::CreateNull(env).val_ :
884         context->GetWebGLRenderingContextImpl().DeleteProgram(env, funcArg[NARG_POS::FIRST]);
885 }
886 
DeleteRenderbuffer(napi_env env,napi_callback_info info)887 napi_value WebGLRenderingContextBase::DeleteRenderbuffer(napi_env env, napi_callback_info info)
888 {
889     NFuncArg funcArg(env, info);
890     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
891         return NVal::CreateNull(env).val_;
892     }
893 
894     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
895     return (context == nullptr) ? NVal::CreateNull(env).val_ :
896         context->GetWebGLRenderingContextImpl().DeleteRenderBuffer(env, funcArg[NARG_POS::FIRST]);
897 }
898 
DeleteShader(napi_env env,napi_callback_info info)899 napi_value WebGLRenderingContextBase::DeleteShader(napi_env env, napi_callback_info info)
900 {
901     NFuncArg funcArg(env, info);
902     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
903         return NVal::CreateNull(env).val_;
904     }
905 
906     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
907     return (context == nullptr) ? NVal::CreateNull(env).val_ :
908         context->GetWebGLRenderingContextImpl().DeleteShader(env, funcArg[NARG_POS::FIRST]);
909 }
910 
DeleteTexture(napi_env env,napi_callback_info info)911 napi_value WebGLRenderingContextBase::DeleteTexture(napi_env env, napi_callback_info info)
912 {
913     NFuncArg funcArg(env, info);
914     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
915         return NVal::CreateNull(env).val_;
916     }
917 
918     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
919     return (context == nullptr) ? NVal::CreateNull(env).val_ :
920         context->GetWebGLRenderingContextImpl().DeleteTexture(env, funcArg[NARG_POS::FIRST]);
921 }
922 
CheckFuncForStencilOrDepth(GLenum func)923 static bool CheckFuncForStencilOrDepth(GLenum func)
924 {
925     switch (func) {
926         case WebGLRenderingContextBase::NEVER:
927         case WebGLRenderingContextBase::LESS:
928         case WebGLRenderingContextBase::LEQUAL:
929         case WebGLRenderingContextBase::GREATER:
930         case WebGLRenderingContextBase::GEQUAL:
931         case WebGLRenderingContextBase::EQUAL:
932         case WebGLRenderingContextBase::NOTEQUAL:
933         case WebGLRenderingContextBase::ALWAYS:
934             return true;
935         default:
936             return false;
937     }
938 }
939 
DepthFunc(napi_env env,napi_callback_info info)940 napi_value WebGLRenderingContextBase::DepthFunc(napi_env env, napi_callback_info info)
941 {
942     NFuncArg funcArg(env, info);
943 
944     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
945         return NVal::CreateNull(env).val_;
946     }
947     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
948     if (context == nullptr) {
949         return NVal::CreateNull(env).val_;
950     }
951     bool succ = false;
952     GLenum func = 0;
953     tie(succ, func) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
954     if (!succ || !CheckFuncForStencilOrDepth(func)) {
955         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
956     }
957     LOGD("WebGL depthFunc func %{public}u", func);
958     glDepthFunc(func);
959     return NVal::CreateNull(env).val_;
960 }
961 
DepthMask(napi_env env,napi_callback_info info)962 napi_value WebGLRenderingContextBase::DepthMask(napi_env env, napi_callback_info info)
963 {
964     NFuncArg funcArg(env, info);
965 
966     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
967         return NVal::CreateNull(env).val_;
968     }
969     bool succ = false;
970     bool flag = false;
971     tie(succ, flag) = NVal(env, funcArg[NARG_POS::FIRST]).ToBool();
972     if (!succ) {
973         flag = true;
974     }
975 
976     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
977     return (context == nullptr) ? NVal::CreateNull(env).val_ :
978         context->GetWebGLRenderingContextImpl().DepthMask(env, flag);
979 }
980 
DepthRange(napi_env env,napi_callback_info info)981 napi_value WebGLRenderingContextBase::DepthRange(napi_env env, napi_callback_info info)
982 {
983     NFuncArg funcArg(env, info);
984 
985     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
986         return NVal::CreateNull(env).val_;
987     }
988     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
989     if (context == nullptr) {
990         return NVal::CreateNull(env).val_;
991     }
992     bool succ = false;
993     double zNear = -1.0;
994     tie(succ, zNear) = NVal(env, funcArg[NARG_POS::FIRST]).ToDouble();
995     if (!succ) {
996         zNear = 0.0;
997     }
998     double zFar = -1.0;
999     tie(succ, zFar) = NVal(env, funcArg[NARG_POS::SECOND]).ToDouble();
1000     if (!succ) {
1001         zFar = 1.0;
1002     }
1003     if (zNear > zFar) {
1004         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_OPERATION);
1005         return NVal::CreateNull(env).val_;
1006     }
1007     LOGD("WebGL depthRange zNear %{public}f zFar %{public}f ", zNear, zFar);
1008     glDepthRangef(static_cast<GLclampf>(zNear), static_cast<GLclampf>(zFar));
1009     return NVal::CreateNull(env).val_;
1010 }
1011 
DetachShader(napi_env env,napi_callback_info info)1012 napi_value WebGLRenderingContextBase::DetachShader(napi_env env, napi_callback_info info)
1013 {
1014     NFuncArg funcArg(env, info);
1015     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1016         return NVal::CreateNull(env).val_;
1017     }
1018 
1019     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1020     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1021         context->GetWebGLRenderingContextImpl().DetachShader(
1022         env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]);
1023 }
1024 
Disable(napi_env env,napi_callback_info info)1025 napi_value WebGLRenderingContextBase::Disable(napi_env env, napi_callback_info info)
1026 {
1027     NFuncArg funcArg(env, info);
1028     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1029         return NVal::CreateNull(env).val_;
1030     }
1031 
1032     bool succ = false;
1033     GLenum cap = 0;
1034     tie(succ, cap) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1035     if (!succ) {
1036         cap = 0;
1037     }
1038     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1039     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1040         context->GetWebGLRenderingContextImpl().Disable(env, cap);
1041 }
1042 
DrawArrays(napi_env env,napi_callback_info info)1043 napi_value WebGLRenderingContextBase::DrawArrays(napi_env env, napi_callback_info info)
1044 {
1045     NFuncArg funcArg(env, info);
1046     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
1047         return NVal::CreateNull(env).val_;
1048     }
1049 
1050     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1051     if (context == nullptr) {
1052         return NVal::CreateNull(env).val_;
1053     }
1054     bool succ = false;
1055     GLenum mode = 0;
1056     tie(succ, mode) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1057     if (!succ) {
1058         return NVal::CreateNull(env).val_;
1059     }
1060     int64_t first = 0;
1061     tie(succ, first) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt64();
1062     if (!succ) {
1063         return NVal::CreateNull(env).val_;
1064     }
1065     GLsizei count = 0;
1066     tie(succ, count) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLsizei();
1067     return !succ ? nullptr : context->GetWebGLRenderingContextImpl().DrawArrays(
1068         env, mode, static_cast<GLint>(first), count);
1069 }
1070 
DrawElements(napi_env env,napi_callback_info info)1071 napi_value WebGLRenderingContextBase::DrawElements(napi_env env, napi_callback_info info)
1072 {
1073     NFuncArg funcArg(env, info);
1074     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
1075         return NVal::CreateNull(env).val_;
1076     }
1077     bool succ = false;
1078     GLenum mode = 0;
1079     tie(succ, mode) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1080     if (!succ) {
1081         return NVal::CreateNull(env).val_;
1082     }
1083     int64_t count = 0;
1084     tie(succ, count) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt64();
1085     if (!succ) {
1086         return NVal::CreateNull(env).val_;
1087     }
1088     GLenum type = 0;
1089     tie(succ, type) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
1090     if (!succ) {
1091         return NVal::CreateNull(env).val_;
1092     }
1093     int64_t offset = 0;
1094     tie(succ, offset) = NVal(env, funcArg[NARG_POS::FOURTH]).ToInt64();
1095     if (!succ) {
1096         return NVal::CreateNull(env).val_;
1097     }
1098     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1099     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1100         context->GetWebGLRenderingContextImpl().DrawElements(
1101         env, mode, static_cast<GLsizei>(count), type, static_cast<GLintptr>(offset));
1102 }
1103 
Enable(napi_env env,napi_callback_info info)1104 napi_value WebGLRenderingContextBase::Enable(napi_env env, napi_callback_info info)
1105 {
1106     NFuncArg funcArg(env, info);
1107     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1108         return NVal::CreateNull(env).val_;
1109     }
1110 
1111     bool succ = false;
1112     GLenum cap = 0;
1113     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1114     if (context == nullptr) {
1115         return NVal::CreateNull(env).val_;
1116     }
1117     tie(succ, cap) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1118     if (!succ) {
1119         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1120         return NVal::CreateNull(env).val_;
1121     }
1122     return context->GetWebGLRenderingContextImpl().Enable(env, cap);
1123 }
1124 
EnableVertexAttribArray(napi_env env,napi_callback_info info)1125 napi_value WebGLRenderingContextBase::EnableVertexAttribArray(napi_env env, napi_callback_info info)
1126 {
1127     NFuncArg funcArg(env, info);
1128     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1129         return NVal::CreateNull(env).val_;
1130     }
1131 
1132     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1133     if (context == nullptr) {
1134         return NVal::CreateNull(env).val_;
1135     }
1136     int64_t index = 0;
1137     bool succ = false;
1138     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt64();
1139     if (!succ) {
1140         index = -1;
1141     }
1142     return context->GetWebGLRenderingContextImpl().EnableVertexAttribArray(env, index);
1143 }
1144 
DisableVertexAttribArray(napi_env env,napi_callback_info info)1145 napi_value WebGLRenderingContextBase::DisableVertexAttribArray(napi_env env, napi_callback_info info)
1146 {
1147     NFuncArg funcArg(env, info);
1148     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1149         return NVal::CreateNull(env).val_;
1150     }
1151 
1152     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1153     if (context == nullptr) {
1154         return NVal::CreateNull(env).val_;
1155     }
1156     int64_t index = 0;
1157     bool succ = false;
1158     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt64();
1159     if (!succ) {
1160         index = -1;
1161     }
1162     return context->GetWebGLRenderingContextImpl().DisableVertexAttribArray(env, index);
1163 }
1164 
Finish(napi_env env,napi_callback_info info)1165 napi_value WebGLRenderingContextBase::Finish(napi_env env, napi_callback_info info)
1166 {
1167     glFinish();
1168     LOGD("WebGL finish end");
1169     return NVal::CreateNull(env).val_;
1170 }
1171 
Flush(napi_env env,napi_callback_info info)1172 napi_value WebGLRenderingContextBase::Flush(napi_env env, napi_callback_info info)
1173 {
1174     NFuncArg funcArg(env, info);
1175     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
1176         return NVal::CreateNull(env).val_;
1177     }
1178 
1179     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1180     if (context == nullptr) {
1181         LOGE("WebGL flush context is nullptr");
1182         return NVal::CreateNull(env).val_;
1183     }
1184     glFlush();
1185     context->Update();
1186     LOGD("WebGL flush end");
1187     return NVal::CreateNull(env).val_;
1188 }
1189 
FramebufferRenderbuffer(napi_env env,napi_callback_info info)1190 napi_value WebGLRenderingContextBase::FramebufferRenderbuffer(napi_env env, napi_callback_info info)
1191 {
1192     NFuncArg funcArg(env, info);
1193     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
1194         return NVal::CreateNull(env).val_;
1195     }
1196 
1197     bool succ = false;
1198     GLenum target = 0;
1199     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1200     if (!succ) {
1201         return NVal::CreateNull(env).val_;
1202     }
1203     GLenum attachment = 0;
1204     tie(succ, attachment) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1205     if (!succ) {
1206         return NVal::CreateNull(env).val_;
1207     }
1208     GLenum renderBufferTarget = 0;
1209     tie(succ, renderBufferTarget) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
1210     if (!succ) {
1211         return NVal::CreateNull(env).val_;
1212     }
1213     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1214     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1215         context->GetWebGLRenderingContextImpl().FrameBufferRenderBuffer(
1216         env, target, attachment, renderBufferTarget, funcArg[NARG_POS::FOURTH]);
1217 }
1218 
FramebufferTexture2D(napi_env env,napi_callback_info info)1219 napi_value WebGLRenderingContextBase::FramebufferTexture2D(napi_env env, napi_callback_info info)
1220 {
1221     NFuncArg funcArg(env, info);
1222     if (!funcArg.InitArgs(NARG_CNT::FIVE)) {
1223         return NVal::CreateNull(env).val_;
1224     }
1225 
1226     bool succ = false;
1227     GLenum target = 0;
1228     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1229     if (!succ) {
1230         return NVal::CreateNull(env).val_;
1231     }
1232     GLenum attachment = 0;
1233     tie(succ, attachment) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1234     if (!succ) {
1235         return NVal::CreateNull(env).val_;
1236     }
1237     GLenum textarget = 0;
1238     tie(succ, textarget) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
1239     if (!succ) {
1240         return NVal::CreateNull(env).val_;
1241     }
1242     int64_t level = 0;
1243     tie(succ, level) = NVal(env, funcArg[NARG_POS::FIFTH]).ToInt64();
1244     if (!succ) {
1245         return NVal::CreateNull(env).val_;
1246     }
1247     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1248     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1249         context->GetWebGLRenderingContextImpl().FrameBufferTexture2D(
1250         env, target, attachment, textarget, funcArg[NARG_POS::FOURTH], static_cast<GLint>(level));
1251 }
1252 
GetUniformLocation(napi_env env,napi_callback_info info)1253 napi_value WebGLRenderingContextBase::GetUniformLocation(napi_env env, napi_callback_info info)
1254 {
1255     NFuncArg funcArg(env, info);
1256     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1257         return NVal::CreateNull(env).val_;
1258     }
1259     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1260     if (context == nullptr) {
1261         LOGE("WebGL getUniformLocation fail to get context");
1262         return NVal::CreateNull(env).val_;
1263     }
1264     bool succ = false;
1265     unique_ptr<char[]> name = nullptr;
1266     size_t size = 0;
1267     tie(succ, name, size) = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String();
1268     if (!succ) {
1269         return NVal::CreateNull(env).val_;
1270     }
1271     std::string str(name.get(), size);
1272     return context->GetWebGLRenderingContextImpl().GetUniformLocation(env, funcArg[NARG_POS::FIRST], str);
1273 }
1274 
GetVertexAttribOffset(napi_env env,napi_callback_info info)1275 napi_value WebGLRenderingContextBase::GetVertexAttribOffset(napi_env env, napi_callback_info info)
1276 {
1277     NFuncArg funcArg(env, info);
1278     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1279         return NVal::CreateNull(env).val_;
1280     }
1281 
1282     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1283     if (context == nullptr) {
1284         LOGE("WebGL getUniformLocation fail to get context");
1285         return NVal::CreateNull(env).val_;
1286     }
1287     bool succ = false;
1288     uint32_t index = 0;
1289     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToUint32();
1290     if (!succ) {
1291         return NVal::CreateNull(env).val_;
1292     }
1293     GLenum pname = 0;
1294     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1295     return !succ ? NVal::CreateNull(env).val_ :
1296         context->GetWebGLRenderingContextImpl().GetVertexAttribOffset(env, index, pname);
1297 }
1298 
ShaderSource(napi_env env,napi_callback_info info)1299 napi_value WebGLRenderingContextBase::ShaderSource(napi_env env, napi_callback_info info)
1300 {
1301     NFuncArg funcArg(env, info);
1302     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1303         return NVal::CreateNull(env).val_;
1304     }
1305 
1306     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1307     if (context == nullptr) {
1308         return NVal::CreateNull(env).val_;
1309     }
1310 
1311     bool succ = false;
1312     size_t size = 0;
1313     unique_ptr<char[]> source = nullptr;
1314     tie(succ, source, size) = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String();
1315     if (!succ) {
1316         return NVal::CreateNull(env).val_;
1317     }
1318     LOGD("WebGL shaderSource source %{public}zu, %{public}s", size, source.get());
1319     std::string str(source.get(), size);
1320     return context->GetWebGLRenderingContextImpl().ShaderSource(env, funcArg[NARG_POS::FIRST], str);
1321 }
1322 
Hint(napi_env env,napi_callback_info info)1323 napi_value WebGLRenderingContextBase::Hint(napi_env env, napi_callback_info info)
1324 {
1325     NFuncArg funcArg(env, info);
1326     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1327         return NVal::CreateNull(env).val_;
1328     }
1329     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1330     if (context == nullptr) {
1331         return NVal::CreateNull(env).val_;
1332     }
1333     bool succ = false;
1334     GLenum target = 0;
1335     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1336     if (!succ) {
1337         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1338         return NVal::CreateNull(env).val_;
1339     }
1340     switch (target) {
1341         case WebGLRenderingContextBase::GENERATE_MIPMAP_HINT:
1342             break;
1343         case WebGL2RenderingContextBase::FRAGMENT_SHADER_DERIVATIVE_HINT:
1344             if (IsHighWebGL(env, funcArg.GetThisVar())) {
1345                 break;
1346             }
1347             [[fallthrough]];
1348         default:
1349             context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1350             return NVal::CreateNull(env).val_;
1351     }
1352     GLenum mode = 0;
1353     tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1354     if (!succ) {
1355         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1356         return NVal::CreateNull(env).val_;
1357     }
1358     LOGD("WebGL hint target %{public}u, mode %{public}u", target, mode);
1359     switch (mode) {
1360         case WebGLRenderingContextBase::DONT_CARE:
1361         case WebGLRenderingContextBase::FASTEST:
1362         case WebGLRenderingContextBase::NICEST:
1363             break;
1364         default:
1365             context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1366             return NVal::CreateNull(env).val_;
1367     }
1368     glHint(target, mode);
1369     return NVal::CreateNull(env).val_;
1370 }
1371 
IsBuffer(napi_env env,napi_callback_info info)1372 napi_value WebGLRenderingContextBase::IsBuffer(napi_env env, napi_callback_info info)
1373 {
1374     NFuncArg funcArg(env, info);
1375     bool res = false;
1376     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1377         return NVal::CreateBool(env, res).val_;
1378     }
1379 
1380     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1381     return (context == nullptr) ? NVal::CreateBool(env, res).val_ :
1382         context->GetWebGLRenderingContextImpl().IsBuffer(env, funcArg[NARG_POS::FIRST]);
1383 }
1384 
IsEnabled(napi_env env,napi_callback_info info)1385 napi_value WebGLRenderingContextBase::IsEnabled(napi_env env, napi_callback_info info)
1386 {
1387     NFuncArg funcArg(env, info);
1388     bool res = false;
1389     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1390         return NVal::CreateBool(env, res).val_;
1391     }
1392     bool succ = false;
1393     GLenum cap = 0;
1394     tie(succ, cap) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1395     if (!succ) {
1396         cap = 0;
1397     }
1398     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1399     return (context == nullptr) ? NVal::CreateBool(env, res).val_ :
1400         context->GetWebGLRenderingContextImpl().IsEnabled(env, cap);
1401 }
1402 
RenderbufferStorage(napi_env env,napi_callback_info info)1403 napi_value WebGLRenderingContextBase::RenderbufferStorage(napi_env env, napi_callback_info info)
1404 {
1405     NFuncArg funcArg(env, info);
1406     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
1407         return NVal::CreateNull(env).val_;
1408     }
1409     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1410     if (context == nullptr) {
1411         return NVal::CreateNull(env).val_;
1412     }
1413     bool succ = false;
1414     TexStorageArg arg = {};
1415     tie(succ, arg.target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1416     if (!succ) {
1417         return NVal::CreateNull(env).val_;
1418     }
1419     tie(succ, arg.internalFormat) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1420     if (!succ) {
1421         return NVal::CreateNull(env).val_;
1422     }
1423     tie(succ, arg.width) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLsizei();
1424     if (!succ) {
1425         return NVal::CreateNull(env).val_;
1426     }
1427     tie(succ, arg.height) = NVal(env, funcArg[NARG_POS::FOURTH]).ToGLsizei();
1428     return !succ ? NVal::CreateNull(env).val_ :
1429         context->GetWebGLRenderingContextImpl().RenderBufferStorage(env, arg);
1430 }
1431 
SampleCoverage(napi_env env,napi_callback_info info)1432 napi_value WebGLRenderingContextBase::SampleCoverage(napi_env env, napi_callback_info info)
1433 {
1434     NFuncArg funcArg(env, info);
1435 
1436     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1437         return NVal::CreateNull(env).val_;
1438     }
1439     bool succ = false;
1440     double value = 0.0;
1441     tie(succ, value) = NVal(env, funcArg[NARG_POS::FIRST]).ToDouble();
1442     if (!succ) {
1443         value = 1.0;
1444     }
1445     bool invert = false;
1446     tie(succ, invert) = NVal(env, funcArg[NARG_POS::SECOND]).ToBool();
1447     if (!succ) {
1448         return NVal::CreateNull(env).val_;
1449     }
1450     LOGD("WebGL sampleCoverage %{public}f %{public}d", value, invert);
1451     glSampleCoverage(static_cast<GLclampf>(value), static_cast<GLboolean>(invert));
1452     return NVal::CreateNull(env).val_;
1453 }
1454 
Scissor(napi_env env,napi_callback_info info)1455 napi_value WebGLRenderingContextBase::Scissor(napi_env env, napi_callback_info info)
1456 {
1457     NFuncArg funcArg(env, info);
1458     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
1459         return NVal::CreateNull(env).val_;
1460     }
1461     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1462     if (context == nullptr) {
1463         return NVal::CreateNull(env).val_;
1464     }
1465     bool succ = false;
1466     int32_t x = 0;
1467     tie(succ, x) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
1468     if (!succ) {
1469         return NVal::CreateNull(env).val_;
1470     }
1471     int32_t y = 0;
1472     tie(succ, y) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32();
1473     if (!succ) {
1474         return NVal::CreateNull(env).val_;
1475     }
1476     int64_t width = 0;
1477     tie(succ, width) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt64();
1478     if (!succ) {
1479         return NVal::CreateNull(env).val_;
1480     }
1481     int64_t height = 0;
1482     tie(succ, height) = NVal(env, funcArg[NARG_POS::FOURTH]).ToInt64();
1483     if (!succ) {
1484         return NVal::CreateNull(env).val_;
1485     }
1486     LOGD("WebGL scissor x %{public}d y %{public}d width %{public}" PRIi64 " height %{public}d" PRIi64,
1487         x, y, width, static_cast<int>(height));
1488 
1489     if (width < 0 || height < 0) {
1490         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_VALUE);
1491         return NVal::CreateNull(env).val_;
1492     }
1493     glScissor(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
1494     return NVal::CreateNull(env).val_;
1495 }
1496 
StencilFunc(napi_env env,napi_callback_info info)1497 napi_value WebGLRenderingContextBase::StencilFunc(napi_env env, napi_callback_info info)
1498 {
1499     NFuncArg funcArg(env, info);
1500     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
1501         return NVal::CreateNull(env).val_;
1502     }
1503 
1504     bool succ = false;
1505     GLenum func = 0;
1506     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1507     if (context == nullptr) {
1508         return NVal::CreateNull(env).val_;
1509     }
1510     tie(succ, func) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1511     if (!succ) {
1512         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1513         return NVal::CreateNull(env).val_;
1514     }
1515     int32_t ref = 0;
1516     tie(succ, ref) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32();
1517     if (!succ) {
1518         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1519         return NVal::CreateNull(env).val_;
1520     }
1521     uint32_t mask = 0;
1522     tie(succ, mask) = NVal(env, funcArg[NARG_POS::THIRD]).ToUint32();
1523     if (!succ) {
1524         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1525         return NVal::CreateNull(env).val_;
1526     }
1527     return context->GetWebGLRenderingContextImpl().StencilFunc(
1528         env, func, static_cast<GLint>(ref), static_cast<GLuint>(mask));
1529 }
1530 
StencilFuncSeparate(napi_env env,napi_callback_info info)1531 napi_value WebGLRenderingContextBase::StencilFuncSeparate(napi_env env, napi_callback_info info)
1532 {
1533     NFuncArg funcArg(env, info);
1534     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
1535         return NVal::CreateNull(env).val_;
1536     }
1537 
1538     bool succ = false;
1539     GLenum face = 0;
1540     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1541     if (context == nullptr) {
1542         return NVal::CreateNull(env).val_;
1543     }
1544     tie(succ, face) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1545     if (!succ) {
1546         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1547         return NVal::CreateNull(env).val_;
1548     }
1549     GLenum func = 0;
1550     tie(succ, func) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1551     if (!succ) {
1552         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1553         return NVal::CreateNull(env).val_;
1554     }
1555     int32_t ref = 0;
1556     tie(succ, ref) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32();
1557     if (!succ) {
1558         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1559         return NVal::CreateNull(env).val_;
1560     }
1561     uint32_t mask = 0;
1562     tie(succ, mask) = NVal(env, funcArg[NARG_POS::FOURTH]).ToUint32();
1563     if (!succ) {
1564         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1565         return NVal::CreateNull(env).val_;
1566     }
1567     return context->GetWebGLRenderingContextImpl().StencilFuncSeparate(
1568         env, face, func, static_cast<GLint>(ref), static_cast<GLuint>(mask));
1569 }
1570 
StencilMask(napi_env env,napi_callback_info info)1571 napi_value WebGLRenderingContextBase::StencilMask(napi_env env, napi_callback_info info)
1572 {
1573     NFuncArg funcArg(env, info);
1574     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1575         return NVal::CreateNull(env).val_;
1576     }
1577     bool succ = false;
1578     uint32_t mask = 0;
1579     tie(succ, mask) = NVal(env, funcArg[NARG_POS::FIRST]).ToUint32();
1580     if (!succ) {
1581         return NVal::CreateNull(env).val_;
1582     }
1583     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1584     if (context == nullptr) {
1585         return NVal::CreateNull(env).val_;
1586     }
1587     return context->GetWebGLRenderingContextImpl().StencilMask(env, static_cast<GLuint>(mask));
1588 }
1589 
StencilMaskSeparate(napi_env env,napi_callback_info info)1590 napi_value WebGLRenderingContextBase::StencilMaskSeparate(napi_env env, napi_callback_info info)
1591 {
1592     NFuncArg funcArg(env, info);
1593     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1594         return NVal::CreateNull(env).val_;
1595     }
1596 
1597     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1598     if (context == nullptr) {
1599         return NVal::CreateNull(env).val_;
1600     }
1601     bool succ = false;
1602     GLenum face = 0;
1603     tie(succ, face) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1604     if (!succ) {
1605         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1606         return NVal::CreateNull(env).val_;
1607     }
1608     uint32_t mask = 0;
1609     tie(succ, mask) = NVal(env, funcArg[NARG_POS::SECOND]).ToUint32();
1610     if (!succ) {
1611         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1612         return NVal::CreateNull(env).val_;
1613     }
1614     return context->GetWebGLRenderingContextImpl().StencilMaskSeparate(env, face, static_cast<GLuint>(mask));
1615 }
1616 
StencilOp(napi_env env,napi_callback_info info)1617 napi_value WebGLRenderingContextBase::StencilOp(napi_env env, napi_callback_info info)
1618 {
1619     NFuncArg funcArg(env, info);
1620     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
1621         return NVal::CreateNull(env).val_;
1622     }
1623     bool succ = false;
1624     GLenum fail = 0;
1625     tie(succ, fail) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1626     if (!succ) {
1627         fail = WebGLRenderingContextBase::KEEP;
1628     }
1629     GLenum zfail = 0;
1630     tie(succ, zfail) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1631     if (!succ) {
1632         zfail = WebGLRenderingContextBase::KEEP;
1633     }
1634     GLenum zpass = 0;
1635     tie(succ, zpass) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
1636     if (!succ) {
1637         zpass = WebGLRenderingContextBase::KEEP;
1638     }
1639     LOGD("WebGL stencilOp fail %{public}u zpass zfail %{public}u %{public}u", fail, zfail, zpass);
1640     glStencilOp(fail, zfail, zpass);
1641     return NVal::CreateNull(env).val_;
1642 }
1643 
StencilOpSeparate(napi_env env,napi_callback_info info)1644 napi_value WebGLRenderingContextBase::StencilOpSeparate(napi_env env, napi_callback_info info)
1645 {
1646     NFuncArg funcArg(env, info);
1647     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
1648         return NVal::CreateNull(env).val_;
1649     }
1650 
1651     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1652     if (context == nullptr) {
1653         return NVal::CreateNull(env).val_;
1654     }
1655 
1656     bool succ = false;
1657     GLenum face = 0;
1658     tie(succ, face) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1659     if (!succ) {
1660         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1661         return NVal::CreateNull(env).val_;
1662     }
1663 
1664     if (!CheckGLenum(env, funcArg.GetThisVar(), face, {
1665         WebGLRenderingContextBase::FRONT,
1666         WebGLRenderingContextBase::BACK,
1667         WebGLRenderingContextBase::FRONT_AND_BACK
1668     }, {})) {
1669         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
1670         return NVal::CreateNull(env).val_;
1671     }
1672 
1673     GLenum sfail = 0;
1674     tie(succ, sfail) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1675     if (!succ) {
1676         sfail = WebGLRenderingContextBase::KEEP;
1677     }
1678     GLenum dpfail = 0;
1679     tie(succ, dpfail) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
1680     if (!succ) {
1681         dpfail = WebGLRenderingContextBase::KEEP;
1682     }
1683     GLenum dppass = 0;
1684     tie(succ, dppass) = NVal(env, funcArg[NARG_POS::FOURTH]).ToGLenum();
1685     if (!succ) {
1686         dppass = WebGLRenderingContextBase::KEEP;
1687     }
1688     LOGD("WebGL stencilOpSeparate face %{public}u sfail %{public}u dpfail %{public}u dppass %{public}u",
1689         face, sfail, dpfail, dppass);
1690     glStencilOpSeparate(face, sfail, dpfail, dppass);
1691     return NVal::CreateNull(env).val_;
1692 }
1693 
TexParameterf(napi_env env,napi_callback_info info)1694 napi_value WebGLRenderingContextBase::TexParameterf(napi_env env, napi_callback_info info)
1695 {
1696     NFuncArg funcArg(env, info);
1697     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
1698         return NVal::CreateNull(env).val_;
1699     }
1700     bool succ = false;
1701     GLenum target = 0;
1702     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1703     if (!succ) {
1704         return NVal::CreateNull(env).val_;
1705     }
1706     GLenum pname = 0;
1707     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1708     if (!succ) {
1709         return NVal::CreateNull(env).val_;
1710     }
1711     double param = 0.0;
1712     tie(succ, param) = NVal(env, funcArg[NARG_POS::THIRD]).ToDouble();
1713     if (!succ) {
1714         return NVal::CreateNull(env).val_;
1715     }
1716     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1717     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1718         context->GetWebGLRenderingContextImpl().TexParameterf(env, target, pname, static_cast<GLfloat>(param));
1719 }
1720 
TexParameteri(napi_env env,napi_callback_info info)1721 napi_value WebGLRenderingContextBase::TexParameteri(napi_env env, napi_callback_info info)
1722 {
1723     NFuncArg funcArg(env, info);
1724     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
1725         return NVal::CreateNull(env).val_;
1726     }
1727     bool succ = false;
1728     GLenum target = 0;
1729     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
1730     if (!succ) {
1731         return NVal::CreateNull(env).val_;
1732     }
1733     GLenum pname = 0;
1734     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
1735     if (!succ) {
1736         return NVal::CreateNull(env).val_;
1737     }
1738     int32_t param = 0;
1739     tie(succ, param) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32();
1740     if (!succ) {
1741         return NVal::CreateNull(env).val_;
1742     }
1743     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1744     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1745         context->GetWebGLRenderingContextImpl().TexParameterf(env, target, pname, static_cast<GLint>(param));
1746 }
1747 
Uniform1f(napi_env env,napi_callback_info info)1748 napi_value WebGLRenderingContextBase::Uniform1f(napi_env env, napi_callback_info info)
1749 {
1750     NFuncArg funcArg(env, info);
1751     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1752         return NVal::CreateNull(env).val_;
1753     }
1754 
1755     bool succ = false;
1756     GLfloat data[4] = { 0 }; // max len 4
1757     tie(succ, data[0]) = NVal(env, funcArg[NARG_POS::SECOND]).ToFloat();
1758     if (!succ) {
1759         return NVal::CreateNull(env).val_;
1760     }
1761     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1762     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1763         context->GetWebGLRenderingContextImpl().UniformF(env, funcArg[NARG_POS::FIRST], 1, data);
1764 }
1765 
Uniform2f(napi_env env,napi_callback_info info)1766 napi_value WebGLRenderingContextBase::Uniform2f(napi_env env, napi_callback_info info)
1767 {
1768     NFuncArg funcArg(env, info);
1769     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
1770         return NVal::CreateNull(env).val_;
1771     }
1772 
1773     bool succ = false;
1774     const uint32_t count = 2; // 2 is 2x2
1775     GLfloat data[4] = {}; // max len 4
1776     for (size_t i = 0; i < count; i++) {
1777         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToFloat();
1778         if (!succ) {
1779             LOGE("WebGL uniform2f invalid arg");
1780             return NVal::CreateNull(env).val_;
1781         }
1782     }
1783     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1784     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1785         context->GetWebGLRenderingContextImpl().UniformF(env, funcArg[NARG_POS::FIRST], count, data);
1786 }
1787 
Uniform3f(napi_env env,napi_callback_info info)1788 napi_value WebGLRenderingContextBase::Uniform3f(napi_env env, napi_callback_info info)
1789 {
1790     NFuncArg funcArg(env, info);
1791     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
1792         return NVal::CreateNull(env).val_;
1793     }
1794 
1795     bool succ = false;
1796     const uint32_t count = 3; // 3 is 3x3
1797     GLfloat data[4] = {}; // max len 4
1798     for (size_t i = 0; i < count; i++) {
1799         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToFloat();
1800         if (!succ) {
1801             LOGE("WebGL uniform3f invalid arg");
1802             return NVal::CreateNull(env).val_;
1803         }
1804     }
1805     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1806     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1807         context->GetWebGLRenderingContextImpl().UniformF(env, funcArg[NARG_POS::FIRST], count, data);
1808 }
1809 
Uniform4f(napi_env env,napi_callback_info info)1810 napi_value WebGLRenderingContextBase::Uniform4f(napi_env env, napi_callback_info info)
1811 {
1812     NFuncArg funcArg(env, info);
1813     if (!funcArg.InitArgs(NARG_CNT::FIVE)) {
1814         return NVal::CreateNull(env).val_;
1815     }
1816 
1817     bool succ = false;
1818     const uint32_t count = 4; // 4 is 4x4
1819     GLfloat data[4] = {}; // max len 4
1820     for (size_t i = 0; i < count; i++) {
1821         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToFloat();
1822         if (!succ) {
1823             LOGE("WebGL uniform4f invalid arg");
1824             return NVal::CreateNull(env).val_;
1825         }
1826     }
1827     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1828     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1829         context->GetWebGLRenderingContextImpl().UniformF(env, funcArg[NARG_POS::FIRST], count, data);
1830 }
1831 
Uniform1i(napi_env env,napi_callback_info info)1832 napi_value WebGLRenderingContextBase::Uniform1i(napi_env env, napi_callback_info info)
1833 {
1834     NFuncArg funcArg(env, info);
1835     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1836         return NVal::CreateNull(env).val_;
1837     }
1838 
1839     bool succ = false;
1840     const uint32_t count = 1;
1841     GLint data[4] = {}; // max len 4
1842     for (size_t i = 0; i < count; i++) {
1843         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToInt32();
1844         if (!succ) {
1845             return NVal::CreateNull(env).val_;
1846         }
1847     }
1848     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1849     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1850         context->GetWebGLRenderingContextImpl().UniformI(env, funcArg[NARG_POS::FIRST], count, data);
1851 }
1852 
Uniform2i(napi_env env,napi_callback_info info)1853 napi_value WebGLRenderingContextBase::Uniform2i(napi_env env, napi_callback_info info)
1854 {
1855     NFuncArg funcArg(env, info);
1856     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
1857         return NVal::CreateNull(env).val_;
1858     }
1859 
1860     bool succ = false;
1861     const uint32_t count = 2; // 2 is 2x2
1862     GLint data[4] = {}; // max len 4
1863     for (size_t i = 0; i < count; i++) {
1864         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToInt32();
1865         if (!succ) {
1866             return NVal::CreateNull(env).val_;
1867         }
1868     }
1869     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1870     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1871         context->GetWebGLRenderingContextImpl().UniformI(env, funcArg[NARG_POS::FIRST], count, data);
1872 }
1873 
Uniform3i(napi_env env,napi_callback_info info)1874 napi_value WebGLRenderingContextBase::Uniform3i(napi_env env, napi_callback_info info)
1875 {
1876     NFuncArg funcArg(env, info);
1877     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
1878         return NVal::CreateNull(env).val_;
1879     }
1880 
1881     bool succ = false;
1882     const uint32_t count = 3; // 3 is 3x3
1883     GLint data[4] = {}; // max len 4
1884     for (size_t i = 0; i < count; i++) {
1885         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToInt32();
1886         if (!succ) {
1887             return NVal::CreateNull(env).val_;
1888         }
1889     }
1890     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1891     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1892         context->GetWebGLRenderingContextImpl().UniformI(env, funcArg[NARG_POS::FIRST], count, data);
1893 }
1894 
Uniform4i(napi_env env,napi_callback_info info)1895 napi_value WebGLRenderingContextBase::Uniform4i(napi_env env, napi_callback_info info)
1896 {
1897     NFuncArg funcArg(env, info);
1898     if (!funcArg.InitArgs(NARG_CNT::FIVE)) {
1899         return NVal::CreateNull(env).val_;
1900     }
1901 
1902     bool succ = false;
1903     const uint32_t count = 4; // 4 is 4x4
1904     GLint data[4] = {}; // max len 4
1905     for (size_t i = 0; i < count; i++) {
1906         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToInt32();
1907         if (!succ) {
1908             return NVal::CreateNull(env).val_;
1909         }
1910     }
1911     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1912     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1913         context->GetWebGLRenderingContextImpl().UniformI(env, funcArg[NARG_POS::FIRST], count, data);
1914 }
1915 
UseProgram(napi_env env,napi_callback_info info)1916 napi_value WebGLRenderingContextBase::UseProgram(napi_env env, napi_callback_info info)
1917 {
1918     NFuncArg funcArg(env, info);
1919     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1920         return NVal::CreateNull(env).val_;
1921     }
1922 
1923     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1924     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1925         context->GetWebGLRenderingContextImpl().UseProgram(env, funcArg[NARG_POS::FIRST]);
1926 }
1927 
ValidateProgram(napi_env env,napi_callback_info info)1928 napi_value WebGLRenderingContextBase::ValidateProgram(napi_env env, napi_callback_info info)
1929 {
1930     NFuncArg funcArg(env, info);
1931     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1932         return NVal::CreateNull(env).val_;
1933     }
1934 
1935     WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, funcArg[NARG_POS::FIRST]);
1936     if (webGLProgram == nullptr) {
1937         return NVal::CreateNull(env).val_;
1938     }
1939     uint32_t program = webGLProgram->GetProgramId();
1940     LOGD("WebGL validateProgram program %{public}u", program);
1941     glValidateProgram(static_cast<GLuint>(program));
1942     return NVal::CreateNull(env).val_;
1943 }
1944 
VertexAttrib1f(napi_env env,napi_callback_info info)1945 napi_value WebGLRenderingContextBase::VertexAttrib1f(napi_env env, napi_callback_info info)
1946 {
1947     NFuncArg funcArg(env, info);
1948     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
1949         return NVal::CreateNull(env).val_;
1950     }
1951 
1952     const int32_t count = 1;
1953     GLfloat data[count] = { 0 };
1954     GLuint index = 0;
1955     bool succ = false;
1956     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToUint32();
1957     if (!succ) {
1958         return NVal::CreateNull(env).val_;
1959     }
1960     for (int32_t i = 0; i < count; i++) {
1961         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToFloat();
1962         if (!succ) {
1963             return NVal::CreateNull(env).val_;
1964         }
1965     }
1966     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1967     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1968         context->GetWebGLRenderingContextImpl().VertexAttribf(env, index, count, data);
1969 }
1970 
VertexAttrib2f(napi_env env,napi_callback_info info)1971 napi_value WebGLRenderingContextBase::VertexAttrib2f(napi_env env, napi_callback_info info)
1972 {
1973     NFuncArg funcArg(env, info);
1974     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
1975         return NVal::CreateNull(env).val_;
1976     }
1977 
1978     const int32_t count = 2; // 2 is 2x2
1979     GLfloat data[count] = { 0 };
1980     GLuint index = 0;
1981     bool succ = false;
1982     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToUint32();
1983     if (!succ) {
1984         return NVal::CreateNull(env).val_;
1985     }
1986     for (int32_t i = 0; i < count; i++) {
1987         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToFloat();
1988         if (!succ) {
1989             return NVal::CreateNull(env).val_;
1990         }
1991     }
1992     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
1993     return (context == nullptr) ? NVal::CreateNull(env).val_ :
1994         context->GetWebGLRenderingContextImpl().VertexAttribf(env, index, count, data);
1995 }
1996 
VertexAttrib3f(napi_env env,napi_callback_info info)1997 napi_value WebGLRenderingContextBase::VertexAttrib3f(napi_env env, napi_callback_info info)
1998 {
1999     NFuncArg funcArg(env, info);
2000     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
2001         return NVal::CreateNull(env).val_;
2002     }
2003 
2004     const int32_t count = 3; // 3 is 3x3
2005     GLfloat data[count] = { 0 };
2006     GLuint index = 0;
2007     bool succ = false;
2008     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToUint32();
2009     if (!succ) {
2010         return NVal::CreateNull(env).val_;
2011     }
2012     for (int32_t i = 0; i < count; i++) {
2013         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToFloat();
2014         if (!succ) {
2015             return NVal::CreateNull(env).val_;
2016         }
2017     }
2018     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2019     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2020         context->GetWebGLRenderingContextImpl().VertexAttribf(env, index, count, data);
2021 }
2022 
VertexAttrib4f(napi_env env,napi_callback_info info)2023 napi_value WebGLRenderingContextBase::VertexAttrib4f(napi_env env, napi_callback_info info)
2024 {
2025     NFuncArg funcArg(env, info);
2026     if (!funcArg.InitArgs(NARG_CNT::FIVE)) {
2027         return NVal::CreateNull(env).val_;
2028     }
2029 
2030     const int32_t count = 4; // 4 is 4x4
2031     GLfloat data[count] = { 0 };
2032     GLuint index = 0;
2033     bool succ = false;
2034     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToUint32();
2035     if (!succ) {
2036         return NVal::CreateNull(env).val_;
2037     }
2038     for (int32_t i = 0; i < count; i++) {
2039         tie(succ, data[i]) = NVal(env, funcArg[i + NARG_POS::SECOND]).ToFloat();
2040         if (!succ) {
2041             return NVal::CreateNull(env).val_;
2042         }
2043     }
2044     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2045     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2046         context->GetWebGLRenderingContextImpl().VertexAttribf(env, index, count, data);
2047 }
2048 
VertexAttribPointer(napi_env env,napi_callback_info info)2049 napi_value WebGLRenderingContextBase::VertexAttribPointer(napi_env env, napi_callback_info info)
2050 {
2051     NFuncArg funcArg(env, info);
2052     if (!funcArg.InitArgs(NARG_CNT::SIX)) {
2053         return NVal::CreateNull(env).val_;
2054     }
2055 
2056     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2057     if (context == nullptr) {
2058         return NVal::CreateNull(env).val_;
2059     }
2060     bool succ = false;
2061     VertexAttribArg vertexInfo = { 0 };
2062     tie(succ, vertexInfo.index) = NVal(env, funcArg[NARG_POS::FIRST]).ToUint32();
2063     if (!succ) {
2064         return NVal::CreateNull(env).val_;
2065     }
2066     tie(succ, vertexInfo.size) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32();
2067     if (!succ) {
2068         return NVal::CreateNull(env).val_;
2069     }
2070     tie(succ, vertexInfo.type) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
2071     if (!succ) {
2072         return NVal::CreateNull(env).val_;
2073     }
2074     tie(succ, vertexInfo.normalized) = NVal(env, funcArg[NARG_POS::FOURTH]).ToBool();
2075     if (!succ) {
2076         return NVal::CreateNull(env).val_;
2077     }
2078     tie(succ, vertexInfo.stride) = NVal(env, funcArg[NARG_POS::FIFTH]).ToGLsizei();
2079     if (!succ) {
2080         return NVal::CreateNull(env).val_;
2081     }
2082     GLenum result;
2083     tie(result, vertexInfo.offset) = WebGLArg::ToGLintptr(env, funcArg[NARG_POS::SIXTH]);
2084     if (result) {
2085         context->GetWebGLRenderingContextImpl().SetError(result);
2086         return NVal::CreateNull(env).val_;
2087     }
2088     return context->GetWebGLRenderingContextImpl().VertexAttribPointer(env, vertexInfo);
2089 }
2090 
Viewport(napi_env env,napi_callback_info info)2091 napi_value WebGLRenderingContextBase::Viewport(napi_env env, napi_callback_info info)
2092 {
2093     NFuncArg funcArg(env, info);
2094     if (!funcArg.InitArgs(NARG_CNT::FOUR)) {
2095         return NVal::CreateNull(env).val_;
2096     }
2097 
2098     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2099     if (context == nullptr) {
2100         return NVal::CreateNull(env).val_;
2101     }
2102 
2103     bool succ = false;
2104     int32_t x = 0;
2105     tie(succ, x) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
2106     if (!succ) {
2107         return NVal::CreateNull(env).val_;
2108     }
2109     int32_t y = 0;
2110     tie(succ, y) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32();
2111     if (!succ) {
2112         return NVal::CreateNull(env).val_;
2113     }
2114     int64_t width = 0;
2115     tie(succ, width) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt64();
2116     if (!succ) {
2117         return NVal::CreateNull(env).val_;
2118     }
2119     int64_t height = 0;
2120     tie(succ, height) = NVal(env, funcArg[NARG_POS::FOURTH]).ToInt64();
2121     if (!succ) {
2122         return NVal::CreateNull(env).val_;
2123     }
2124     LOGD("webgl viewport x %{public}d y %{public}d width %{public}" PRIi64 " height %{public}" PRIi64,
2125         x, y, width, height);
2126     if (width < 0 || height < 0) {
2127         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_VALUE);
2128         return NVal::CreateNull(env).val_;
2129     }
2130     glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
2131     return NVal::CreateNull(env).val_;
2132 }
2133 
IsFramebuffer(napi_env env,napi_callback_info info)2134 napi_value WebGLRenderingContextBase::IsFramebuffer(napi_env env, napi_callback_info info)
2135 {
2136     NFuncArg funcArg(env, info);
2137     bool res = false;
2138     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2139         return NVal::CreateBool(env, res).val_;
2140     }
2141 
2142     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2143     return (context == nullptr) ? NVal::CreateBool(env, res).val_ :
2144         context->GetWebGLRenderingContextImpl().IsFrameBuffer(env, funcArg[NARG_POS::FIRST]);
2145 }
2146 
IsProgram(napi_env env,napi_callback_info info)2147 napi_value WebGLRenderingContextBase::IsProgram(napi_env env, napi_callback_info info)
2148 {
2149     NFuncArg funcArg(env, info);
2150     bool res = false;
2151     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2152         return NVal::CreateBool(env, res).val_;
2153     }
2154 
2155     WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, funcArg[NARG_POS::FIRST]);
2156     if (webGLProgram == nullptr) {
2157         return NVal::CreateBool(env, res).val_;
2158     }
2159     uint32_t program = webGLProgram->GetProgramId();
2160     res = static_cast<bool>(glIsProgram(static_cast<GLuint>(program)));
2161     LOGD("WebGL isProgram programId %{public}u res %{public}d", program, res);
2162     return NVal::CreateBool(env, res).val_;
2163 }
2164 
IsRenderbuffer(napi_env env,napi_callback_info info)2165 napi_value WebGLRenderingContextBase::IsRenderbuffer(napi_env env, napi_callback_info info)
2166 {
2167     NFuncArg funcArg(env, info);
2168     bool res = false;
2169     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2170         return NVal::CreateBool(env, res).val_;
2171     }
2172     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2173     if (context == nullptr) {
2174         return NVal::CreateBool(env, res).val_;
2175     }
2176     WebGLRenderbuffer* webGLRenderbuffer = context->GetWebGLRenderingContextImpl().GetValidRenderBuffer(
2177         env, funcArg[NARG_POS::FIRST]);
2178     if (webGLRenderbuffer == nullptr) {
2179         return NVal::CreateBool(env, res).val_;
2180     }
2181     uint32_t renderbuffer = webGLRenderbuffer->GetRenderbuffer();
2182     res = static_cast<bool>(glIsRenderbuffer(static_cast<GLuint>(renderbuffer)));
2183     LOGD("WebGL isRenderbuffer renderbuffer %{public}u res %{public}d", renderbuffer, res);
2184     return NVal::CreateBool(env, res).val_;
2185 }
2186 
IsShader(napi_env env,napi_callback_info info)2187 napi_value WebGLRenderingContextBase::IsShader(napi_env env, napi_callback_info info)
2188 {
2189     NFuncArg funcArg(env, info);
2190     bool res = false;
2191     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2192         return NVal::CreateBool(env, res).val_;
2193     }
2194 
2195     WebGLShader* webGLShader = WebGLShader::GetObjectInstance(env, funcArg[NARG_POS::FIRST]);
2196     if (webGLShader == nullptr) {
2197         LOGE("webGLShader is nullptr.");
2198         return NVal::CreateBool(env, res).val_;
2199     }
2200     uint32_t shaderId = webGLShader->GetShaderId();
2201     res = static_cast<bool>(glIsShader(static_cast<GLuint>(shaderId)));
2202     LOGD("WebGL isShader shaderId %{public}u res %{public}d", shaderId, res);
2203     return NVal::CreateBool(env, res).val_;
2204 }
2205 
IsTexture(napi_env env,napi_callback_info info)2206 napi_value WebGLRenderingContextBase::IsTexture(napi_env env, napi_callback_info info)
2207 {
2208     NFuncArg funcArg(env, info);
2209     bool res = false;
2210     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2211         return NVal::CreateBool(env, res).val_;
2212     }
2213 
2214     WebGLTexture* webGLTexture = WebGLTexture::GetObjectInstance(env, funcArg[NARG_POS::FIRST]);
2215     if (webGLTexture == nullptr) {
2216         return NVal::CreateBool(env, res).val_;
2217     }
2218     uint32_t texture = webGLTexture->GetTexture();
2219     res = static_cast<bool>(glIsTexture(static_cast<GLuint>(texture)));
2220     LOGD("WebGL isTexture texture %{public}u res %{public}d", texture, res);
2221     return NVal::CreateBool(env, res).val_;
2222 }
2223 
LineWidth(napi_env env,napi_callback_info info)2224 napi_value WebGLRenderingContextBase::LineWidth(napi_env env, napi_callback_info info)
2225 {
2226     NFuncArg funcArg(env, info);
2227     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2228         return NVal::CreateNull(env).val_;
2229     }
2230     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2231     if (context == nullptr) {
2232         return NVal::CreateNull(env).val_;
2233     }
2234 
2235     bool succ = false;
2236     double linewidth = 0.0;
2237     tie(succ, linewidth) = NVal(env, funcArg[NARG_POS::FIRST]).ToDouble();
2238     if (!succ) {
2239         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_VALUE);
2240         return NVal::CreateNull(env).val_;
2241     }
2242     LOGD("WebGL lineWidth linewidth %{public}f", linewidth);
2243     glLineWidth(static_cast<GLfloat>(linewidth));
2244     return NVal::CreateNull(env).val_;
2245 }
2246 
LinkProgram(napi_env env,napi_callback_info info)2247 napi_value WebGLRenderingContextBase::LinkProgram(napi_env env, napi_callback_info info)
2248 {
2249     NFuncArg funcArg(env, info);
2250     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2251         return NVal::CreateNull(env).val_;
2252     }
2253 
2254     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2255     if (context == nullptr) {
2256         return NVal::CreateNull(env).val_;
2257     }
2258     return context->GetWebGLRenderingContextImpl().LinkProgram(env, funcArg[NARG_POS::FIRST]);
2259 }
2260 
PixelStorei(napi_env env,napi_callback_info info)2261 napi_value WebGLRenderingContextBase::PixelStorei(napi_env env, napi_callback_info info)
2262 {
2263     NFuncArg funcArg(env, info);
2264     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2265         return NVal::CreateNull(env).val_;
2266     }
2267 
2268     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2269     if (context == nullptr) {
2270         return NVal::CreateNull(env).val_;
2271     }
2272     bool succ = false;
2273     GLenum pname = 0;
2274     tie(succ, pname) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2275     if (!succ) {
2276         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
2277         return NVal::CreateNull(env).val_;
2278     }
2279     GLint param = 0;
2280     bool isbool = NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_boolean);
2281     if (isbool) {
2282         bool parambool = false;
2283         tie(succ, parambool) = NVal(env, funcArg[NARG_POS::SECOND]).ToBool();
2284         if (!succ) {
2285             context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_VALUE);
2286             return NVal::CreateNull(env).val_;
2287         }
2288         param = parambool ? 1 : 0;
2289     } else {
2290         tie(succ, param) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32();
2291         if (!succ) {
2292             context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_VALUE);
2293             return NVal::CreateNull(env).val_;
2294         }
2295     }
2296     context->GetWebGLRenderingContextImpl().PixelStorei(env, pname, param);
2297     return NVal::CreateNull(env).val_;
2298 }
2299 
PolygonOffset(napi_env env,napi_callback_info info)2300 napi_value WebGLRenderingContextBase::PolygonOffset(napi_env env, napi_callback_info info)
2301 {
2302     NFuncArg funcArg(env, info);
2303 
2304     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2305         return NVal::CreateNull(env).val_;
2306     }
2307     bool succ = false;
2308     double factor = 0.0;
2309     tie(succ, factor) = NVal(env, funcArg[NARG_POS::FIRST]).ToDouble();
2310     if (!succ) {
2311         return NVal::CreateNull(env).val_;
2312     }
2313     double units = 0.0;
2314     tie(succ, units) = NVal(env, funcArg[NARG_POS::SECOND]).ToDouble();
2315     if (!succ) {
2316         return NVal::CreateNull(env).val_;
2317     }
2318     LOGD("WebGL polygonOffset factor %{public}f units %{public}f", factor, units);
2319     glPolygonOffset(static_cast<GLfloat>(factor), static_cast<GLfloat>(units));
2320     return NVal::CreateNull(env).val_;
2321 }
2322 
FrontFace(napi_env env,napi_callback_info info)2323 napi_value WebGLRenderingContextBase::FrontFace(napi_env env, napi_callback_info info)
2324 {
2325     NFuncArg funcArg(env, info);
2326     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2327         return NVal::CreateNull(env).val_;
2328     }
2329 
2330     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2331     if (context == nullptr) {
2332         return NVal::CreateNull(env).val_;
2333     }
2334     bool succ = false;
2335     GLenum mode = 0;
2336     tie(succ, mode) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2337     if (!succ) {
2338         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
2339         return NVal::CreateNull(env).val_;
2340     }
2341     LOGD("WebGL frontFace mode %{public}u", mode);
2342     switch (mode) {
2343         case WebGLRenderingContextBase::CW:
2344         case WebGLRenderingContextBase::CCW:
2345             break;
2346         default:
2347             context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
2348             return NVal::CreateNull(env).val_;
2349     }
2350     glFrontFace(mode);
2351     return NVal::CreateNull(env).val_;
2352 }
2353 
GenerateMipmap(napi_env env,napi_callback_info info)2354 napi_value WebGLRenderingContextBase::GenerateMipmap(napi_env env, napi_callback_info info)
2355 {
2356     NFuncArg funcArg(env, info);
2357     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2358         return NVal::CreateNull(env).val_;
2359     }
2360 
2361     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2362     if (context == nullptr) {
2363         return NVal::CreateNull(env).val_;
2364     }
2365     bool succ = false;
2366     GLenum target = 0;
2367     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2368     if (!succ) {
2369         return NVal::CreateNull(env).val_;
2370     }
2371     return context->GetWebGLRenderingContextImpl().GenerateMipmap(env, target);
2372 }
2373 
CreateWebGLActiveInfo(napi_env env,napi_callback_info info,void (* handleActiveInfo)(GLuint programId,GLuint index,GLint & size,GLenum & type,GLchar * name))2374 static napi_value CreateWebGLActiveInfo(napi_env env, napi_callback_info info,
2375     void (*handleActiveInfo)(GLuint programId, GLuint index, GLint& size, GLenum& type, GLchar* name))
2376 {
2377     NFuncArg funcArg(env, info);
2378     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2379         LOGE("WebGL getActiveAttrib invalid param");
2380         return NVal::CreateNull(env).val_;
2381     }
2382     bool succ = false;
2383     WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, funcArg[NARG_POS::FIRST]);
2384     if (webGLProgram == nullptr) {
2385         return NVal::CreateNull(env).val_;
2386     }
2387     uint32_t programId = webGLProgram->GetProgramId();
2388     int64_t index = 0;
2389     tie(succ, index) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt64();
2390     if (!succ) {
2391         return NVal::CreateNull(env).val_;
2392     }
2393     LOGD("WebGL CreateWebGLActiveInfo programId %{public}u index %{public}" PRIi64, programId, index);
2394     WebGLActiveInfo* webGLActiveInfo = nullptr;
2395     napi_value objActiveInfo = WebGLActiveInfo::CreateObjectInstance(env, &webGLActiveInfo).val_;
2396     if (webGLActiveInfo == nullptr) {
2397         return NVal::CreateNull(env).val_;
2398     }
2399     GLint size = 0;
2400     GLenum type = 0;
2401     GLchar name[WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH + 1] = { 0 };
2402     handleActiveInfo(static_cast<GLuint>(programId), static_cast<GLuint>(index), size, type, name);
2403     webGLActiveInfo->SetActiveName(name, WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH);
2404     webGLActiveInfo->SetActiveType(type);
2405     webGLActiveInfo->SetActiveSize(size);
2406     return objActiveInfo;
2407 }
2408 
GetActiveAttrib(napi_env env,napi_callback_info info)2409 napi_value WebGLRenderingContextBase::GetActiveAttrib(napi_env env, napi_callback_info info)
2410 {
2411     return CreateWebGLActiveInfo(
2412         env, info, [](GLuint programId, GLuint index, GLint& size, GLenum& type, GLchar* name) {
2413             GLsizei bufSize = WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH;
2414             GLsizei length;
2415             glGetActiveAttrib(programId, index, bufSize, &length, &size, &type, name);
2416             if (length > WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH) {
2417                 LOGE("WebGL: getActiveAttrib: error bufSize exceed!");
2418             }
2419             LOGD("WebGL getActiveAttrib %{public}s %{public}u %{public}d %{public}u", name, type, size, length);
2420         });
2421 }
2422 
GetActiveUniform(napi_env env,napi_callback_info info)2423 napi_value WebGLRenderingContextBase::GetActiveUniform(napi_env env, napi_callback_info info)
2424 {
2425     return CreateWebGLActiveInfo(
2426         env, info, [](GLuint programId, GLuint index, GLint& size, GLenum& type, GLchar* name) {
2427             GLsizei bufSize = WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH;
2428             GLsizei length;
2429             glGetActiveUniform(programId, index, bufSize, &length, &size, &type, name);
2430             if (length > WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH) {
2431                 LOGE("WebGL: getActiveUniform: error bufSize exceed!");
2432             }
2433             LOGD("WebGL GetActiveUniform %{public}s %{public}u %{public}d", name, type, size);
2434         });
2435 }
2436 
GetBufferParameter(napi_env env,napi_callback_info info)2437 napi_value WebGLRenderingContextBase::GetBufferParameter(napi_env env, napi_callback_info info)
2438 {
2439     NFuncArg funcArg(env, info);
2440     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2441         return NVal::CreateNull(env).val_;
2442     }
2443 
2444     bool succ = false;
2445     GLenum target = 0;
2446     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2447     if (!succ) {
2448         return NVal::CreateNull(env).val_;
2449     }
2450     GLenum pname = 0;
2451     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
2452     if (!succ) {
2453         return NVal::CreateNull(env).val_;
2454     }
2455     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2456     return (context == nullptr) ? NVal::CreateInt64(env, WebGLRenderingContextBase::INVALID_OPERATION).val_ :
2457         context->GetWebGLRenderingContextImpl().GetBufferParameter(env, target, pname);
2458 }
2459 
GetError(napi_env env,napi_callback_info info)2460 napi_value WebGLRenderingContextBase::GetError(napi_env env, napi_callback_info info)
2461 {
2462     NFuncArg funcArg(env, info);
2463     funcArg.InitArgs(NARG_CNT::ZERO);
2464     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2465     return (context == nullptr) ? NVal::CreateInt64(env, WebGLRenderingContextBase::INVALID_OPERATION).val_ :
2466         context->GetWebGLRenderingContextImpl().GetError(env);
2467 }
2468 
GetFramebufferAttachmentParameter(napi_env env,napi_callback_info info)2469 napi_value WebGLRenderingContextBase::GetFramebufferAttachmentParameter(napi_env env, napi_callback_info info)
2470 {
2471     NFuncArg funcArg(env, info);
2472     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
2473         return NVal::CreateNull(env).val_;
2474     }
2475 
2476     bool succ = false;
2477     GLenum target = 0;
2478     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2479     if (!succ) {
2480         return NVal::CreateNull(env).val_;
2481     }
2482     GLenum attachment = 0;
2483     tie(succ, attachment) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
2484     if (!succ) {
2485         return NVal::CreateNull(env).val_;
2486     }
2487     GLenum pname = 0;
2488     tie(succ, pname) = NVal(env, funcArg[NARG_POS::THIRD]).ToGLenum();
2489     if (!succ) {
2490         return NVal::CreateNull(env).val_;
2491     }
2492 
2493     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2494     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2495         context->GetWebGLRenderingContextImpl().GetFrameBufferAttachmentParameter(env, target, attachment, pname);
2496 }
2497 
GetProgramParameter(napi_env env,napi_callback_info info)2498 napi_value WebGLRenderingContextBase::GetProgramParameter(napi_env env, napi_callback_info info)
2499 {
2500     NFuncArg funcArg(env, info);
2501     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2502         return NVal::CreateNull(env).val_;
2503     }
2504 
2505     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2506     if (context == nullptr) {
2507         return NVal::CreateNull(env).val_;
2508     }
2509     bool succ = false;
2510     GLenum pname = 0;
2511     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
2512     return !succ ? NVal::CreateNull(env).val_ :
2513         context->GetWebGLRenderingContextImpl().GetProgramParameter(env, funcArg[NARG_POS::FIRST], pname);
2514 }
2515 
GetRenderbufferParameter(napi_env env,napi_callback_info info)2516 napi_value WebGLRenderingContextBase::GetRenderbufferParameter(napi_env env, napi_callback_info info)
2517 {
2518     NFuncArg funcArg(env, info);
2519     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2520         return NVal::CreateNull(env).val_;
2521     }
2522     bool succ = false;
2523     GLenum target = 0;
2524     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2525     if (!succ) {
2526         return NVal::CreateNull(env).val_;
2527     }
2528     GLenum pname = 0;
2529     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
2530     if (!succ) {
2531         return NVal::CreateNull(env).val_;
2532     }
2533     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2534     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2535         context->GetWebGLRenderingContextImpl().GetRenderBufferParameter(env, target, pname);
2536 }
2537 
GetTexParameter(napi_env env,napi_callback_info info)2538 napi_value WebGLRenderingContextBase::GetTexParameter(napi_env env, napi_callback_info info)
2539 {
2540     NFuncArg funcArg(env, info);
2541     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2542         return NVal::CreateNull(env).val_;
2543     }
2544     bool succ = false;
2545     GLenum target = 0;
2546     tie(succ, target) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2547     if (!succ) {
2548         return NVal::CreateNull(env).val_;
2549     }
2550     LOGD("WebGL getTexParameter target %{public}u", target);
2551     GLenum pname = 0;
2552     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
2553     if (!succ) {
2554         return NVal::CreateNull(env).val_;
2555     }
2556     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2557     if (context == nullptr) {
2558         return NVal::CreateNull(env).val_;
2559     }
2560     return context->GetWebGLRenderingContextImpl().GetTexParameter(env, target, pname);
2561 }
2562 
GetShaderParameter(napi_env env,napi_callback_info info)2563 napi_value WebGLRenderingContextBase::GetShaderParameter(napi_env env, napi_callback_info info)
2564 {
2565     NFuncArg funcArg(env, info);
2566     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2567         return NVal::CreateNull(env).val_;
2568     }
2569     bool succ = false;
2570     GLenum pname = 0;
2571     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2572     if (context == nullptr) {
2573         return NVal::CreateNull(env).val_;
2574     }
2575     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
2576     if (!succ) {
2577         context->GetWebGLRenderingContextImpl().SetError(WebGLRenderingContextBase::INVALID_ENUM);
2578         return NVal::CreateNull(env).val_;
2579     }
2580     return context->GetWebGLRenderingContextImpl().GetShaderParameter(env, funcArg[NARG_POS::FIRST], pname);
2581 }
2582 
GetAttribLocation(napi_env env,napi_callback_info info)2583 napi_value WebGLRenderingContextBase::GetAttribLocation(napi_env env, napi_callback_info info)
2584 {
2585     NFuncArg funcArg(env, info);
2586     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2587         return NVal::CreateInt64(env, -1).val_;
2588     }
2589 
2590     bool succ = false;
2591     unique_ptr<char[]> name = nullptr;
2592     size_t size = 0;
2593     tie(succ, name, size) = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String();
2594     if (!succ) {
2595         return NVal::CreateInt64(env, -1).val_;
2596     }
2597     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2598     if (context == nullptr) {
2599         return NVal::CreateNull(env).val_;
2600     }
2601     std::string str(name.get(), size);
2602     return context->GetWebGLRenderingContextImpl().GetAttribLocation(env, funcArg[NARG_POS::FIRST], str);
2603 }
2604 
VertexAttrib1fv(napi_env env,napi_callback_info info)2605 napi_value WebGLRenderingContextBase::VertexAttrib1fv(napi_env env, napi_callback_info info)
2606 {
2607     NFuncArg funcArg(env, info);
2608     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2609         return NVal::CreateNull(env).val_;
2610     }
2611 
2612     bool succ = false;
2613     int64_t index = 0;
2614     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt64();
2615     if (!succ) {
2616         return NVal::CreateNull(env).val_;
2617     }
2618     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2619     if (context == nullptr) {
2620         return NVal::CreateNull(env).val_;
2621     }
2622     return context->GetWebGLRenderingContextImpl().VertexAttribfv(env, index, 1, funcArg[NARG_POS::SECOND]);
2623 }
2624 
VertexAttrib2fv(napi_env env,napi_callback_info info)2625 napi_value WebGLRenderingContextBase::VertexAttrib2fv(napi_env env, napi_callback_info info)
2626 {
2627     NFuncArg funcArg(env, info);
2628     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2629         return NVal::CreateNull(env).val_;
2630     }
2631 
2632     bool succ = false;
2633     int64_t index = 0;
2634     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt64();
2635     if (!succ) {
2636         return NVal::CreateNull(env).val_;
2637     }
2638     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2639     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2640         context->GetWebGLRenderingContextImpl().VertexAttribfv(env, index, 2, funcArg[NARG_POS::SECOND]); // 2 count
2641 }
2642 
VertexAttrib3fv(napi_env env,napi_callback_info info)2643 napi_value WebGLRenderingContextBase::VertexAttrib3fv(napi_env env, napi_callback_info info)
2644 {
2645     NFuncArg funcArg(env, info);
2646     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2647         return NVal::CreateNull(env).val_;
2648     }
2649 
2650     bool succ = false;
2651     int64_t index = 0;
2652     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt64();
2653     if (!succ) {
2654         return NVal::CreateNull(env).val_;
2655     }
2656     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2657     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2658         context->GetWebGLRenderingContextImpl().VertexAttribfv(env, index, 3, funcArg[NARG_POS::SECOND]); // 3 count
2659 }
2660 
VertexAttrib4fv(napi_env env,napi_callback_info info)2661 napi_value WebGLRenderingContextBase::VertexAttrib4fv(napi_env env, napi_callback_info info)
2662 {
2663     NFuncArg funcArg(env, info);
2664     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2665         return NVal::CreateNull(env).val_;
2666     }
2667 
2668     bool succ = false;
2669     int64_t index = 0;
2670     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt64();
2671     if (!succ) {
2672         return NVal::CreateNull(env).val_;
2673     }
2674     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2675     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2676         context->GetWebGLRenderingContextImpl().VertexAttribfv(env, index, 4, funcArg[NARG_POS::SECOND]); // 4 count
2677 }
2678 
GetVertexAttrib(napi_env env,napi_callback_info info)2679 napi_value WebGLRenderingContextBase::GetVertexAttrib(napi_env env, napi_callback_info info)
2680 {
2681     NFuncArg funcArg(env, info);
2682     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2683         return NVal::CreateNull(env).val_;
2684     }
2685     bool succ = false;
2686     GLuint index = 0;
2687     tie(succ, index) = NVal(env, funcArg[NARG_POS::FIRST]).ToUint32();
2688     if (!succ) {
2689         return NVal::CreateNull(env).val_;
2690     }
2691     GLenum pname = 0;
2692     tie(succ, pname) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
2693     if (!succ) {
2694         return NVal::CreateNull(env).val_;
2695     }
2696     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2697     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2698         context->GetWebGLRenderingContextImpl().GetVertexAttrib(env, pname, index);
2699 }
2700 
GetParameter(napi_env env,napi_callback_info info)2701 napi_value WebGLRenderingContextBase::GetParameter(napi_env env, napi_callback_info info)
2702 {
2703     NFuncArg funcArg(env, info);
2704     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2705         return NVal::CreateNull(env).val_;
2706     }
2707     bool succ = false;
2708     GLenum pname = 0;
2709     tie(succ, pname) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2710     if (!succ) {
2711         return NVal::CreateNull(env).val_;
2712     }
2713     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2714     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2715         context->GetWebGLRenderingContextImpl().GetParameter(env, pname);
2716 }
2717 
GetAttachedShaders(napi_env env,napi_callback_info info)2718 napi_value WebGLRenderingContextBase::GetAttachedShaders(napi_env env, napi_callback_info info)
2719 {
2720     NFuncArg funcArg(env, info);
2721     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2722         return NVal::CreateNull(env).val_;
2723     }
2724 
2725     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2726     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2727         context->GetWebGLRenderingContextImpl().GetAttachedShaders(env, funcArg[NARG_POS::FIRST]);
2728 }
2729 
GetShaderPrecisionFormat(napi_env env,napi_callback_info info)2730 napi_value WebGLRenderingContextBase::GetShaderPrecisionFormat(napi_env env, napi_callback_info info)
2731 {
2732     NFuncArg funcArg(env, info);
2733     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2734         return NVal::CreateNull(env).val_;
2735     }
2736 
2737     bool succ = false;
2738     GLenum shaderType = 0;
2739     tie(succ, shaderType) = NVal(env, funcArg[NARG_POS::FIRST]).ToGLenum();
2740     if (!succ) {
2741         return NVal::CreateNull(env).val_;
2742     }
2743     LOGD("WebGL getShaderPrecisionFormat shaderType %{public}u", shaderType);
2744     GLenum precisionType;
2745     tie(succ, precisionType) = NVal(env, funcArg[NARG_POS::SECOND]).ToGLenum();
2746     if (!succ) {
2747         return NVal::CreateNull(env).val_;
2748     }
2749     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2750     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2751         context->GetWebGLRenderingContextImpl().GetShaderPrecisionFormat(env, shaderType, precisionType);
2752 }
2753 
GetShaderInfoLog(napi_env env,napi_callback_info info)2754 napi_value WebGLRenderingContextBase::GetShaderInfoLog(napi_env env, napi_callback_info info)
2755 {
2756     NFuncArg funcArg(env, info);
2757     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2758         return NVal::CreateUTF8String(env, "").val_;
2759     }
2760     WebGLShader* webGlShader = WebGLShader::GetObjectInstance(env, funcArg[NARG_POS::FIRST]);
2761     if (webGlShader == nullptr) {
2762         return NVal::CreateUTF8String(env, "").val_;
2763     }
2764     GLuint shaderId = webGlShader->GetShaderId();
2765     GLint length = 0;
2766     glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);
2767     if (length == 0) {
2768         return NVal::CreateUTF8String(env, "").val_;
2769     }
2770     GLsizei size = 0;
2771     std::unique_ptr<char[]> buf = std::make_unique<char[]>(length + 1);
2772     if (buf == nullptr) {
2773         return NVal::CreateUTF8String(env, "").val_;
2774     }
2775     glGetShaderInfoLog(shaderId, length, &size, buf.get());
2776     if (size >= length) {
2777         return NVal::CreateUTF8String(env, "").val_;
2778     }
2779     string str = buf.get();
2780     LOGD("WebGL getShaderInfoLog shaderId %{public}u length %{public}d %{public}zu %{public}s",
2781         shaderId, length, str.size(), str.c_str());
2782     return NVal::CreateUTF8String(env, str).val_;
2783 }
2784 
GetProgramInfoLog(napi_env env,napi_callback_info info)2785 napi_value WebGLRenderingContextBase::GetProgramInfoLog(napi_env env, napi_callback_info info)
2786 {
2787     NFuncArg funcArg(env, info);
2788     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2789         return NVal::CreateUTF8String(env, "").val_;
2790     }
2791     WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, funcArg[NARG_POS::FIRST]);
2792     if (webGLProgram == nullptr) {
2793         return NVal::CreateUTF8String(env, "").val_;
2794     }
2795 
2796     GLuint programId = webGLProgram->GetProgramId();
2797     GLint length = 0;
2798     GLsizei size = 0;
2799     glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &length);
2800     if (length == 0) {
2801         return NVal::CreateUTF8String(env, "").val_;
2802     }
2803     std::unique_ptr<char[]> buf = std::make_unique<char[]>(length + 1);
2804     if (buf == nullptr) {
2805         return NVal::CreateUTF8String(env, "").val_;
2806     }
2807     glGetProgramInfoLog(programId, length, &size, buf.get());
2808     if (size >= length) {
2809         return NVal::CreateUTF8String(env, "").val_;
2810     }
2811     string str = buf.get();
2812     LOGD("WebGL getProgramInfoLog programId %{public}u length %{public}d %{public}zu %{public}s",
2813         programId, length, str.size(), str.c_str());
2814     return NVal::CreateUTF8String(env, str).val_;
2815 }
2816 
GetShaderSource(napi_env env,napi_callback_info info)2817 napi_value WebGLRenderingContextBase::GetShaderSource(napi_env env, napi_callback_info info)
2818 {
2819     NFuncArg funcArg(env, info);
2820     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
2821         return NVal::CreateUTF8String(env, "").val_;
2822     }
2823 
2824     WebGLShader* webGlShader = WebGLShader::GetObjectInstance(env, funcArg[NARG_POS::FIRST]);
2825     if (webGlShader == nullptr) {
2826         return NVal::CreateUTF8String(env, "").val_;
2827     }
2828     uint32_t shaderId = webGlShader->GetShaderId();
2829     LOGD("WebGL getShaderSource shaderId %{public}u", shaderId);
2830     return NVal::CreateUTF8String(env, webGlShader->GetShaderRes()).val_;
2831 }
2832 
GetUniform(napi_env env,napi_callback_info info)2833 napi_value WebGLRenderingContextBase::GetUniform(napi_env env, napi_callback_info info)
2834 {
2835     NFuncArg funcArg(env, info);
2836     if (!funcArg.InitArgs(NARG_CNT::TWO)) {
2837         return NVal::CreateNull(env).val_;
2838     }
2839 
2840     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2841     return (context == nullptr) ? NVal::CreateNull(env).val_ :
2842         context->GetWebGLRenderingContextImpl().GetUniform(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]);
2843 }
2844 
GetDrawingBufferWidth(napi_env env,napi_callback_info info)2845 napi_value WebGLRenderingContextBase::GetDrawingBufferWidth(napi_env env, napi_callback_info info)
2846 {
2847     NFuncArg funcArg(env, info);
2848     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
2849         return NVal::CreateInt64(env, 0).val_;
2850     }
2851     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2852     return (context == nullptr) ? NVal::CreateInt64(env, 0).val_ :
2853         NVal::CreateInt64(env, context->GetBufferWidth()).val_;
2854 }
2855 
GetDrawingBufferHeight(napi_env env,napi_callback_info info)2856 napi_value WebGLRenderingContextBase::GetDrawingBufferHeight(napi_env env, napi_callback_info info)
2857 {
2858     NFuncArg funcArg(env, info);
2859     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
2860         return NVal::CreateInt64(env, 0).val_;
2861     }
2862     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, funcArg.GetThisVar());
2863     return (context == nullptr) ? NVal::CreateInt64(env, 0).val_ :
2864         NVal::CreateInt64(env, context->GetBufferHeight()).val_;
2865 }
2866 
SetError(napi_env env,napi_value thisVar,GLenum error,std::string func,int32_t line)2867 void WebGLRenderingContextBase::SetError(napi_env env, napi_value thisVar, GLenum error, std::string func, int32_t line)
2868 {
2869     WebGLRenderingContext* context = GetWebGLRenderingContextBase(env, thisVar);
2870     if (context == nullptr) {
2871         return;
2872     }
2873     GLenum err = glGetError();
2874     if (err != GL_NO_ERROR) {
2875         LOGE("SetError last error %{public}u", err);
2876     }
2877     LOGE("Set error %{public}u for %{public}s:%{public}d ", error, func.c_str(), line);
2878     context->GetWebGLRenderingContextImpl().SetError(error);
2879 }
2880 } // namespace Rosen
2881 } // namespace OHOS
2882 #ifdef __cplusplus
2883 }
2884 #endif
2885