1 /*
2 * Copyright (c) 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 #include "context/webgl2_rendering_context_impl.h"
16
17 #include "context/webgl2_rendering_context_base.h"
18 #include "context/webgl_context_attributes.h"
19 #include "context/webgl_rendering_context.h"
20 #include "context/webgl_rendering_context_base.h"
21 #include "context/webgl_rendering_context_basic_base.h"
22 #include "napi/n_class.h"
23 #include "napi/n_func_arg.h"
24 #include "util/egl_manager.h"
25 #include "util/log.h"
26 #include "util/util.h"
27 #include "webgl/webgl_query.h"
28 #include "webgl/webgl_sampler.h"
29 #include "webgl/webgl_shader.h"
30 #include "webgl/webgl_sync.h"
31 #include "webgl/webgl_transform_feedback.h"
32 #include "webgl/webgl_vertex_array_object.h"
33
34 namespace OHOS {
35 namespace Rosen {
36 namespace Impl {
37 using namespace std;
Init()38 void WebGL2RenderingContextImpl::Init()
39 {
40 WebGLRenderingContextBaseImpl::Init();
41 if (maxSamplerUnit_) {
42 return;
43 }
44 GLint max = 0;
45 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max);
46 maxSamplerUnit_ = static_cast<GLuint>(max);
47 samplerUnits_.resize(max);
48
49 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max);
50 maxBoundTransformFeedbackBufferIndex_ = static_cast<GLuint>(max);
51 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max);
52 maxBoundUniformBufferIndex_ = static_cast<GLuint>(max);
53 LOGD("WebGL2 Init maxBoundTransformFeedbackBufferIndex_ %{public}u, maxBoundUniformBufferIndex_ %{public}u"
54 "maxSamplerUnit_ %{public}d",
55 maxBoundTransformFeedbackBufferIndex_, maxBoundUniformBufferIndex_, max);
56 }
57
CreateQuery(napi_env env)58 napi_value WebGL2RenderingContextImpl::CreateQuery(napi_env env)
59 {
60 WebGLQuery* webGlQuery = nullptr;
61 napi_value objQuery = WebGLQuery::CreateObjectInstance(env, &webGlQuery).val_;
62 if (webGlQuery == nullptr) {
63 return NVal::CreateNull(env).val_;
64 }
65
66 uint32_t queryId = 0;
67 glGenQueries(1, &queryId);
68 webGlQuery->SetQuery(queryId);
69 AddObject<WebGLQuery>(env, queryId, objQuery);
70 LOGD("WebGL2 createQuery queryId = %{public}u", queryId);
71 return objQuery;
72 }
73
DeleteQuery(napi_env env,napi_value object)74 napi_value WebGL2RenderingContextImpl::DeleteQuery(napi_env env, napi_value object)
75 {
76 uint32_t queryId = 0;
77 WebGLQuery* webGlQuery = WebGLObject::GetObjectInstance<WebGLQuery>(env, object);
78 if (webGlQuery == nullptr) {
79 return NVal::CreateNull(env).val_;
80 }
81 queryId = webGlQuery->GetQuery();
82 glDeleteQueries(1, &queryId);
83 DeleteObject<WebGLQuery>(env, queryId);
84 uint32_t index = 0;
85 LOGD("WebGL2 deleteQuery target %{public}u, queryId %{public}u", webGlQuery->GetTarget(), queryId);
86 if (CheckQueryTarget(env, webGlQuery->GetTarget(), index)) {
87 LOGD("WebGL2 deleteQuery currentQuery_ %{public}u", currentQuery_[index]);
88 if (currentQuery_[index] == queryId) {
89 currentQuery_[index] = 0;
90 glEndQuery(webGlQuery->GetTarget());
91 }
92 }
93 return NVal::CreateNull(env).val_;
94 }
95
IsQuery(napi_env env,napi_value object)96 napi_value WebGL2RenderingContextImpl::IsQuery(napi_env env, napi_value object)
97 {
98 GLuint queryId = 0;
99 WebGLQuery* webGlQuery = WebGLObject::GetObjectInstance<WebGLQuery>(env, object);
100 if (webGlQuery == nullptr) {
101 return NVal::CreateBool(env, false).val_;
102 }
103 queryId = webGlQuery->GetQuery();
104
105 GLboolean returnValue = glIsQuery(queryId);
106 bool res = static_cast<bool>(returnValue);
107 LOGD("WebGL2 isQuery query %{public}u result %{public}d ", queryId, res);
108 return NVal::CreateBool(env, res).val_;
109 }
110
GetQuery(napi_env env,GLenum target,GLenum pName)111 napi_value WebGL2RenderingContextImpl::GetQuery(napi_env env, GLenum target, GLenum pName)
112 {
113 LOGD("WebGL2 getQuery target %{public}u %{public}u", target, pName);
114 if (pName != WebGL2RenderingContextBase::CURRENT_QUERY) {
115 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "pName %{public}u", pName);
116 return NVal::CreateNull(env).val_;
117 }
118 uint32_t index = 0;
119 if (!CheckQueryTarget(env, target, index)) {
120 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckQueryTarget failed");
121 return NVal::CreateNull(env).val_;
122 }
123
124 GLint params = 0;
125 glGetQueryiv(target, pName, ¶ms);
126 LOGD("WebGL2 getQuery params = %{public}d %{public}u", params, currentQuery_[index]);
127 return GetObject<WebGLQuery>(env, params);
128 }
129
BeginQuery(napi_env env,GLenum target,napi_value object)130 napi_value WebGL2RenderingContextImpl::BeginQuery(napi_env env, GLenum target, napi_value object)
131 {
132 LOGD("WebGL2 beginQuery target %{public}u", target);
133 GLuint queryId = 0;
134 WebGLQuery* webGlQuery = WebGLObject::GetObjectInstance<WebGLQuery>(env, object);
135 if (webGlQuery == nullptr) {
136 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "webGlQuery is nullptr");
137 return NVal::CreateNull(env).val_;
138 }
139 queryId = webGlQuery->GetQuery();
140
141 if (webGlQuery->GetTarget() && webGlQuery->GetTarget() != target) {
142 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION,
143 "webGlQuery->GetTarget %{public}u target %{public}u", webGlQuery->GetTarget(), target);
144 return NVal::CreateNull(env).val_;
145 }
146 uint32_t index = 0;
147 if (!CheckQueryTarget(env, target, index)) {
148 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckQueryTarget failed");
149 return NVal::CreateNull(env).val_;
150 }
151
152 if (currentQuery_[index] && currentQuery_[index] != queryId) {
153 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION,
154 "currentQuery_[index] %{public}u queryId %{public}u", currentQuery_[index], queryId);
155 return NVal::CreateNull(env).val_;
156 }
157 currentQuery_[index] = queryId;
158 webGlQuery->SetTarget(target);
159
160 glBeginQuery(target, queryId);
161 LOGD("WebGL2 beginQuery queryId %{public}u result %{public}u", queryId, GetError_());
162 return NVal::CreateNull(env).val_;
163 }
164
EndQuery(napi_env env,GLenum target)165 napi_value WebGL2RenderingContextImpl::EndQuery(napi_env env, GLenum target)
166 {
167 LOGD("WebGL2 endQuery target %{public}u", target);
168 uint32_t index = 0;
169 if (!CheckQueryTarget(env, target, index)) {
170 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
171 return NVal::CreateNull(env).val_;
172 }
173 if (!currentQuery_[index]) {
174 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
175 return NVal::CreateNull(env).val_;
176 }
177 currentQuery_[index] = 0;
178 glEndQuery(target);
179 return NVal::CreateNull(env).val_;
180 }
181
GetQueryParameter(napi_env env,napi_value queryObj,GLenum pName)182 napi_value WebGL2RenderingContextImpl::GetQueryParameter(napi_env env, napi_value queryObj, GLenum pName)
183 {
184 GLuint queryId = 0;
185 WebGLQuery* webGlQuery = WebGLObject::GetObjectInstance<WebGLQuery>(env, queryObj);
186 if (webGlQuery == nullptr) {
187 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
188 return NVal::CreateNull(env).val_;
189 }
190 queryId = webGlQuery->GetQuery();
191
192 GLuint params = 0;
193 switch (pName) {
194 case GL_QUERY_RESULT: {
195 glGetQueryObjectuiv(queryId, pName, ¶ms);
196 int64_t res = static_cast<int64_t>(params);
197 LOGD("WebGL2 getQueryParameter params %{public}u", params);
198 return NVal::CreateInt64(env, res).val_;
199 }
200 case GL_QUERY_RESULT_AVAILABLE: {
201 glGetQueryObjectuiv(queryId, pName, ¶ms);
202 bool res = (params == GL_FALSE) ? false : true;
203 LOGD("WebGL2 getQueryParameter params %{public}u", params);
204 return NVal::CreateBool(env, res).val_;
205 }
206 default : {
207 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
208 return NVal::CreateNull(env).val_;
209 }
210 }
211 }
212
CreateSampler(napi_env env)213 napi_value WebGL2RenderingContextImpl::CreateSampler(napi_env env)
214 {
215 WebGLSampler* webGlSampler = nullptr;
216 napi_value objSampler = WebGLSampler::CreateObjectInstance(env, &webGlSampler).val_;
217 if (webGlSampler == nullptr) {
218 return NVal::CreateNull(env).val_;
219 }
220 GLuint samplerId = 0;
221 glGenSamplers(1, &samplerId);
222 webGlSampler->SetSampler(samplerId);
223 LOGD("WebGL2 createSampler samplerId = %{public}u", samplerId);
224 AddObject<WebGLSampler>(env, samplerId, objSampler);
225 return objSampler;
226 }
227
DeleteSampler(napi_env env,napi_value samplerObj)228 napi_value WebGL2RenderingContextImpl::DeleteSampler(napi_env env, napi_value samplerObj)
229 {
230 WebGLSampler* sampler = WebGLObject::GetObjectInstance<WebGLSampler>(env, samplerObj);
231 if (sampler == nullptr) {
232 return NVal::CreateNull(env).val_;
233 }
234 GLuint samplerId = sampler->GetSampler();
235 LOGD("WebGL2 deleteSampler samplerId = %{public}u", samplerId);
236 // delete
237 glBindSampler(sampler->GetSampleUnit(), 0);
238
239 samplerUnits_[sampler->GetSampleUnit()] = 0;
240 glDeleteSamplers(1, &samplerId);
241 sampler->SetSampleUnit(0);
242 DeleteObject<WebGLSampler>(env, samplerId);
243 return NVal::CreateNull(env).val_;
244 }
245
IsSampler(napi_env env,napi_value samplerObj)246 napi_value WebGL2RenderingContextImpl::IsSampler(napi_env env, napi_value samplerObj)
247 {
248 WebGLSampler* sampler = WebGLObject::GetObjectInstance<WebGLSampler>(env, samplerObj);
249 if (sampler == nullptr) {
250 return NVal::CreateBool(env, false).val_;
251 }
252 GLuint samplerId = sampler->GetSampler();
253
254 GLboolean returnValue = glIsSampler(samplerId);
255 bool res = static_cast<bool>(returnValue);
256 LOGD("WebGL2 IsSampler samplerId = %{public}u res %{public}d", samplerId, res);
257 return NVal::CreateBool(env, res).val_;
258 }
259
BindSampler(napi_env env,GLuint unit,napi_value samplerObj)260 napi_value WebGL2RenderingContextImpl::BindSampler(napi_env env, GLuint unit, napi_value samplerObj)
261 {
262 WebGLSampler* sampler = WebGLObject::GetObjectInstance<WebGLSampler>(env, samplerObj);
263 if (sampler == nullptr) {
264 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
265 return NVal::CreateNull(env).val_;
266 }
267 GLuint samplerId = sampler->GetSampler();
268 if (unit >= samplerUnits_.size()) {
269 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
270 return NVal::CreateNull(env).val_;
271 }
272 sampler->SetSampleUnit(unit);
273 glBindSampler(unit, samplerId);
274 samplerUnits_[unit] = samplerId;
275 LOGD("WebGL2 bindSampler unit = %{public}u samplerId = %{public}u", unit, samplerId);
276 return NVal::CreateNull(env).val_;
277 }
278
SamplerParameter(napi_env env,napi_value samplerObj,GLenum pName,bool isFloat,void * param)279 napi_value WebGL2RenderingContextImpl::SamplerParameter(
280 napi_env env, napi_value samplerObj, GLenum pName, bool isFloat, void* param)
281 {
282 LOGD("WebGL2 samplerParameteri pname %{public}u", pName);
283 WebGLSampler* sampler = WebGLObject::GetObjectInstance<WebGLSampler>(env, samplerObj);
284 if (sampler == nullptr) {
285 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
286 return NVal::CreateNull(env).val_;
287 }
288 GLuint samplerId = sampler->GetSampler();
289 switch (pName) {
290 case GL_TEXTURE_COMPARE_FUNC:
291 case GL_TEXTURE_COMPARE_MODE:
292 case GL_TEXTURE_MAG_FILTER:
293 case GL_TEXTURE_MIN_FILTER:
294 case GL_TEXTURE_WRAP_R:
295 case GL_TEXTURE_WRAP_S:
296 case GL_TEXTURE_WRAP_T:
297 case GL_TEXTURE_MAX_LOD:
298 case GL_TEXTURE_MIN_LOD:
299 break;
300 default:
301 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
302 return NVal::CreateNull(env).val_;
303 }
304 if (isFloat) {
305 GLfloat v = *static_cast<GLfloat*>(param);
306 glSamplerParameterf(samplerId, pName, v);
307 } else {
308 GLint v = *static_cast<GLint*>(param);
309 glSamplerParameteri(samplerId, pName, v);
310 }
311 return NVal::CreateNull(env).val_;
312 }
313
GetSamplerParameter(napi_env env,napi_value samplerObj,GLenum pName)314 napi_value WebGL2RenderingContextImpl::GetSamplerParameter(napi_env env, napi_value samplerObj, GLenum pName)
315 {
316 WebGLSampler* sampler = WebGLObject::GetObjectInstance<WebGLSampler>(env, samplerObj);
317 if (sampler == nullptr) {
318 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
319 return NVal::CreateNull(env).val_;
320 }
321 GLuint samplerId = sampler->GetSampler();
322 switch (pName) {
323 case GL_TEXTURE_COMPARE_FUNC:
324 case GL_TEXTURE_COMPARE_MODE:
325 case GL_TEXTURE_MAG_FILTER:
326 case GL_TEXTURE_MIN_FILTER:
327 case GL_TEXTURE_WRAP_R:
328 case GL_TEXTURE_WRAP_S:
329 case GL_TEXTURE_WRAP_T: {
330 GLint params;
331 glGetSamplerParameteriv(static_cast<GLuint>(samplerId), static_cast<GLenum>(pName), ¶ms);
332 int64_t res = static_cast<int64_t>(params);
333 LOGD("WebGL2 getSamplerParameter samplerId %{public}u params %{public}d", samplerId, params);
334 return NVal::CreateInt64(env, res).val_;
335 }
336 case GL_TEXTURE_MAX_LOD:
337 case GL_TEXTURE_MIN_LOD: {
338 GLfloat params;
339 glGetSamplerParameterfv(static_cast<GLuint>(samplerId), static_cast<GLenum>(pName), ¶ms);
340 float res = static_cast<float>(params);
341 LOGD("WebGL2 getSamplerParameter samplerId %{public}u params %{public}f", samplerId, params);
342 return NVal::CreateDouble(env, (double)res).val_;
343 }
344 default:
345 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
346 return NVal::CreateNull(env).val_;
347 }
348 }
349
CreateVertexArray(napi_env env)350 napi_value WebGL2RenderingContextImpl::CreateVertexArray(napi_env env)
351 {
352 WebGLVertexArrayObject* webGLVertexArrayObject = nullptr;
353 napi_value objVertexArrayObject = WebGLVertexArrayObject::CreateObjectInstance(env, &webGLVertexArrayObject).val_;
354 if (webGLVertexArrayObject == nullptr) {
355 return NVal::CreateNull(env).val_;
356 }
357 uint32_t vertexArraysId = 0;
358 glGenVertexArrays(1, &vertexArraysId);
359
360 webGLVertexArrayObject->SetVertexArrays(vertexArraysId);
361 LOGD("WebGL2 createVertexArray vertexArraysId = %{public}u", vertexArraysId);
362 AddObject<WebGLVertexArrayObject>(env, vertexArraysId, objVertexArrayObject);
363 return objVertexArrayObject;
364 }
365
DeleteVertexArray(napi_env env,napi_value object)366 napi_value WebGL2RenderingContextImpl::DeleteVertexArray(napi_env env, napi_value object)
367 {
368 uint32_t vertexArrays = WebGLVertexArrayObject::DEFAULT_VERTEX_ARRAY_OBJECT;
369 WebGLVertexArrayObject* webGLVertexArrayObject =
370 WebGLObject::GetObjectInstance<WebGLVertexArrayObject>(env, object);
371 if (webGLVertexArrayObject == nullptr) {
372 return NVal::CreateNull(env).val_;
373 }
374 vertexArrays = webGLVertexArrayObject->GetVertexArrays();
375 if (boundVertexArrayId_ && boundVertexArrayId_ == vertexArrays) {
376 boundVertexArrayId_ = 0;
377 }
378 glDeleteVertexArrays(1, &vertexArrays);
379 LOGD("WebGL2 deleteVertexArrays vertexArrays %{public}u", vertexArrays);
380 DeleteObject<WebGLVertexArrayObject>(env, vertexArrays);
381 return NVal::CreateNull(env).val_;
382 }
383
IsVertexArray(napi_env env,napi_value object)384 napi_value WebGL2RenderingContextImpl::IsVertexArray(napi_env env, napi_value object)
385 {
386 GLuint vertexArrayId = WebGLVertexArrayObject::DEFAULT_VERTEX_ARRAY_OBJECT;
387 WebGLVertexArrayObject* webGLVertexArrayObject =
388 WebGLObject::GetObjectInstance<WebGLVertexArrayObject>(env, object);
389 if (webGLVertexArrayObject == nullptr) {
390 return NVal::CreateBool(env, false).val_;
391 }
392 vertexArrayId = webGLVertexArrayObject->GetVertexArrays();
393 GLboolean returnValue = glIsVertexArray(vertexArrayId);
394 LOGD("WebGL2 isVertexArray %{public}u %{public}d", vertexArrayId, returnValue);
395 return NVal::CreateBool(env, returnValue).val_;
396 }
397
BindVertexArray(napi_env env,napi_value object)398 napi_value WebGL2RenderingContextImpl::BindVertexArray(napi_env env, napi_value object)
399 {
400 GLuint vertexArrayId = WebGLVertexArrayObject::DEFAULT_VERTEX_ARRAY_OBJECT;
401 WebGLVertexArrayObject* webGLVertexArrayObject =
402 WebGLObject::GetObjectInstance<WebGLVertexArrayObject>(env, object);
403 if (webGLVertexArrayObject == nullptr) {
404 return NVal::CreateNull(env).val_;
405 }
406 vertexArrayId = webGLVertexArrayObject->GetVertexArrays();
407 glBindVertexArray(vertexArrayId);
408 boundVertexArrayId_ = vertexArrayId;
409 LOGD("WebGL2 bindVertexArray %{public}u ", vertexArrayId);
410 return NVal::CreateNull(env).val_;
411 }
412
FenceSync(napi_env env,GLenum condition,GLbitfield flags)413 napi_value WebGL2RenderingContextImpl::FenceSync(napi_env env, GLenum condition, GLbitfield flags)
414 {
415 WebGLSync* webGlSync = nullptr;
416 napi_value objSync = WebGLSync::CreateObjectInstance(env, &webGlSync).val_;
417 if (webGlSync == nullptr) {
418 return NVal::CreateNull(env).val_;
419 }
420 GLsync returnValue = glFenceSync(condition, flags);
421 webGlSync->SetSync(reinterpret_cast<int64_t>(returnValue));
422 LOGD("WebGL2 fenceSync syncId %{public}" PRIi64 " result %{public}u condition %{public}u flags %{public}u",
423 reinterpret_cast<int64_t>(returnValue), GetError_(), condition, flags);
424 return objSync;
425 }
426
IsSync(napi_env env,napi_value syncObj)427 napi_value WebGL2RenderingContextImpl::IsSync(napi_env env, napi_value syncObj)
428 {
429 WebGLSync* webGlSync = WebGLObject::GetObjectInstance<WebGLSync>(env, syncObj);
430 if (webGlSync == nullptr) {
431 return NVal::CreateBool(env, false).val_;
432 }
433 int64_t syncId = webGlSync->GetSync();
434 GLboolean returnValue = glIsSync(reinterpret_cast<GLsync>(syncId));
435 LOGD("WebGL2 isSync syncId %{public}" PRIi64 " result %{public}d", syncId, returnValue);
436 return NVal::CreateBool(env, static_cast<bool>(returnValue)).val_;
437 }
438
DeleteSync(napi_env env,napi_value syncObj)439 napi_value WebGL2RenderingContextImpl::DeleteSync(napi_env env, napi_value syncObj)
440 {
441 WebGLSync* webGlSync = WebGLObject::GetObjectInstance<WebGLSync>(env, syncObj);
442 if (webGlSync == nullptr) {
443 return NVal::CreateNull(env).val_;
444 }
445 int64_t syncId = webGlSync->GetSync();
446 glDeleteSync(reinterpret_cast<GLsync>(syncId));
447 LOGD("WebGL2 deleteSync syncId %{public}" PRIi64, syncId);
448 return NVal::CreateNull(env).val_;
449 }
450
ClientWaitSync(napi_env env,napi_value syncObj,GLbitfield flags,GLint64 timeout)451 napi_value WebGL2RenderingContextImpl::ClientWaitSync(
452 napi_env env, napi_value syncObj, GLbitfield flags, GLint64 timeout)
453 {
454 WebGLSync* webGlSync = WebGLObject::GetObjectInstance<WebGLSync>(env, syncObj);
455 if (webGlSync == nullptr) {
456 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "webGlSync is nullptr");
457 return NVal::CreateInt64(env, WebGL2RenderingContextBase::WAIT_FAILED).val_;
458 }
459 int64_t syncId = webGlSync->GetSync();
460 if (timeout < WebGL2RenderingContextBase::TIMEOUT_IGNORED) {
461 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "timeout %{pulic}" PRIi64, timeout);
462 return NVal::CreateInt64(env, WebGL2RenderingContextBase::WAIT_FAILED).val_;
463 }
464 GLuint64 timeout64 = (timeout == -1) ? GL_TIMEOUT_IGNORED : static_cast<GLuint64>(timeout);
465 GLenum returnValue = glClientWaitSync(reinterpret_cast<GLsync>(syncId), flags, timeout64);
466 LOGD("WebGL2 clientWaitSync syncId = %{public}d %{public}u result %{public}u",
467 static_cast<int>(syncId), returnValue, GetError_());
468 return NVal::CreateInt64(env, static_cast<int64_t>(returnValue)).val_;
469 }
470
WaitSync(napi_env env,napi_value syncObj,GLbitfield flags,GLint64 timeout)471 napi_value WebGL2RenderingContextImpl::WaitSync(napi_env env, napi_value syncObj, GLbitfield flags, GLint64 timeout)
472 {
473 WebGLSync* webGlSync = WebGLObject::GetObjectInstance<WebGLSync>(env, syncObj);
474 if (webGlSync == nullptr) {
475 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "webGlSync is nullptr");
476 return NVal::CreateNull(env).val_;
477 }
478 int64_t syncId = webGlSync->GetSync();
479 if (timeout < WebGL2RenderingContextBase::TIMEOUT_IGNORED) {
480 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "timeout %{pulic}" PRIi64, timeout);
481 return NVal::CreateNull(env).val_;
482 }
483 GLuint64 timeout64 = (timeout == -1) ? GL_TIMEOUT_IGNORED : static_cast<GLuint64>(timeout);
484 glWaitSync(reinterpret_cast<GLsync>(syncId), flags, timeout64);
485 LOGD("WebGL2 waitSync GL_TIMEOUT_IGNORED %{public}u", static_cast<unsigned int>(GL_TIMEOUT_IGNORED));
486 return NVal::CreateNull(env).val_;
487 }
488
GetSyncParameter(napi_env env,napi_value syncObj,GLenum pname)489 napi_value WebGL2RenderingContextImpl::GetSyncParameter(napi_env env, napi_value syncObj, GLenum pname)
490 {
491 WebGLSync* webGlSync = WebGLObject::GetObjectInstance<WebGLSync>(env, syncObj);
492 if (webGlSync == nullptr) {
493 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
494 return NVal::CreateNull(env).val_;
495 }
496 int64_t syncId = webGlSync->GetSync();
497 LOGD("WebGL2 getSyncParameter syncId %{public}" PRIi64 " pname %{public}u ", syncId, pname);
498 if (CheckInList(pname, { GL_OBJECT_TYPE, GL_SYNC_STATUS, GL_SYNC_CONDITION, GL_SYNC_FLAGS })) {
499 GLint value = 0;
500 GLsizei length = -1;
501 glGetSynciv(reinterpret_cast<GLsync>(syncId), pname, 1, &length, &value);
502 LOGD("WebGL2 getSyncParameter value %{public}d ", value);
503 return NVal::CreateInt64(env, value).val_;
504 } else {
505 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
506 return NVal::CreateNull(env).val_;
507 }
508 }
509
CreateTransformFeedback(napi_env env)510 napi_value WebGL2RenderingContextImpl::CreateTransformFeedback(napi_env env)
511 {
512 WebGLTransformFeedback* webGlTransformFeedback = nullptr;
513 napi_value objTransformFeedback = WebGLTransformFeedback::CreateObjectInstance(env, &webGlTransformFeedback).val_;
514 if (webGlTransformFeedback == nullptr) {
515 return NVal::CreateNull(env).val_;
516 }
517 GLuint transformFeedbackId = 0;
518 glGenTransformFeedbacks(1, &transformFeedbackId);
519 webGlTransformFeedback->SetTransformFeedback(transformFeedbackId);
520 LOGD("WebGL2 createTransformFeedback transformFeedbackId %{public}u", transformFeedbackId);
521 AddObject<WebGLTransformFeedback>(env, transformFeedbackId, objTransformFeedback);
522 return objTransformFeedback;
523 }
524
DeleteTransformFeedback(napi_env env,napi_value obj)525 napi_value WebGL2RenderingContextImpl::DeleteTransformFeedback(napi_env env, napi_value obj)
526 {
527 uint32_t transformFeedbackId = WebGLTransformFeedback::DEFAULT_TRANSFORM_FEEDBACK;
528 WebGLTransformFeedback* webGlTransformFeedback = WebGLObject::GetObjectInstance<WebGLTransformFeedback>(env, obj);
529 if (webGlTransformFeedback == nullptr) {
530 return NVal::CreateNull(env).val_;
531 }
532 transformFeedbackId = webGlTransformFeedback->GetTransformFeedback();
533 DeleteObject<WebGLTransformFeedback>(env, transformFeedbackId);
534 glDeleteTransformFeedbacks(1, &transformFeedbackId);
535 LOGD("WebGL2 deleteTransformFeedback transformFeedbackId %{public}u", transformFeedbackId);
536 if (boundTransformFeedback_ != transformFeedbackId) {
537 LOGE("WebGL2 bindTransformFeedback bound %{public}u", boundTransformFeedback_);
538 }
539 boundTransformFeedback_ = 0;
540 return NVal::CreateNull(env).val_;
541 }
542
IsTransformFeedback(napi_env env,napi_value obj)543 napi_value WebGL2RenderingContextImpl::IsTransformFeedback(napi_env env, napi_value obj)
544 {
545 WebGLTransformFeedback* webGlTransformFeedback = WebGLObject::GetObjectInstance<WebGLTransformFeedback>(env, obj);
546 if (webGlTransformFeedback == nullptr) {
547 return NVal::CreateBool(env, false).val_;
548 }
549 GLuint transformFeedbackId = webGlTransformFeedback->GetTransformFeedback();
550 LOGD("WebGL2 isTransformFeedback transformFeedbackId %{public}u bound %{public}u",
551 transformFeedbackId, boundTransformFeedback_);
552 if (GetObjectInstance<WebGLTransformFeedback>(env, transformFeedbackId) != nullptr &&
553 boundTransformFeedback_ == transformFeedbackId) {
554 return NVal::CreateBool(env, true).val_;
555 }
556 return NVal::CreateBool(env, false).val_;
557 }
558
BindTransformFeedback(napi_env env,napi_value obj,GLenum target)559 napi_value WebGL2RenderingContextImpl::BindTransformFeedback(napi_env env, napi_value obj, GLenum target)
560 {
561 WebGLTransformFeedback* webGlTransformFeedback = WebGLObject::GetObjectInstance<WebGLTransformFeedback>(env, obj);
562 if (webGlTransformFeedback == nullptr) {
563 return NVal::CreateBool(env, false).val_;
564 }
565 GLuint transformFeedbackId = webGlTransformFeedback->GetTransformFeedback();
566 if (target != GL_TRANSFORM_FEEDBACK) {
567 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
568 return NVal::CreateNull(env).val_;
569 }
570 if (boundTransformFeedback_ && boundTransformFeedback_ != transformFeedbackId) {
571 LOGE("WebGL2 bindTransformFeedback has been bound %{public}u", boundTransformFeedback_);
572 }
573 boundTransformFeedback_ = transformFeedbackId;
574 glBindTransformFeedback(target, transformFeedbackId);
575 LOGD("WebGL2 bindTransformFeedback id %{public}u target %{public}u result %{public}u",
576 transformFeedbackId, target, GetError_());
577 if (webGlTransformFeedback) {
578 webGlTransformFeedback->SetTarget(target);
579 }
580 return NVal::CreateNull(env).val_;
581 }
582
GetTransformFeedbackVaryingType(GLuint programId,GLint index)583 static GLint GetTransformFeedbackVaryingType(GLuint programId, GLint index)
584 {
585 GLint params = 0;
586 glGetProgramiv(programId, WebGL2RenderingContextBase::TRANSFORM_FEEDBACK_VARYINGS, ¶ms);
587 LOGD("WebGL2 GetTransformFeedbackVaryingType programId %{public}u params %{public}d", programId, params);
588 return params;
589 }
590
BeginTransformFeedback(napi_env env,GLenum primitiveMode)591 napi_value WebGL2RenderingContextImpl::BeginTransformFeedback(napi_env env, GLenum primitiveMode)
592 {
593 if (!CheckInList(primitiveMode, { WebGLRenderingContextBase::POINTS, WebGLRenderingContextBase::LINES,
594 WebGLRenderingContextBase::TRIANGLES })) {
595 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
596 return NVal::CreateNull(env).val_;
597 }
598 if (GetTransformFeedbackVaryingType(currentProgramId_, boundTransformFeedback_) <= 0) {
599 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
600 return NVal::CreateNull(env).val_;
601 }
602 glBeginTransformFeedback(primitiveMode);
603 LOGD("WebGL2 beginTransformFeedback primitiveMode %{public}u result %{public}u", primitiveMode, GetError_());
604 return NVal::CreateNull(env).val_;
605 }
606
EndTransformFeedback(napi_env env)607 napi_value WebGL2RenderingContextImpl::EndTransformFeedback(napi_env env)
608 {
609 LOGD("WebGL2 endTransformFeedback");
610 if (GetTransformFeedbackVaryingType(currentProgramId_, boundTransformFeedback_) <= 0) {
611 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
612 return NVal::CreateNull(env).val_;
613 }
614 glEndTransformFeedback();
615 return NVal::CreateNull(env).val_;
616 }
617
GetTransformFeedbackVarying(napi_env env,napi_value programObj,GLuint index)618 napi_value WebGL2RenderingContextImpl::GetTransformFeedbackVarying(napi_env env, napi_value programObj, GLuint index)
619 {
620 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
621 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
622 if (webGLProgram == nullptr) {
623 return NVal::CreateNull(env).val_;
624 }
625 programId = webGLProgram->GetProgramId();
626
627 WebGLActiveInfo* webGLActiveInfo = nullptr;
628 napi_value objActiveInfo = WebGLActiveInfo::CreateObjectInstance(env, &webGLActiveInfo).val_;
629 if (webGLActiveInfo == nullptr) {
630 return NVal::CreateNull(env).val_;
631 }
632
633 GLsizei bufSize = WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH;
634 GLsizei length = 0;
635 GLsizei size = 0;
636 GLenum type = 0;
637 GLchar name[WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH] = { 0 };
638 glGetTransformFeedbackVarying(programId, index, bufSize, &length, &size, &type, name);
639 LOGD("WebGL2 getTransformFeedbackVarying: name '%{public}s' %{public}u length %{public}d %{public}d"
640 " index %{public}u", name, type, length, size, index);
641 if (type == 0) {
642 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
643 return NVal::CreateNull(env).val_;
644 }
645 webGLActiveInfo->SetActiveName(name, WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH);
646 webGLActiveInfo->SetActiveSize(size);
647 webGLActiveInfo->SetActiveType(type);
648 return objActiveInfo;
649 }
650
TexStorage2D(napi_env env,const TexStorageArg & arg)651 napi_value WebGL2RenderingContextImpl::TexStorage2D(napi_env env, const TexStorageArg& arg)
652 {
653 arg.Dump("WebGL2 texStorage2D");
654 if (arg.target != GL_TEXTURE_2D && arg.target != GL_TEXTURE_CUBE_MAP) {
655 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
656 return NVal::CreateNull(env).val_;
657 }
658 WebGLTexture* texture = GetBoundTexture(env, arg.target, false);
659 if (texture == nullptr) {
660 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
661 return NVal::CreateNull(env).val_;
662 }
663 GLenum result = CheckTexStorage(env, arg);
664 if (result != WebGLRenderingContextBase::NO_ERROR) {
665 SET_ERROR_WITH_LOG(result, "CheckTexStorage failed");
666 return NVal::CreateNull(env).val_;
667 }
668 glTexStorage2D(arg.target, arg.levels, arg.internalFormat, arg.width, arg.height);
669 texture->SetTexStorageInfo(&arg);
670 return NVal::CreateNull(env).val_;
671 }
672
TexStorage3D(napi_env env,const TexStorageArg & arg)673 napi_value WebGL2RenderingContextImpl::TexStorage3D(napi_env env, const TexStorageArg& arg)
674 {
675 arg.Dump("WebGL texStorage3D");
676 if (arg.target != GL_TEXTURE_3D && arg.target != GL_TEXTURE_2D_ARRAY) {
677 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
678 return NVal::CreateNull(env).val_;
679 }
680 GLenum result = CheckTexStorage(env, arg);
681 if (result != WebGLRenderingContextBase::NO_ERROR) {
682 SET_ERROR_WITH_LOG(result, "CheckTexStorage failed");
683 return NVal::CreateNull(env).val_;
684 }
685 WebGLTexture* texture = GetBoundTexture(env, arg.target, false);
686 if (texture == nullptr) {
687 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
688 return NVal::CreateNull(env).val_;
689 }
690 glTexStorage3D(arg.target, arg.levels, arg.internalFormat, arg.width, arg.height, arg.depth);
691 texture->SetTexStorageInfo(&arg);
692 LOGD("WebGL texStorage3D result %{public}u", GetError_());
693 return NVal::CreateNull(env).val_;
694 }
695
CheckTexImage3D(napi_env env,const TexImageArg & imgArg)696 GLenum WebGL2RenderingContextImpl::CheckTexImage3D(napi_env env, const TexImageArg& imgArg)
697 {
698 switch (imgArg.target) {
699 case GL_TEXTURE_3D:
700 case GL_TEXTURE_2D_ARRAY:
701 break;
702 default:
703 return WebGLRenderingContextBase::INVALID_ENUM;
704 }
705 GLenum result = CheckTextureLevel(imgArg.target, imgArg.level);
706 if (result != WebGLRenderingContextBase::NO_ERROR) {
707 return result;
708 }
709 return CheckTextureFormatAndType(env, imgArg.internalFormat, imgArg.format, imgArg.type, imgArg.level);
710 }
711
TexImage3D(napi_env env,const TexImageArg & arg,napi_value source)712 napi_value WebGL2RenderingContextImpl::TexImage3D(napi_env env, const TexImageArg& arg, napi_value source)
713 {
714 TexImageArg imgArg(arg);
715 imgArg.Dump("WebGL2 texImage3D");
716 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
717 if (texture == nullptr) {
718 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
719 return NVal::CreateNull(env).val_;
720 }
721
722 GLenum result = CheckTexImage3D(env, imgArg);
723 if (result != WebGLRenderingContextBase::NO_ERROR) {
724 SET_ERROR_WITH_LOG(result, "CheckTexImage3D failed");
725 return NVal::CreateNull(env).val_;
726 }
727 GLvoid* data = nullptr;
728 WebGLImageSource imageSource(env, version_, unpackFlipY_, unpackPremultiplyAlpha_);
729 if (!NVal(env, source).IsNull()) {
730 result = imageSource.GenImageSource(
731 { imgArg.format, imgArg.type, imgArg.width, imgArg.height, imgArg.depth }, source);
732 if (result) {
733 SET_ERROR_WITH_LOG(result, "GenImageSource failed");
734 return NVal::CreateNull(env).val_;
735 }
736 data = imageSource.GetImageSourceData();
737 imgArg.width = imageSource.GetWidth();
738 imgArg.height = imageSource.GetHeight();
739 }
740
741 glTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height, imgArg.depth,
742 imgArg.border, imgArg.format, imgArg.type, data);
743 texture->SetTextureLevel({ imgArg.target, imgArg.level,
744 imgArg.internalFormat, imgArg.width, imgArg.height, imgArg.depth, imgArg.type });
745 LOGD("WebGL2 texImage3D result %{public}u", GetError_());
746 return NVal::CreateNull(env).val_;
747 }
748
TexImage3D(napi_env env,const TexImageArg & imgArg,napi_value dataObj,GLuint srcOffset)749 napi_value WebGL2RenderingContextImpl::TexImage3D(
750 napi_env env, const TexImageArg& imgArg, napi_value dataObj, GLuint srcOffset)
751 {
752 imgArg.Dump("WebGL2 texImage3D");
753 GLenum result = CheckTexImage3D(env, imgArg);
754 if (result != WebGLRenderingContextBase::NO_ERROR) {
755 SET_ERROR_WITH_LOG(result, "CheckTexImage3D failed");
756 return NVal::CreateNull(env).val_;
757 }
758
759 GLvoid* data = nullptr;
760 WebGLImageSource imageSource(env, version_, unpackFlipY_, unpackPremultiplyAlpha_);
761 if (!NVal(env, dataObj).IsNull()) {
762 result = imageSource.GenImageSource(
763 { imgArg.format, imgArg.type, imgArg.width, imgArg.height, imgArg.depth }, dataObj, srcOffset);
764 if (result) {
765 SET_ERROR_WITH_LOG(result, "GenImageSource failed");
766 return NVal::CreateNull(env).val_;
767 }
768 data = imageSource.GetImageSourceData();
769 }
770 if (data != nullptr) {
771 GLenum result = CheckTextureDataBuffer(imgArg, imageSource.GetWebGLReadBuffer());
772 if (result) {
773 SET_ERROR_WITH_LOG(result, "CheckTextureDataBuffer failed");
774 return NVal::CreateNull(env).val_;
775 }
776 }
777 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
778 if (texture == nullptr) {
779 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "texture is nullptr");
780 return NVal::CreateNull(env).val_;
781 }
782 glTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height, imgArg.depth,
783 imgArg.border, imgArg.format, imgArg.type, data);
784 texture->SetTextureLevel(imgArg);
785 LOGD("WebGL2 texImage3D result %{public}u", GetError_());
786 return NVal::CreateNull(env).val_;
787 }
788
TexImage3D(napi_env env,const TexImageArg & imgArg,GLintptr pboOffset)789 napi_value WebGL2RenderingContextImpl::TexImage3D(napi_env env, const TexImageArg& imgArg, GLintptr pboOffset)
790 {
791 imgArg.Dump("WebGL2 texImage3D");
792 GLenum result = CheckTexImage3D(env, imgArg);
793 if (result != WebGLRenderingContextBase::NO_ERROR) {
794 SET_ERROR(result);
795 return NVal::CreateNull(env).val_;
796 }
797 glTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height, imgArg.depth,
798 imgArg.border, imgArg.format, imgArg.type, reinterpret_cast<void*>(pboOffset));
799 LOGD("WebGL2 texImage3D result %{public}u", GetError_());
800 return NVal::CreateNull(env).val_;
801 }
802
CheckTexSubImage3D(napi_env env,const TexSubImage3DArg & arg)803 GLenum WebGL2RenderingContextImpl::CheckTexSubImage3D(napi_env env, const TexSubImage3DArg& arg)
804 {
805 switch (arg.target) {
806 case GL_TEXTURE_3D:
807 case GL_TEXTURE_2D_ARRAY:
808 break;
809 default:
810 return WebGLRenderingContextBase::INVALID_ENUM;
811 }
812 GLenum result = CheckTextureLevel(arg.target, arg.level);
813 if (result != WebGLRenderingContextBase::NO_ERROR) {
814 return result;
815 }
816 WebGLTexture* texture = GetBoundTexture(env, arg.target, false);
817 if (texture == nullptr) {
818 return WebGLRenderingContextBase::INVALID_VALUE;
819 }
820
821 if (!texture->CheckValid(arg.target, arg.level)) {
822 return WebGLRenderingContextBase::INVALID_OPERATION;
823 }
824
825 if (!WebGLTexture::CheckTextureSize(arg.xOffset, arg.width, texture->GetWidth(arg.target, arg.level)) ||
826 !WebGLTexture::CheckTextureSize(arg.yOffset, arg.height, texture->GetHeight(arg.target, arg.level)) ||
827 !WebGLTexture::CheckTextureSize(arg.zOffset, arg.depth, texture->GetDepth(arg.target, arg.level))) {
828 return WebGLRenderingContextBase::INVALID_VALUE;
829 }
830 GLenum internalFormat = texture->GetInternalFormat(arg.target, arg.level);
831 return CheckTextureFormatAndType(env, internalFormat, arg.format, arg.type, arg.level);
832 }
833
TexSubImage3D(napi_env env,const TexSubImage3DArg & arg,napi_value source)834 napi_value WebGL2RenderingContextImpl::TexSubImage3D(napi_env env, const TexSubImage3DArg& arg, napi_value source)
835 {
836 TexSubImage3DArg imgArg(arg);
837 imgArg.Dump("WebGL2 texSubImage3D source");
838 GLvoid* data = nullptr;
839 WebGLImageSource imageSource(env, version_, unpackFlipY_, unpackPremultiplyAlpha_);
840 if (!NVal(env, source).IsNull()) {
841 GLenum result = imageSource.GenImageSource(
842 { imgArg.format, imgArg.type, imgArg.width, imgArg.height, imgArg.depth }, source);
843 if (result) {
844 SET_ERROR_WITH_LOG(result, "GenImageSource failed");
845 return NVal::CreateNull(env).val_;
846 }
847 data = imageSource.GetImageSourceData();
848 imgArg.width = imageSource.GetWidth();
849 imgArg.height = imageSource.GetHeight();
850 } else {
851 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
852 return NVal::CreateNull(env).val_;
853 }
854 GLenum result = CheckTexSubImage3D(env, imgArg);
855 if (result != WebGLRenderingContextBase::NO_ERROR) {
856 SET_ERROR_WITH_LOG(result, "CheckTexSubImage3D failed");
857 return NVal::CreateNull(env).val_;
858 }
859 glTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
860 imgArg.height, imgArg.depth, imgArg.format, imgArg.type, data);
861 LOGD("WebGL2 texSubImage3D result %{public}u", GetError_());
862 return NVal::CreateNull(env).val_;
863 }
864
TexSubImage3D(napi_env env,const TexSubImage3DArg & imgArg,napi_value dataObj,GLuint srcOffset)865 napi_value WebGL2RenderingContextImpl::TexSubImage3D(
866 napi_env env, const TexSubImage3DArg& imgArg, napi_value dataObj, GLuint srcOffset)
867 {
868 imgArg.Dump("WebGL2 texSubImage3D data buffer");
869
870 WebGLImageSource imageSource(env, version_, unpackFlipY_, unpackPremultiplyAlpha_);
871 GLvoid* data = nullptr;
872 bool changeUnpackAlignment = false;
873 if (!NVal(env, dataObj).IsNull()) {
874 GLenum result = imageSource.GenImageSource(
875 { imgArg.format, imgArg.type, imgArg.width, imgArg.height, imgArg.depth }, dataObj, srcOffset);
876 if (result) {
877 SET_ERROR_WITH_LOG(result, "GenImageSource failed");
878 return NVal::CreateNull(env).val_;
879 }
880 data = imageSource.GetImageSourceData();
881 changeUnpackAlignment = unpackFlipY_ || unpackPremultiplyAlpha_;
882 } else {
883 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
884 return NVal::CreateNull(env).val_;
885 }
886
887 GLenum result = CheckTexSubImage3D(env, imgArg);
888 if (result != WebGLRenderingContextBase::NO_ERROR) {
889 SET_ERROR_WITH_LOG(result, "CheckTexSubImage3D failed");
890 return NVal::CreateNull(env).val_;
891 }
892
893 if (changeUnpackAlignment) {
894 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
895 }
896 glTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
897 imgArg.height, imgArg.depth, imgArg.format, imgArg.type, data);
898 if (changeUnpackAlignment) {
899 glPixelStorei(GL_UNPACK_ALIGNMENT, unpackAlignment_);
900 }
901 LOGD("WebGL2 texSubImage3D result %{public}u", GetError_());
902 return NVal::CreateNull(env).val_;
903 }
904
TexSubImage3D(napi_env env,const TexSubImage3DArg & imgArg,GLintptr pboOffset)905 napi_value WebGL2RenderingContextImpl::TexSubImage3D(napi_env env, const TexSubImage3DArg& imgArg, GLintptr pboOffset)
906 {
907 imgArg.Dump("WebGL2 texSubImage3D pboOffset");
908 GLenum result = CheckTexSubImage3D(env, imgArg);
909 if (result != WebGLRenderingContextBase::NO_ERROR) {
910 SET_ERROR(result);
911 return NVal::CreateNull(env).val_;
912 }
913 glTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
914 imgArg.height, imgArg.depth, imgArg.format, imgArg.type, reinterpret_cast<void*>(pboOffset));
915 LOGD("WebGL2 texSubImage3D result %{public}u", GetError_());
916 return NVal::CreateNull(env).val_;
917 }
918
CopyTexSubImage3D(napi_env env,const CopyTexSubImage3DArg & imgArg)919 napi_value WebGL2RenderingContextImpl::CopyTexSubImage3D(napi_env env, const CopyTexSubImage3DArg& imgArg)
920 {
921 imgArg.Dump("WebGL2 copyTexSubImage3D");
922 GLenum result = CheckCopyTexSubImage(env, imgArg);
923 if (result) {
924 SET_ERROR_WITH_LOG(result, "CheckCopyTexSubImage failed");
925 return NVal::CreateNull(env).val_;
926 }
927 GLuint frameBufferId = 0;
928 result = CheckReadBufferAndGetInfo(env, &frameBufferId, nullptr, nullptr);
929 if (result != WebGLRenderingContextBase::NO_ERROR) {
930 SET_ERROR_WITH_LOG(result, "CheckReadBufferAndGetInfo failed");
931 return NVal::CreateNull(env).val_;
932 }
933 glCopyTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.x, imgArg.y,
934 imgArg.width, imgArg.height);
935 LOGD("WebGL2 copyTexSubImage3D result %{public}u", GetError_());
936 return NVal::CreateNull(env).val_;
937 }
938
CompressedTexImage3D(napi_env env,const TexImageArg & imgArg,GLsizei imageSize,GLintptr offset)939 napi_value WebGL2RenderingContextImpl::CompressedTexImage3D(
940 napi_env env, const TexImageArg& imgArg, GLsizei imageSize, GLintptr offset)
941 {
942 imgArg.Dump("WebGL2 compressedTexImage3D");
943 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
944 if (texture == nullptr) {
945 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "texture is nullptr");
946 return NVal::CreateNull(env).val_;
947 }
948 if (texture->CheckImmutable()) {
949 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckImmutable failed");
950 return NVal::CreateNull(env).val_;
951 }
952
953 glCompressedTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height,
954 imgArg.depth, imgArg.border, imageSize, reinterpret_cast<void*>(offset));
955 LOGD("WebGL2 copyTexSubImage3D result %{public}u", GetError_());
956 return NVal::CreateNull(env).val_;
957 }
958
CompressedTexImage3D(napi_env env,const TexImageArg & imgArg,napi_value dataObj,GLuint srcOffset,GLuint srcLengthOverride)959 napi_value WebGL2RenderingContextImpl::CompressedTexImage3D(
960 napi_env env, const TexImageArg& imgArg, napi_value dataObj, GLuint srcOffset, GLuint srcLengthOverride)
961 {
962 imgArg.Dump("WebGL2 compressedTexImage3D");
963 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
964 if (texture == nullptr) {
965 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "texture is nullptr");
966 return NVal::CreateNull(env).val_;
967 }
968 if (texture->CheckImmutable()) {
969 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckImmutable failed");
970 return NVal::CreateNull(env).val_;
971 }
972 WebGLReadBufferArg readData(env);
973 GLvoid* data = nullptr;
974 GLsizei length = 0;
975 if (NVal(env, dataObj).IsNull()) {
976 napi_status status = readData.GenBufferData(dataObj, BUFFER_DATA_FLOAT_32);
977 if (status != napi_ok) {
978 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "GenBufferData failed");
979 return NVal::CreateNull(env).val_;
980 }
981 readData.DumpBuffer(readData.GetBufferDataType());
982 data = reinterpret_cast<void*>(readData.GetBuffer() + srcOffset);
983 length = static_cast<GLsizei>((srcLengthOverride == 0) ? readData.GetBufferLength() : srcLengthOverride);
984 }
985 glCompressedTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height,
986 imgArg.depth, imgArg.border, length, data);
987 texture->SetTextureLevel({ imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height,
988 imgArg.depth, GL_UNSIGNED_BYTE });
989 LOGD("WebGL2 compressedTexImage3D result %{public}u", GetError_());
990 return NVal::CreateNull(env).val_;
991 }
992
CompressedTexSubImage3D(napi_env env,const TexSubImage3DArg & imgArg,GLsizei imageSize,GLintptr offset)993 napi_value WebGL2RenderingContextImpl::CompressedTexSubImage3D(
994 napi_env env, const TexSubImage3DArg& imgArg, GLsizei imageSize, GLintptr offset)
995 {
996 imgArg.Dump("WebGL2 compressedTexSubImage3D");
997 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
998 if (texture == nullptr) {
999 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "texture is nullptr");
1000 return NVal::CreateNull(env).val_;
1001 }
1002 if (imgArg.format != texture->GetInternalFormat(imgArg.target, imgArg.level)) {
1003 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
1004 return NVal::CreateNull(env).val_;
1005 }
1006 glCompressedTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
1007 imgArg.height, imgArg.depth, imgArg.format, imageSize, reinterpret_cast<void*>(offset));
1008 LOGD("WebGL2 compressedTexSubImage3D result %{public}u", GetError_());
1009 return NVal::CreateNull(env).val_;
1010 }
1011
CompressedTexSubImage3D(napi_env env,const TexSubImage3DArg & imgArg,napi_value dataObj,GLuint srcOffset,GLuint srcLengthOverride)1012 napi_value WebGL2RenderingContextImpl::CompressedTexSubImage3D(
1013 napi_env env, const TexSubImage3DArg& imgArg, napi_value dataObj, GLuint srcOffset, GLuint srcLengthOverride)
1014 {
1015 imgArg.Dump("WebGL2 compressedTexSubImage3D");
1016 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
1017 if (texture == nullptr) {
1018 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "texture is nullptr");
1019 return NVal::CreateNull(env).val_;
1020 }
1021 if (imgArg.format != texture->GetInternalFormat(imgArg.target, imgArg.level)) {
1022 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
1023 return NVal::CreateNull(env).val_;
1024 }
1025
1026 WebGLReadBufferArg readData(env);
1027 GLvoid* data = nullptr;
1028 GLsizei length = 0;
1029 if (NVal(env, dataObj).IsNull()) {
1030 napi_status status = readData.GenBufferData(dataObj, BUFFER_DATA_FLOAT_32);
1031 if (status != napi_ok) {
1032 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1033 return NVal::CreateNull(env).val_;
1034 }
1035 readData.DumpBuffer(readData.GetBufferDataType());
1036 data = reinterpret_cast<void*>(readData.GetBuffer() + srcOffset);
1037 length = static_cast<GLsizei>((srcLengthOverride == 0) ? readData.GetBufferLength() : srcLengthOverride);
1038 }
1039
1040 glCompressedTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
1041 imgArg.height, imgArg.depth, imgArg.format, length, data);
1042 LOGD("WebGL2 compressedTexSubImage3D result %{public}u", GetError_());
1043 return NVal::CreateNull(env).val_;
1044 }
1045
ClearBufferV(napi_env env,GLenum buffer,GLint drawBuffer,napi_value value,int64_t srcOffset,BufferDataType type)1046 napi_value WebGL2RenderingContextImpl::ClearBufferV(
1047 napi_env env, GLenum buffer, GLint drawBuffer, napi_value value, int64_t srcOffset, BufferDataType type)
1048 {
1049 LOGD("WebGL2 clearBuffer buffer %{public}u %{public}d srcOffset %{public}" PRIi64, buffer, drawBuffer, srcOffset);
1050 WebGLReadBufferArg bufferData(env);
1051 napi_status status = bufferData.GenBufferData(value, type);
1052 if (status != 0) {
1053 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "WebGL2 clearBuffer failed to getbuffer data");
1054 return NVal::CreateNull(env).val_;
1055 }
1056 if (bufferData.GetBufferDataType() != type) {
1057 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1058 "WebGL2 clearBuffer invalid buffer data type %{public}d", bufferData.GetBufferDataType());
1059 return NVal::CreateNull(env).val_;
1060 }
1061
1062 GLenum result = CheckClearBuffer(env, buffer, bufferData);
1063 if (result != WebGLRenderingContextBase::NO_ERROR) {
1064 SET_ERROR_WITH_LOG(result, "WebGL2 clearBuffer invalid clear buffer");
1065 return NVal::CreateNull(env).val_;
1066 }
1067
1068 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1069 switch (type) {
1070 case BUFFER_DATA_FLOAT_32:
1071 glClearBufferfv(buffer, drawBuffer, reinterpret_cast<GLfloat*>(bufferData.GetBuffer() + srcOffset));
1072 break;
1073 case BUFFER_DATA_INT_32:
1074 glClearBufferiv(buffer, drawBuffer, reinterpret_cast<GLint*>(bufferData.GetBuffer() + srcOffset));
1075 break;
1076 case BUFFER_DATA_UINT_32:
1077 glClearBufferuiv(buffer, drawBuffer, reinterpret_cast<GLuint*>(bufferData.GetBuffer() + srcOffset));
1078 break;
1079 default:
1080 break;
1081 }
1082 LOGD("WebGL2 clearBuffer buffer %{public}u result %{public}u", buffer, GetError_());
1083 return NVal::CreateNull(env).val_;
1084 }
1085
ClearBufferfi(napi_env env,GLenum buffer,GLint drawBuffer,GLfloat depth,GLint stencil)1086 napi_value WebGL2RenderingContextImpl::ClearBufferfi(
1087 napi_env env, GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil)
1088 {
1089 if (buffer != WebGLRenderingContextBase::DEPTH_STENCIL) {
1090 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1091 return NVal::CreateNull(env).val_;
1092 }
1093 glClearBufferfi(buffer, drawBuffer, depth, stencil);
1094 LOGD("WebGL2 clearBufferfi buffer %{public}u %{public}d depth %{public}f %{public}d result %{public}u",
1095 buffer, drawBuffer, depth, stencil, GetError_());
1096 return NVal::CreateNull(env).val_;
1097 }
1098
GetIndexedParameter(napi_env env,GLenum target,GLuint index)1099 napi_value WebGL2RenderingContextImpl::GetIndexedParameter(napi_env env, GLenum target, GLuint index)
1100 {
1101 LOGD("WebGL2 getIndexedParameter index %{public}u", index);
1102 switch (target) {
1103 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: {
1104 if (index >= maxBoundTransformFeedbackBufferIndex_) {
1105 return NVal::CreateNull(env).val_;
1106 }
1107 return GetObject<WebGLBuffer>(env, boundIndexedTransformFeedbackBuffers_[index]);
1108 }
1109 case GL_UNIFORM_BUFFER_BINDING: {
1110 if (index >= maxBoundUniformBufferIndex_) {
1111 return NVal::CreateNull(env).val_;
1112 }
1113 return GetObject<WebGLBuffer>(env, boundIndexedUniformBuffers_[index]);
1114 }
1115 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1116 case GL_UNIFORM_BUFFER_SIZE:
1117 case GL_UNIFORM_BUFFER_START: {
1118 int64_t data;
1119 glGetInteger64i_v(target, index, &data);
1120 LOGD("WebGL getIndexedParameter end");
1121 return NVal::CreateInt64(env, data).val_;
1122 }
1123 default :
1124 LOGD("WebGL getIndexedParameter get nullptr");
1125 return NVal::CreateNull(env).val_;
1126 }
1127 }
1128
GetFragDataLocation(napi_env env,napi_value programObj,const std::string & name)1129 napi_value WebGL2RenderingContextImpl::GetFragDataLocation(napi_env env, napi_value programObj, const std::string& name)
1130 {
1131 GLuint program = WebGLProgram::DEFAULT_PROGRAM_ID;
1132 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1133 if (webGLProgram == nullptr) {
1134 return NVal::CreateInt64(env, -1).val_;
1135 }
1136 program = webGLProgram->GetProgramId();
1137
1138 GLint res = glGetFragDataLocation(program, const_cast<char*>(name.c_str()));
1139 LOGD("WebGL2 getFragDataLocation name %{public}s result %{public}d", name.c_str(), res);
1140 return NVal::CreateInt64(env, res).val_;
1141 }
1142
VertexAttribI4i(napi_env env,GLuint index,GLint * data)1143 napi_value WebGL2RenderingContextImpl::VertexAttribI4i(napi_env env, GLuint index, GLint* data)
1144 {
1145 VertexAttribInfo* info = GetVertexAttribInfo(index);
1146 if (info == nullptr) {
1147 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1148 return NVal::CreateNull(env).val_;
1149 }
1150
1151 glVertexAttribI4i(index, data[0], data[1], data[2], data[3]); // 2, 3 index for data
1152 info->type = BUFFER_DATA_INT_32;
1153 LOGD("WebGL2 vertexAttribI4i index %{public}u [%{public}d %{public}d %{public}d %{public}d] result %{public}u",
1154 index, data[0], data[1], data[2], data[3], GetError_()); // 2, 3 index for data
1155 return NVal::CreateNull(env).val_;
1156 }
1157
VertexAttribI4ui(napi_env env,GLuint index,GLuint * data)1158 napi_value WebGL2RenderingContextImpl::VertexAttribI4ui(napi_env env, GLuint index, GLuint* data)
1159 {
1160 VertexAttribInfo* info = GetVertexAttribInfo(index);
1161 if (info == nullptr) {
1162 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1163 return NVal::CreateNull(env).val_;
1164 }
1165
1166 glVertexAttribI4ui(index, data[0], data[1], data[2], data[3]); // 2, 3 index for data
1167 info->type = BUFFER_DATA_UINT_32;
1168 LOGD("WebGL2 vertexAttribI4ui index %{public}u [%{public}u %{public}u %{public}u %{public}u] result %{public}u",
1169 index, data[0], data[1], data[2], data[3], GetError_()); // 2, 3 index for data
1170 return NVal::CreateNull(env).val_;
1171 }
1172
VertexAttribI4iv(napi_env env,GLuint index,napi_value data)1173 napi_value WebGL2RenderingContextImpl::VertexAttribI4iv(napi_env env, GLuint index, napi_value data)
1174 {
1175 VertexAttribInfo* info = GetVertexAttribInfo(index);
1176 if (info == nullptr) {
1177 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1178 return NVal::CreateNull(env).val_;
1179 }
1180
1181 WebGLReadBufferArg bufferData(env);
1182 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_INT_32);
1183 if (status != 0) {
1184 LOGE("WebGL vertexAttribI4iv failed to getbuffer data");
1185 return NVal::CreateNull(env).val_;
1186 }
1187 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1188 if (bufferData.GetBufferDataType() != BUFFER_DATA_INT_32) {
1189 LOGE("WebGL vertexAttribI4iv invalid data type %{public}u", bufferData.GetBufferDataType());
1190 return NVal::CreateNull(env).val_;
1191 }
1192 glVertexAttribI4iv(index, reinterpret_cast<GLint*>(bufferData.GetBuffer()));
1193 info->type = BUFFER_DATA_INT_32;
1194 return NVal::CreateNull(env).val_;
1195 }
1196
VertexAttribI4uiv(napi_env env,GLuint index,napi_value data)1197 napi_value WebGL2RenderingContextImpl::VertexAttribI4uiv(napi_env env, GLuint index, napi_value data)
1198 {
1199 VertexAttribInfo* info = GetVertexAttribInfo(index);
1200 if (info == nullptr) {
1201 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1202 return NVal::CreateNull(env).val_;
1203 }
1204 WebGLReadBufferArg bufferData(env);
1205 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_UINT_32);
1206 if (status != 0) {
1207 LOGE("WebGL vertexAttribI4uiv failed to getbuffer data");
1208 return NVal::CreateNull(env).val_;
1209 }
1210 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1211 if (bufferData.GetBufferDataType() != BUFFER_DATA_UINT_32) {
1212 LOGE("WebGL2 vertexAttribI4uiv invalid data type %{public}d", bufferData.GetBufferDataType());
1213 return NVal::CreateNull(env).val_;
1214 }
1215 glVertexAttribI4uiv(index, reinterpret_cast<const GLuint*>(bufferData.GetBuffer()));
1216 info->type = BUFFER_DATA_UINT_32;
1217 return NVal::CreateNull(env).val_;
1218 }
1219
VertexAttribIPointer(napi_env env,const VertexAttribArg & vertexInfo)1220 napi_value WebGL2RenderingContextImpl::VertexAttribIPointer(napi_env env, const VertexAttribArg& vertexInfo)
1221 {
1222 vertexInfo.Dump("WebGL2 vertexAttribPointer");
1223 if (!CheckGLenum(vertexInfo.type,
1224 { GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT }, {})) {
1225 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1226 "WebGL vertexAttribPointer invalid type %{public}u", vertexInfo.type);
1227 }
1228
1229 GLenum result = CheckVertexAttribPointer(env, vertexInfo);
1230 if (result) {
1231 SET_ERROR(result);
1232 return NVal::CreateNull(env).val_;
1233 }
1234
1235 glVertexAttribIPointer(vertexInfo.index, vertexInfo.size, vertexInfo.type, vertexInfo.stride,
1236 reinterpret_cast<GLvoid*>(vertexInfo.offset));
1237 LOGD("WebGL vertexAttribPointer index %{public}u offset %{public}u",
1238 static_cast<unsigned int>(vertexInfo.index), static_cast<unsigned int>(vertexInfo.offset));
1239 return NVal::CreateNull(env).val_;
1240 }
1241
VertexAttribDivisor(napi_env env,GLuint index,GLuint divisor)1242 napi_value WebGL2RenderingContextImpl::VertexAttribDivisor(napi_env env, GLuint index, GLuint divisor)
1243 {
1244 LOGD("WebGL2 vertexAttribDivisor index %{public}u divisor %{public}u", index, divisor);
1245 if (index >= GetMaxVertexAttribs()) {
1246 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1247 "WebGL2 vertexAttribDivisor invalid index %{public}u", index);
1248 return NVal::CreateNull(env).val_;
1249 }
1250 glVertexAttribDivisor(index, divisor);
1251 return NVal::CreateNull(env).val_;
1252 }
1253
DrawBuffers(napi_env env,napi_value dataObj)1254 napi_value WebGL2RenderingContextImpl::DrawBuffers(napi_env env, napi_value dataObj)
1255 {
1256 WebGLReadBufferArg bufferData(env);
1257 napi_status status = bufferData.GenBufferData(dataObj, BUFFER_DATA_GLENUM);
1258 if (status != 0) {
1259 LOGE("WebGL glDrawBuffers failed to getbuffer data");
1260 return NVal::CreateNull(env).val_;
1261 }
1262 if (bufferData.GetBufferType() != BUFFER_ARRAY) {
1263 LOGE("WebGL glDrawBuffers invalid buffer type %d", bufferData.GetBufferType());
1264 return NVal::CreateNull(env).val_;
1265 }
1266 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1267 GLenum* data = reinterpret_cast<GLenum*>(bufferData.GetBuffer());
1268 GLsizei length = static_cast<GLsizei>(bufferData.GetBufferLength() / sizeof(GLenum));
1269 glDrawBuffers(length, data);
1270 return NVal::CreateNull(env).val_;
1271 }
1272
DrawArraysInstanced(napi_env env,GLenum mode,GLint first,GLsizei count,GLsizei instanceCount)1273 napi_value WebGL2RenderingContextImpl::DrawArraysInstanced(
1274 napi_env env, GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1275 {
1276 LOGD("WebGL drawArraysInstanced mode %{public}u %{public}d %{public}d %{public}d",
1277 mode, first, count, instanceCount);
1278 GLenum result = CheckDrawArrays(env, mode, first, count);
1279 if (result != WebGLRenderingContextBase::NO_ERROR) {
1280 SET_ERROR_WITH_LOG(result, "CheckDrawArrays failed");
1281 return NVal::CreateNull(env).val_;
1282 }
1283 if (instanceCount < 0) {
1284 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "instanceCount < 0");
1285 return NVal::CreateNull(env).val_;
1286 }
1287 glDrawArraysInstanced(mode, first, count, instanceCount);
1288 return NVal::CreateNull(env).val_;
1289 }
1290
DrawElementsInstanced(napi_env env,const DrawElementArg & arg,GLsizei instanceCount)1291 napi_value WebGL2RenderingContextImpl::DrawElementsInstanced(
1292 napi_env env, const DrawElementArg& arg, GLsizei instanceCount)
1293 {
1294 LOGD("WebGL2 drawElementsInstanced mode %{public}u %{public}d %{public}u", arg.mode, arg.count, arg.type);
1295 GLenum result = CheckDrawElements(env, arg.mode, arg.count, arg.type, arg.offset);
1296 if (result != WebGLRenderingContextBase::NO_ERROR) {
1297 SET_ERROR_WITH_LOG(result, "CheckDrawElements failed");
1298 return NVal::CreateNull(env).val_;
1299 }
1300 if (instanceCount < 0) {
1301 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "instanceCount < 0");
1302 return NVal::CreateNull(env).val_;
1303 }
1304 glDrawElementsInstanced(arg.mode, arg.count, arg.type, reinterpret_cast<GLvoid*>(arg.offset), instanceCount);
1305 return NVal::CreateNull(env).val_;
1306 }
1307
DrawRangeElements(napi_env env,const DrawElementArg & arg,GLuint start,GLuint end)1308 napi_value WebGL2RenderingContextImpl::DrawRangeElements(
1309 napi_env env, const DrawElementArg& arg, GLuint start, GLuint end)
1310 {
1311 LOGD("WebGL2 drawRangeElements mode %{public}u %{public}d %{public}u start [%{public}u %{public}u]"
1312 "%{public}d" PRIi64, arg.mode, arg.count, arg.type, start, end, static_cast<int>(arg.offset));
1313 GLenum result = CheckDrawElements(env, arg.mode, arg.count, arg.type, arg.offset);
1314 if (result != WebGLRenderingContextBase::NO_ERROR) {
1315 SET_ERROR(result);
1316 return NVal::CreateNull(env).val_;
1317 }
1318 glDrawRangeElements(arg.mode, start, end, arg.count, arg.type, reinterpret_cast<GLvoid*>(arg.offset));
1319 return NVal::CreateNull(env).val_;
1320 }
1321
CopyBufferSubData(napi_env env,GLenum targets[2],int64_t readOffset,int64_t writeOffset,int64_t size)1322 napi_value WebGL2RenderingContextImpl::CopyBufferSubData(
1323 napi_env env, GLenum targets[2], int64_t readOffset, int64_t writeOffset, int64_t size)
1324 {
1325 LOGD("WebGL2 copyBufferSubData targets [%{public}u %{public}u] offset"
1326 " [%{public}" PRIi64 " %{public}" PRIi64 "] %{public}" PRIi64,
1327 targets[0], targets[1], readOffset, writeOffset, size);
1328 if (!WebGLArg::CheckNoneNegInt<GLint>(readOffset) || !WebGLArg::CheckNoneNegInt<GLint>(writeOffset) ||
1329 !WebGLArg::CheckNoneNegInt<GLint>(size)) {
1330 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "CheckNoneNegInt failed");
1331 return NVal::CreateNull(env).val_;
1332 }
1333 WebGLBuffer* readBuffer = GetBoundBuffer(env, targets[0]); // read
1334 if (readBuffer == nullptr || readBuffer->GetBufferSize() == 0) {
1335 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "readBuffer is nullptr or size is 0");
1336 return NVal::CreateNull(env).val_;
1337 }
1338 WebGLBuffer* writeBuffer = GetBoundBuffer(env, targets[1]); // write
1339 if (writeBuffer == nullptr || writeBuffer->GetBufferSize() == 0) {
1340 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "writeBuffer is nullptr or size is 0");
1341 return NVal::CreateNull(env).val_;
1342 }
1343 if (readOffset + size > static_cast<int64_t>(readBuffer->GetBufferSize()) ||
1344 writeOffset + size > static_cast<int64_t>(writeBuffer->GetBufferSize())) {
1345 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "readOffset or writeOffset size error");
1346 return NVal::CreateNull(env).val_;
1347 }
1348 if ((writeBuffer->GetTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffer->GetTarget() != GL_ELEMENT_ARRAY_BUFFER) ||
1349 (writeBuffer->GetTarget() != GL_ELEMENT_ARRAY_BUFFER && readBuffer->GetTarget() == GL_ELEMENT_ARRAY_BUFFER)) {
1350 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "readOffset or writeOffset GetTarget failed");
1351 return NVal::CreateNull(env).val_;
1352 }
1353 if (writeBuffer->GetTarget() == 0) {
1354 writeBuffer->SetTarget(readBuffer->GetTarget());
1355 }
1356 glCopyBufferSubData(targets[0], targets[1], static_cast<GLintptr>(readOffset), static_cast<GLintptr>(writeOffset),
1357 static_cast<GLsizeiptr>(size));
1358 LOGD("WebGL2 copyBufferSubData result %{public}u", GetError_());
1359 return NVal::CreateNull(env).val_;
1360 }
1361
GetBufferSubData(napi_env env,GLenum target,int64_t offset,napi_value data,const BufferExt & ext)1362 napi_value WebGL2RenderingContextImpl::GetBufferSubData(
1363 napi_env env, GLenum target, int64_t offset, napi_value data, const BufferExt& ext)
1364 {
1365 LOGD("WebGL2 getBufferSubData target %{public}u %{public}" PRIi64, target, offset);
1366 WebGLReadBufferArg bufferData(env);
1367 napi_status status = bufferData.GenBufferData(data);
1368 if (status != 0 || bufferData.GetBufferType() == BUFFER_ARRAY) {
1369 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "check buffer failed");
1370 return NVal::CreateNull(env).val_;
1371 }
1372 if (!WebGLArg::CheckNoneNegInt<GLint>(offset)) {
1373 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "CheckNoneNegInt failed");
1374 return NVal::CreateNull(env).val_;
1375 }
1376 WebGLBuffer* writeBuffer = GetBoundBuffer(env, target);
1377 if (writeBuffer == nullptr || writeBuffer->GetBufferSize() == 0) {
1378 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "no buffer");
1379 return NVal::CreateNull(env).val_;
1380 }
1381 if (static_cast<size_t>(offset) + bufferData.GetBufferLength() > writeBuffer->GetBufferSize()) {
1382 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "check buffer size failed");
1383 return NVal::CreateNull(env).val_;
1384 }
1385 GLsizeiptr dstSize = (ext.length == 0) ? static_cast<GLsizeiptr>(bufferData.GetBufferLength())
1386 : static_cast<GLsizeiptr>(ext.length * bufferData.GetBufferDataSize());
1387 GLuint dstOffset = static_cast<GLuint>(ext.offset * bufferData.GetBufferDataSize());
1388 LOGD("WebGL2 getBufferSubData dstSize %{public}u dstOffset %{public}p",
1389 static_cast<unsigned int>(dstSize), writeBuffer->bufferData_);
1390
1391 void *mapBuffer = glMapBufferRange(target, static_cast<GLintptr>(offset), dstSize, GL_MAP_READ_BIT);
1392 if (mapBuffer == nullptr ||
1393 memcpy_s(bufferData.GetBuffer() + dstOffset, bufferData.GetBufferLength(), mapBuffer, dstSize) != 0) {
1394 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "mapBuffer is nullptr");
1395 }
1396 glUnmapBuffer(target);
1397 LOGD("WebGL2 getBufferSubData target %{public}u result %{public}u ", target, GetError_());
1398 return NVal::CreateNull(env).val_;
1399 }
1400
BlitFrameBuffer(napi_env env,GLint data[8],GLbitfield mask,GLenum filter)1401 napi_value WebGL2RenderingContextImpl::BlitFrameBuffer(napi_env env, GLint data[8], GLbitfield mask, GLenum filter)
1402 {
1403 // 0,1,2,3,4,5,6,7 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1
1404 glBlitFramebuffer(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], mask, filter);
1405 LOGD("WebGL2 blitFrameBuffer filter %{public}u result %{public}u ", filter, GetError_());
1406 return NVal::CreateNull(env).val_;
1407 }
1408
FrameBufferTextureLayer(napi_env env,GLenum target,GLenum attachment,napi_value textureObj,const TextureLayerArg & layer)1409 napi_value WebGL2RenderingContextImpl::FrameBufferTextureLayer(
1410 napi_env env, GLenum target, GLenum attachment, napi_value textureObj, const TextureLayerArg& layer)
1411 {
1412 int32_t textureId = WebGLTexture::DEFAULT_TEXTURE;
1413 WebGLTexture* webGlTexture = WebGLTexture::GetObjectInstance(env, textureObj);
1414 if (webGlTexture == nullptr) {
1415 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1416 return NVal::CreateNull(env).val_;
1417 }
1418 textureId = static_cast<int32_t>(webGlTexture->GetTexture());
1419 glFramebufferTextureLayer(target, attachment, textureId, layer.level, layer.layer);
1420 LOGD("WebGL frameBufferTextureLayer texture %{public}d result %{public}u", textureId, GetError_());
1421
1422 WebGLFramebuffer* frameBuffer = GetBoundFrameBuffer(env, target);
1423 if (frameBuffer == nullptr) {
1424 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "can not find bind frame buffer");
1425 return NVal::CreateNull(env).val_;
1426 }
1427 frameBuffer->AddAttachment(
1428 target, attachment, static_cast<GLuint>(textureId), webGlTexture->GetTarget(), layer.level);
1429 return NVal::CreateNull(env).val_;
1430 }
1431
ReadBuffer(napi_env env,GLenum mode)1432 napi_value WebGL2RenderingContextImpl::ReadBuffer(napi_env env, GLenum mode)
1433 {
1434 LOGD("WebGL2 readBuffer mode %{public}u", mode);
1435 if (!CheckReadBufferMode(mode)) {
1436 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckReadBufferMode failed");
1437 return NVal::CreateNull(env).val_;
1438 }
1439
1440 WebGLFramebuffer* readFrameBuffer = GetBoundFrameBuffer(env, WebGL2RenderingContextBase::READ_FRAMEBUFFER);
1441 if (readFrameBuffer == nullptr) {
1442 if (mode != WebGLRenderingContextBase::BACK && mode != WebGLRenderingContextBase::NONE) {
1443 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION,
1444 "readFrameBuffer is nullptr, mode %{public}u", mode);
1445 return NVal::CreateNull(env).val_;
1446 }
1447 defaultReadBufferMode_ = mode;
1448 if (mode == WebGLRenderingContextBase::BACK) {
1449 mode = WebGLRenderingContextBase::COLOR_ATTACHMENT0;
1450 }
1451 } else {
1452 if (mode == WebGLRenderingContextBase::BACK) {
1453 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "mode %{public}u", mode);
1454 return NVal::CreateNull(env).val_;
1455 }
1456 readFrameBuffer->SetReadBufferMode(mode);
1457 }
1458 glReadBuffer(mode);
1459 return NVal::CreateNull(env).val_;
1460 }
1461
RenderBufferStorageMultiSample(napi_env env,const TexStorageArg & arg,GLsizei samples)1462 napi_value WebGL2RenderingContextImpl::RenderBufferStorageMultiSample(
1463 napi_env env, const TexStorageArg& arg, GLsizei samples)
1464 {
1465 arg.Dump("WebGL2 renderbufferStorageMultisample");
1466 LOGD("WebGL2 renderbufferStorageMultisample samples %{public}d", samples);
1467
1468 WebGLRenderbuffer* renderBuffer = CheckRenderBufferStorage(env, arg);
1469 if (renderBuffer == nullptr) {
1470 return NVal::CreateNull(env).val_;
1471 }
1472 if (samples < 0) {
1473 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "samples < 0");
1474 return NVal::CreateNull(env).val_;
1475 }
1476 if (arg.internalFormat == GL_DEPTH_STENCIL) {
1477 if (samples > 0) {
1478 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "GL_DEPTH_STENCIL samples > 0");
1479 return NVal::CreateNull(env).val_;
1480 }
1481 glRenderbufferStorage(arg.target, GL_DEPTH24_STENCIL8, arg.width, arg.height);
1482 } else {
1483 if (CheckInList(arg.internalFormat, WebGLTexture::GetSupportInternalFormatGroup1())) {
1484 if (samples > 0) {
1485 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckInList group1 failed");
1486 return NVal::CreateNull(env).val_;
1487 }
1488 } else if (!CheckInList(arg.internalFormat, WebGLTexture::GetSupportInternalFormatGroup2())) {
1489 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckInList group2 failed");
1490 return NVal::CreateNull(env).val_;
1491 }
1492 if (samples == 0) {
1493 glRenderbufferStorage(arg.target, arg.internalFormat, arg.width, arg.height);
1494 } else {
1495 glRenderbufferStorageMultisample(arg.target, samples, arg.internalFormat, arg.width, arg.height);
1496 }
1497 }
1498 renderBuffer->SetInternalFormat(arg.internalFormat);
1499 renderBuffer->SetSize(arg.width, arg.height);
1500 LOGD("WebGL2 renderbufferStorageMultisample result %{public}u", GetError_());
1501 return NVal::CreateNull(env).val_;
1502 }
1503
BindBuffer(napi_env env,GLenum target,napi_value object)1504 napi_value WebGL2RenderingContextImpl::BindBuffer(napi_env env, GLenum target, napi_value object)
1505 {
1506 // support default value
1507 uint32_t bufferId = WebGLBuffer::DEFAULT_BUFFER;
1508 WebGLBuffer* webGlBuffer = GetValidBuffer(env, object);
1509 if (webGlBuffer != nullptr) {
1510 bufferId = webGlBuffer->GetBufferId();
1511 }
1512 uint32_t index = BoundBufferType::ARRAY_BUFFER;
1513 if (!CheckBufferTarget(env, target, index)) {
1514 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1515 return NVal::CreateNull(env).val_;
1516 }
1517 if (webGlBuffer != nullptr && !CheckBufferTargetCompatibility(env, target, webGlBuffer)) {
1518 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
1519 return NVal::CreateNull(env).val_;
1520 }
1521 if (boundBufferIds_[index] && boundBufferIds_[index] != bufferId) {
1522 LOGD("WebGL2 bindBuffer has been bound bufferId %{public}u", boundBufferIds_[index]);
1523 }
1524 boundBufferIds_[index] = bufferId;
1525
1526 glBindBuffer(target, static_cast<GLuint>(bufferId));
1527 if (webGlBuffer) {
1528 webGlBuffer->SetTarget(target);
1529 }
1530 LOGD("WebGL2 bindBuffer target %{public}u bufferId %{public}u result %{public}u",
1531 target, bufferId, GetError_());
1532 return NVal::CreateNull(env).val_;
1533 }
1534
BindBufferBase(napi_env env,const BufferBaseArg & arg,napi_value bufferObj)1535 napi_value WebGL2RenderingContextImpl::BindBufferBase(napi_env env, const BufferBaseArg& arg, napi_value bufferObj)
1536 {
1537 GLuint bufferId = WebGLBuffer::DEFAULT_BUFFER;
1538 WebGLBuffer* webGlBuffer = GetValidBuffer(env, bufferObj);
1539 if (webGlBuffer != nullptr) {
1540 bufferId = webGlBuffer->GetBufferId();
1541 }
1542 if (!CheckBufferBindTarget(arg.target)) {
1543 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckBufferBindTarget failed");
1544 return NVal::CreateNull(env).val_;
1545 }
1546 if (webGlBuffer != nullptr && !CheckBufferTargetCompatibility(env, arg.target, webGlBuffer)) {
1547 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckBufferTargetCompatibility failed");
1548 return NVal::CreateNull(env).val_;
1549 }
1550 if (!UpdateBaseTargetBoundBuffer(env, arg.target, arg.index, bufferId)) {
1551 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "UpdateBaseTargetBoundBuffer failed");
1552 return NVal::CreateNull(env).val_;
1553 }
1554 if (webGlBuffer != nullptr && !webGlBuffer->GetTarget()) {
1555 webGlBuffer->SetTarget(arg.target);
1556 }
1557 glBindBufferBase(arg.target, arg.index, bufferId);
1558 LOGD("WebGL2 bindBufferBase target %{public}u %{public}u %{public}u result %{public}u ",
1559 arg.target, arg.index, bufferId, GetError_());
1560 return NVal::CreateNull(env).val_;
1561 }
1562
BindBufferRange(napi_env env,const BufferBaseArg & arg,napi_value bufferObj,GLintptr offset,GLsizeiptr size)1563 napi_value WebGL2RenderingContextImpl::BindBufferRange(
1564 napi_env env, const BufferBaseArg& arg, napi_value bufferObj, GLintptr offset, GLsizeiptr size)
1565 {
1566 GLuint bufferId = WebGLBuffer::DEFAULT_BUFFER;
1567 WebGLBuffer* webGlBuffer = GetValidBuffer(env, bufferObj);
1568 if (webGlBuffer != nullptr) {
1569 bufferId = webGlBuffer->GetBufferId();
1570 }
1571 if (!CheckBufferBindTarget(arg.target)) {
1572 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckBufferBindTarget failed");
1573 return NVal::CreateNull(env).val_;
1574 }
1575 if (webGlBuffer != nullptr && !CheckBufferTargetCompatibility(env, arg.target, webGlBuffer)) {
1576 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckBufferTargetCompatibility failed");
1577 return NVal::CreateNull(env).val_;
1578 }
1579 if (!UpdateBaseTargetBoundBuffer(env, arg.target, arg.index, bufferId)) {
1580 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "UpdateBaseTargetBoundBuffer failed");
1581 return NVal::CreateNull(env).val_;
1582 }
1583 if (webGlBuffer != nullptr && !webGlBuffer->GetTarget()) {
1584 webGlBuffer->SetTarget(arg.target);
1585 }
1586 LOGD("WebGL2 bindBufferRange target %{public}u %{public}u %{public}u", arg.target, arg.index, bufferId);
1587 glBindBufferRange(arg.target, arg.index, bufferId, offset, size);
1588 return NVal::CreateNull(env).val_;
1589 }
1590
DeleteBuffer(napi_env env,napi_value object)1591 napi_value WebGL2RenderingContextImpl::DeleteBuffer(napi_env env, napi_value object)
1592 {
1593 return WebGLRenderingContextBaseImpl::DeleteBuffer(env, object);
1594 }
1595
GetUniformBlockIndex(napi_env env,napi_value programObj,const std::string & uniformBlockName)1596 napi_value WebGL2RenderingContextImpl::GetUniformBlockIndex(
1597 napi_env env, napi_value programObj, const std::string& uniformBlockName)
1598 {
1599 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1600 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1601 if (webGLProgram == nullptr) {
1602 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "webGLProgram is nullptr");
1603 return NVal::CreateInt64(env, -1).val_;
1604 }
1605 programId = webGLProgram->GetProgramId();
1606 if (!WebGLArg::CheckString(uniformBlockName)) {
1607 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "CheckString failed");
1608 return NVal::CreateInt64(env, -1).val_;
1609 }
1610 GLuint returnValue = glGetUniformBlockIndex(programId, uniformBlockName.c_str());
1611 LOGD("WebGL2 getUniformBlockIndex name %{public}s programId %{public}u result %{public}u",
1612 uniformBlockName.c_str(), programId, returnValue);
1613 return NVal::CreateInt64(env, returnValue).val_;
1614 }
1615
UniformBlockBinding(napi_env env,napi_value programObj,GLuint uniformBlockIndex,GLuint uniformBlockBinding)1616 napi_value WebGL2RenderingContextImpl::UniformBlockBinding(
1617 napi_env env, napi_value programObj, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
1618 {
1619 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1620 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1621 if (webGLProgram == nullptr) {
1622 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1623 return NVal::CreateNull(env).val_;
1624 }
1625 programId = webGLProgram->GetProgramId();
1626 glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding);
1627 LOGD("WebGL2 uniformBlockBinding programId %{public}u %{public}u %{public}u result %{public}u",
1628 programId, uniformBlockIndex, uniformBlockBinding, GetError_());
1629 return NVal::CreateNull(env).val_;
1630 }
1631
InvalidateFrameBuffer(napi_env env,GLenum target,napi_value data)1632 napi_value WebGL2RenderingContextImpl::InvalidateFrameBuffer(napi_env env, GLenum target, napi_value data)
1633 {
1634 LOGD("WebGL2 invalidate Framebuffer target %{public}u", target);
1635 WebGLReadBufferArg bufferData(env);
1636 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_GLENUM);
1637 if (status != 0) {
1638 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1639 "WebGL2 invalidateFramebuffer failed to getbuffer data");
1640 return NVal::CreateNull(env).val_;
1641 }
1642 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1643 if (bufferData.GetBufferDataType() != BUFFER_DATA_GLENUM) {
1644 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1645 "WebGL2 invalidateFramebuffer invalid data type %{public}u", bufferData.GetBufferDataType());
1646 return NVal::CreateNull(env).val_;
1647 }
1648 if (bufferData.GetBufferType() != BUFFER_ARRAY) {
1649 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1650 "WebGL2 invalidateFramebuffer invalid type %{public}u", bufferData.GetBufferType());
1651 return NVal::CreateNull(env).val_;
1652 }
1653 glInvalidateFramebuffer(target, static_cast<GLsizei>(bufferData.GetBufferLength() / sizeof(GLenum)),
1654 reinterpret_cast<GLenum*>(bufferData.GetBuffer()));
1655 return NVal::CreateNull(env).val_;
1656 }
1657
InvalidateSubFrameBuffer(napi_env env,GLenum target,napi_value data,const BufferPosition & position,const BufferSize & size)1658 napi_value WebGL2RenderingContextImpl::InvalidateSubFrameBuffer(
1659 napi_env env, GLenum target, napi_value data, const BufferPosition& position, const BufferSize& size)
1660 {
1661 WebGLReadBufferArg bufferData(env);
1662 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_GLENUM);
1663 if (status != 0) {
1664 LOGE("WebGL2 invalidateFramebuffer failed to getbuffer data");
1665 return NVal::CreateNull(env).val_;
1666 }
1667 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1668 if (bufferData.GetBufferDataType() != BUFFER_DATA_GLENUM) {
1669 LOGE("WebGL2 invalidateFramebuffer invalid data type %{public}d", bufferData.GetBufferDataType());
1670 return NVal::CreateNull(env).val_;
1671 }
1672 if (bufferData.GetBufferType() != BUFFER_ARRAY) {
1673 LOGE("WebGL2 invalidateFramebuffer invalid type %{public}d", bufferData.GetBufferType());
1674 return NVal::CreateNull(env).val_;
1675 }
1676
1677 glInvalidateSubFramebuffer(target, static_cast<GLsizei>(bufferData.GetBufferLength() / sizeof(GLenum)),
1678 reinterpret_cast<GLenum*>(bufferData.GetBuffer()), position.x, position.y, size.width, size.height);
1679 return NVal::CreateNull(env).val_;
1680 }
1681
GetInternalFormatParameter(napi_env env,GLenum target,GLenum internalFormat,GLenum pname)1682 napi_value WebGL2RenderingContextImpl::GetInternalFormatParameter(
1683 napi_env env, GLenum target, GLenum internalFormat, GLenum pname)
1684 {
1685 if (target != WebGLRenderingContextBase::RENDERBUFFER) {
1686 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "target %{publuc}u", target);
1687 return NVal::CreateNull(env).val_;
1688 }
1689 LOGD("WebGL2 getInternalformatParameter target %{public}u %{public}u %{public}u", target, internalFormat, pname);
1690 WebGLWriteBufferArg writeBuffer(env);
1691 if (CheckInList(internalFormat, WebGLTexture::GetSupportInternalFormatGroup1())) {
1692 return writeBuffer.ToExternalArray(BUFFER_DATA_INT_32);
1693 } else if (!CheckInList(internalFormat, WebGLTexture::GetSupportInternalFormatGroup2())) {
1694 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckInList failed");
1695 return NVal::CreateNull(env).val_;
1696 }
1697
1698 GLint length = -1;
1699 if (pname == GL_SAMPLES) {
1700 glGetInternalformativ(target, internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &length);
1701 LOGD("WebGL2 getInternalformatParameter length %{public}u", length);
1702 } else {
1703 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "pname %{publuc}u", pname);
1704 return NVal::CreateNull(env).val_;
1705 }
1706 if (length > 0) {
1707 GLint* params = reinterpret_cast<GLint*>(writeBuffer.AllocBuffer(length * sizeof(GLint)));
1708 if (params == nullptr) {
1709 return NVal::CreateNull(env).val_;
1710 }
1711 glGetInternalformativ(target, internalFormat, pname, length, params);
1712 writeBuffer.DumpBuffer(BUFFER_DATA_INT_32);
1713 }
1714 return writeBuffer.ToExternalArray(BUFFER_DATA_INT_32);
1715 }
1716
TransformFeedbackVaryings(napi_env env,napi_value programObj,napi_value data,GLenum bufferMode)1717 napi_value WebGL2RenderingContextImpl::TransformFeedbackVaryings(
1718 napi_env env, napi_value programObj, napi_value data, GLenum bufferMode)
1719 {
1720 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1721 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1722 if (webGLProgram == nullptr) {
1723 return NVal::CreateNull(env).val_;
1724 }
1725 programId = webGLProgram->GetProgramId();
1726 if (bufferMode != GL_INTERLEAVED_ATTRIBS && bufferMode != GL_SEPARATE_ATTRIBS) {
1727 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1728 return NVal::CreateNull(env).val_;
1729 }
1730 std::vector<char*> list = {};
1731 bool succ = WebGLArg::GetStringList(env, data, list);
1732 if (!succ) {
1733 WebGLArg::FreeStringList(list);
1734 return NVal::CreateNull(env).val_;
1735 }
1736 glTransformFeedbackVaryings(programId, static_cast<GLsizei>(list.size()), list.data(), bufferMode);
1737 WebGLArg::FreeStringList(list);
1738 return NVal::CreateNull(env).val_;
1739 }
1740
GetUniformIndices(napi_env env,napi_value programObj,napi_value data)1741 napi_value WebGL2RenderingContextImpl::GetUniformIndices(napi_env env, napi_value programObj, napi_value data)
1742 {
1743 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1744 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1745 if (webGLProgram == nullptr) {
1746 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1747 return NVal::CreateNull(env).val_;
1748 }
1749 programId = webGLProgram->GetProgramId();
1750
1751 std::vector<char*> list = {};
1752 bool succ = WebGLArg::GetStringList(env, data, list);
1753 if (!succ) {
1754 WebGLArg::FreeStringList(list);
1755 return NVal::CreateNull(env).val_;
1756 }
1757 LOGD("WebGL2 getUniformIndices uniformCount %{public}zu", list.size());
1758
1759 WebGLWriteBufferArg writeBuffer(env);
1760 napi_value result = NVal::CreateNull(env).val_;
1761 GLuint* uniformIndices = reinterpret_cast<GLuint*>(writeBuffer.AllocBuffer(list.size() * sizeof(GLuint)));
1762 if (uniformIndices != nullptr) {
1763 glGetUniformIndices(programId, static_cast<GLsizei>(list.size()), const_cast<const GLchar**>(list.data()),
1764 static_cast<GLuint*>(uniformIndices));
1765 writeBuffer.DumpBuffer(BUFFER_DATA_UINT_32);
1766 result = writeBuffer.ToNormalArray(BUFFER_DATA_UINT_32, BUFFER_DATA_UINT_32);
1767 }
1768 WebGLArg::FreeStringList(list);
1769 return result;
1770 }
1771
GetActiveUniforms(napi_env env,napi_value programObj,napi_value data,GLenum pname)1772 napi_value WebGL2RenderingContextImpl::GetActiveUniforms(
1773 napi_env env, napi_value programObj, napi_value data, GLenum pname)
1774 {
1775 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1776 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1777 if (webGLProgram == nullptr) {
1778 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1779 return NVal::CreateNull(env).val_;
1780 }
1781 if (pname == GL_UNIFORM_NAME_LENGTH) {
1782 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1783 return NVal::CreateNull(env).val_;
1784 }
1785
1786 programId = webGLProgram->GetProgramId();
1787 LOGD("WebGL2 getActiveUniforms programId %{public}u pname %{public}u", programId, pname);
1788 WebGLReadBufferArg bufferData(env);
1789 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_UINT_32);
1790 if (status != 0) {
1791 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1792 "WebGL2 invalidateFramebuffer failed to getbuffer data");
1793 return NVal::CreateNull(env).val_;
1794 }
1795 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1796 GLsizei size = static_cast<GLsizei>(bufferData.GetBufferLength() / bufferData.GetBufferDataSize());
1797
1798 WebGLWriteBufferArg writeBuffer(env);
1799 GLint* params = reinterpret_cast<GLint*>(writeBuffer.AllocBuffer(size * sizeof(GLint)));
1800 if (params == nullptr) {
1801 return NVal::CreateNull(env).val_;
1802 }
1803 glGetActiveUniformsiv(
1804 programId, size, reinterpret_cast<GLuint*>(bufferData.GetBuffer()), pname, reinterpret_cast<GLint*>(params));
1805 switch (pname) {
1806 case GL_UNIFORM_TYPE:
1807 case GL_UNIFORM_SIZE:
1808 return writeBuffer.ToNormalArray(BUFFER_DATA_INT_32, BUFFER_DATA_BIGUINT_64);
1809 case GL_UNIFORM_BLOCK_INDEX:
1810 case GL_UNIFORM_OFFSET:
1811 case GL_UNIFORM_ARRAY_STRIDE:
1812 case GL_UNIFORM_MATRIX_STRIDE:
1813 return writeBuffer.ToNormalArray(BUFFER_DATA_INT_32, BUFFER_DATA_INT_32);
1814 case GL_UNIFORM_IS_ROW_MAJOR:
1815 return writeBuffer.ToNormalArray(BUFFER_DATA_INT_32, BUFFER_DATA_BOOLEAN);
1816 default:
1817 break;
1818 }
1819 return NVal::CreateNull(env).val_;
1820 }
1821
GetActiveUniformBlockParameter(napi_env env,napi_value programObj,GLuint uniformBlockIndex,GLenum pname)1822 napi_value WebGL2RenderingContextImpl::GetActiveUniformBlockParameter(
1823 napi_env env, napi_value programObj, GLuint uniformBlockIndex, GLenum pname)
1824 {
1825 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1826 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1827 if (webGLProgram == nullptr) {
1828 return NVal::CreateInt64(env, -1).val_;
1829 }
1830 programId = webGLProgram->GetProgramId();
1831 LOGD("WebGL2 getActiveUniformBlockParameter programId %{public}u %{public}u %{public}u",
1832 programId, uniformBlockIndex, pname);
1833 switch (pname) {
1834 case GL_UNIFORM_BLOCK_BINDING:
1835 case GL_UNIFORM_BLOCK_DATA_SIZE:
1836 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
1837 GLint params;
1838 glGetActiveUniformBlockiv(programId, uniformBlockIndex, pname, ¶ms);
1839 return NVal::CreateInt64(env, params).val_;
1840 }
1841 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
1842 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: {
1843 GLint params;
1844 glGetActiveUniformBlockiv(programId, uniformBlockIndex, pname, ¶ms);
1845 return NVal::CreateBool(env, params != GL_FALSE).val_;
1846 }
1847 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: {
1848 WebGLWriteBufferArg writeBuffer(env);
1849 GLint uniformCount = 1;
1850 glGetActiveUniformBlockiv(programId, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformCount);
1851 LOGD("WebGL2 getActiveUniformBlockParameter uniformCount %{public}d", uniformCount);
1852 GLint* params = reinterpret_cast<GLint*>(writeBuffer.AllocBuffer(uniformCount * sizeof(GLint)));
1853 if (params == nullptr) {
1854 return NVal::CreateNull(env).val_;
1855 }
1856 glGetActiveUniformBlockiv(programId, uniformBlockIndex, pname, params);
1857 return writeBuffer.ToNormalArray(BUFFER_DATA_INT_32, BUFFER_DATA_UINT_32);
1858 }
1859 default:
1860 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1861 return NVal::CreateNull(env).val_;
1862 }
1863 return NVal::CreateInt64(env, -1).val_;
1864 }
1865
GetActiveUniformBlockName(napi_env env,napi_value programObj,GLuint uniformBlockIndex)1866 napi_value WebGL2RenderingContextImpl::GetActiveUniformBlockName(
1867 napi_env env, napi_value programObj, GLuint uniformBlockIndex)
1868 {
1869 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1870 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1871 if (webGLProgram == nullptr) {
1872 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "webGLProgram is nullptr");
1873 return NVal::CreateUTF8String(env, "").val_;
1874 }
1875 programId = webGLProgram->GetProgramId();
1876
1877 GLint length = 0;
1878 GLsizei size = 0;
1879 glGetProgramiv(programId, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &length);
1880 if (length <= 0) {
1881 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "length < 0");
1882 return NVal::CreateUTF8String(env, "").val_;
1883 }
1884 std::unique_ptr<char[]> buf = std::make_unique<char[]>(length + 1);
1885 if (buf == nullptr) {
1886 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "buf is nullptr");
1887 return NVal::CreateNull(env).val_;
1888 }
1889 glGetActiveUniformBlockName(programId, uniformBlockIndex, length, &size, buf.get());
1890 LOGD("WebGL2 getActiveUniformBlockName programId %{public}u uniformBlockIndex %{public}u name %{public}s",
1891 programId, uniformBlockIndex, buf.get());
1892 string str(buf.get(), size);
1893 return NVal::CreateUTF8String(env, str).val_;
1894 }
1895
CheckClearBuffer(napi_env env,GLenum buffer,const WebGLReadBufferArg & bufferData)1896 GLenum WebGL2RenderingContextImpl::CheckClearBuffer(napi_env env, GLenum buffer, const WebGLReadBufferArg& bufferData)
1897 {
1898 size_t size = bufferData.GetBufferLength() / bufferData.GetBufferDataSize();
1899 switch (buffer) {
1900 case WebGL2RenderingContextBase::COLOR:
1901 case WebGLRenderingContextBase::FRONT:
1902 case WebGLRenderingContextBase::BACK:
1903 case WebGLRenderingContextBase::FRONT_AND_BACK:
1904 if (size < 4) { // 4 max element
1905 return WebGLRenderingContextBase::INVALID_VALUE;
1906 }
1907 break;
1908 case WebGL2RenderingContextBase::DEPTH:
1909 case WebGL2RenderingContextBase::STENCIL:
1910 case WebGLRenderingContextBase::DEPTH_STENCIL:
1911 if (size < 1) {
1912 return WebGLRenderingContextBase::INVALID_VALUE;
1913 }
1914 break;
1915 default:
1916 return WebGLRenderingContextBase::INVALID_ENUM;
1917 }
1918 return WebGLRenderingContextBase::NO_ERROR;
1919 }
1920
CheckQueryTarget(napi_env env,GLenum target,uint32_t & index)1921 bool WebGL2RenderingContextImpl::CheckQueryTarget(napi_env env, GLenum target, uint32_t& index)
1922 {
1923 switch (target) {
1924 case WebGL2RenderingContextBase::ANY_SAMPLES_PASSED:
1925 case WebGL2RenderingContextBase::ANY_SAMPLES_PASSED_CONSERVATIVE:
1926 index = BoundQueryType::ANY_SAMPLES_PASSED;
1927 break;
1928 case WebGL2RenderingContextBase::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1929 index = BoundQueryType::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1930 break;
1931 default:
1932 return false;
1933 }
1934 return true;
1935 }
1936
CheckTexStorage(napi_env env,const TexStorageArg & arg)1937 GLenum WebGL2RenderingContextImpl::CheckTexStorage(napi_env env, const TexStorageArg& arg)
1938 {
1939 WebGLTexture* texture = GetBoundTexture(env, arg.target, false);
1940 if (!texture) {
1941 LOGE("CheckTexStorage %{public}u", arg.target);
1942 return WebGLRenderingContextBase::INVALID_OPERATION;
1943 }
1944
1945 if (!CheckStorageInternalFormat(env, arg.internalFormat)) {
1946 return WebGLRenderingContextBase::INVALID_ENUM;
1947 }
1948
1949 if (arg.width <= 0 || arg.height <= 0 || arg.depth <= 0) {
1950 LOGE("CheckTexStorage invalid width %{public}d, height %{public}d, depth %{public}d",
1951 arg.width, arg.height, arg.depth);
1952 return WebGLRenderingContextBase::INVALID_VALUE;
1953 }
1954
1955 if (arg.levels <= 0) {
1956 LOGE("CheckTexStorage invalid levels %{public}d", arg.levels);
1957 return WebGLRenderingContextBase::INVALID_VALUE;
1958 }
1959
1960 if (arg.target == GL_TEXTURE_3D) {
1961 if (arg.levels > log2(std::max(std::max(arg.width, arg.height), arg.depth)) + 1) {
1962 LOGE("CheckTexStorage invalid levels %{public}d", arg.levels);
1963 return WebGLRenderingContextBase::INVALID_OPERATION;
1964 }
1965 } else {
1966 if (arg.levels > log2(std::max(arg.width, arg.height)) + 1) {
1967 LOGE("CheckTexStorage invalid %{public}d %{public}d",
1968 arg.levels, static_cast<int>(log2(std::max(arg.width, arg.height)) + 1));
1969 return WebGLRenderingContextBase::INVALID_OPERATION;
1970 }
1971 }
1972 return WebGLRenderingContextBase::NO_ERROR;
1973 }
1974
CheckBufferBindTarget(GLenum target)1975 bool WebGL2RenderingContextImpl::CheckBufferBindTarget(GLenum target)
1976 {
1977 if (target == GL_TRANSFORM_FEEDBACK_BUFFER || target == GL_UNIFORM_BUFFER) {
1978 return true;
1979 }
1980 return false;
1981 }
1982
CheckTransformFeedbackBuffer(GLenum target,WebGLBuffer * buffer)1983 bool WebGL2RenderingContextImpl::CheckTransformFeedbackBuffer(GLenum target, WebGLBuffer* buffer)
1984 {
1985 if (target == GL_TRANSFORM_FEEDBACK_BUFFER) {
1986 for (size_t i = 0; i < sizeof(boundBufferIds_) / boundBufferIds_[0]; i++) {
1987 if (i == BoundBufferType::TRANSFORM_FEEDBACK_BUFFER) {
1988 continue;
1989 }
1990 if (boundBufferIds_[i] == buffer->GetBufferId()) {
1991 LOGD("boundBufferIds_ %{public}u %{public}zu", boundBufferIds_[i], i);
1992 return false;
1993 }
1994 }
1995 LOGD("boundIndexedUniformBuffers_ %{public}zu", boundIndexedUniformBuffers_.size());
1996 for (size_t i = 0; i < boundIndexedUniformBuffers_.size(); ++i) {
1997 if (boundIndexedUniformBuffers_[i] == buffer->GetBufferId()) {
1998 return false;
1999 }
2000 }
2001 } else {
2002 LOGD("Get TRANSFORM_FEEDBACK_BUFFER id %{public}u ",
2003 boundBufferIds_[BoundBufferType::TRANSFORM_FEEDBACK_BUFFER]);
2004 if (boundBufferIds_[BoundBufferType::TRANSFORM_FEEDBACK_BUFFER] == buffer->GetBufferId()) {
2005 return false;
2006 }
2007 for (size_t i = 0; i < boundIndexedTransformFeedbackBuffers_.size(); ++i) {
2008 if (boundIndexedTransformFeedbackBuffers_[i] == buffer->GetBufferId()) {
2009 return false;
2010 }
2011 }
2012 }
2013 return true;
2014 }
2015
CheckBufferTargetCompatibility(napi_env env,GLenum target,WebGLBuffer * buffer)2016 bool WebGL2RenderingContextImpl::CheckBufferTargetCompatibility(napi_env env, GLenum target, WebGLBuffer* buffer)
2017 {
2018 LOGD("buffer target %{public}u %{public}u id %{public}u", buffer->GetTarget(), target, buffer->GetBufferId());
2019 switch (buffer->GetTarget()) {
2020 case GL_ELEMENT_ARRAY_BUFFER:
2021 switch (target) {
2022 case GL_ARRAY_BUFFER:
2023 case GL_PIXEL_PACK_BUFFER:
2024 case GL_PIXEL_UNPACK_BUFFER:
2025 case GL_TRANSFORM_FEEDBACK_BUFFER:
2026 case GL_UNIFORM_BUFFER:
2027 return false;
2028 default:
2029 break;
2030 }
2031 break;
2032 case GL_ARRAY_BUFFER:
2033 case GL_COPY_READ_BUFFER:
2034 case GL_COPY_WRITE_BUFFER:
2035 case GL_PIXEL_PACK_BUFFER:
2036 case GL_PIXEL_UNPACK_BUFFER:
2037 case GL_UNIFORM_BUFFER:
2038 case GL_TRANSFORM_FEEDBACK_BUFFER:
2039 if (target == GL_ELEMENT_ARRAY_BUFFER) {
2040 return false;
2041 }
2042 break;
2043 default:
2044 break;
2045 }
2046 return CheckTransformFeedbackBuffer(target, buffer);
2047 }
2048
UpdateBaseTargetBoundBuffer(napi_env env,GLenum target,GLuint index,GLuint bufferId)2049 bool WebGL2RenderingContextImpl::UpdateBaseTargetBoundBuffer(
2050 napi_env env, GLenum target, GLuint index, GLuint bufferId)
2051 {
2052 if (target == GL_TRANSFORM_FEEDBACK_BUFFER) {
2053 if (index >= maxBoundTransformFeedbackBufferIndex_) {
2054 LOGE("Out of bound indexed transform feedback buffer %{public}u", index);
2055 return false;
2056 }
2057 boundIndexedTransformFeedbackBuffers_[index] = bufferId;
2058 boundBufferIds_[BoundBufferType::TRANSFORM_FEEDBACK_BUFFER] = bufferId;
2059 if (!bufferId) { // for delete
2060 boundIndexedTransformFeedbackBuffers_.erase(index);
2061 }
2062 return true;
2063 }
2064 if (target == GL_UNIFORM_BUFFER) {
2065 if (index >= maxBoundUniformBufferIndex_) {
2066 LOGE("Out of bound indexed uniform buffer %{public}u", index);
2067 return false;
2068 }
2069 boundIndexedUniformBuffers_[index] = bufferId;
2070 boundBufferIds_[BoundBufferType::UNIFORM_BUFFER] = bufferId;
2071 if (!bufferId) { // for delete
2072 boundIndexedUniformBuffers_.erase(index);
2073 }
2074 return true;
2075 }
2076 return false;
2077 }
2078
CheckStorageInternalFormat(napi_env env,GLenum internalFormat)2079 bool WebGL2RenderingContextImpl::CheckStorageInternalFormat(napi_env env, GLenum internalFormat)
2080 {
2081 return CheckInList(internalFormat, {
2082 GL_R8,
2083 GL_R8_SNORM,
2084 GL_R16F,
2085 GL_R32F,
2086 GL_R8UI,
2087 GL_R8I,
2088 GL_R16UI,
2089 GL_R16I,
2090 GL_R32UI,
2091 GL_R32I,
2092 GL_RG8,
2093 GL_RG8_SNORM,
2094 GL_RG16F,
2095 GL_RG32F,
2096 GL_RG8UI,
2097 GL_RG8I,
2098 GL_RG16UI,
2099 GL_RG16I,
2100 GL_RG32UI,
2101 GL_RG32I,
2102 GL_RGB8,
2103 GL_SRGB8,
2104 GL_RGB565,
2105 GL_RGB8_SNORM,
2106 GL_R11F_G11F_B10F,
2107 GL_RGB9_E5,
2108 GL_RGB16F,
2109 GL_RGB32F,
2110 GL_RGB8UI,
2111 GL_RGB8I,
2112 GL_RGB16UI,
2113 GL_RGB16I,
2114 GL_RGB32UI,
2115 GL_RGB32I,
2116 GL_RGBA8,
2117 GL_SRGB8_ALPHA8,
2118 GL_RGBA8_SNORM,
2119 GL_RGB5_A1,
2120 GL_RGBA4,
2121 GL_RGB10_A2,
2122 GL_RGBA16F,
2123 GL_RGBA32F,
2124 GL_RGBA8UI,
2125 GL_RGBA8I,
2126 GL_RGB10_A2UI,
2127 GL_RGBA16UI,
2128 GL_RGBA16I,
2129 GL_RGBA32UI,
2130 GL_RGBA32I,
2131 GL_DEPTH_COMPONENT16,
2132 GL_DEPTH_COMPONENT24,
2133 GL_DEPTH_COMPONENT32F,
2134 GL_DEPTH24_STENCIL8,
2135 GL_DEPTH32F_STENCIL8,
2136 GL_COMPRESSED_R11_EAC,
2137 GL_COMPRESSED_SIGNED_R11_EAC,
2138 GL_COMPRESSED_RG11_EAC,
2139 GL_COMPRESSED_SIGNED_RG11_EAC,
2140 GL_COMPRESSED_RGB8_ETC2,
2141 GL_COMPRESSED_SRGB8_ETC2,
2142 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
2143 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
2144 GL_COMPRESSED_RGBA8_ETC2_EAC,
2145 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
2146 });
2147 }
2148 } // namespace Impl
2149 } // namespace Rosen
2150 } // namespace OHOS
2151