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 (!objQuery) {
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 (!objSampler) {
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 (!objVertexArrayObject) {
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 (!objSync) {
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}u %{public}u result %{public}u", syncId, returnValue, GetError_());
467 return NVal::CreateInt64(env, static_cast<int64_t>(returnValue)).val_;
468 }
469
WaitSync(napi_env env,napi_value syncObj,GLbitfield flags,GLint64 timeout)470 napi_value WebGL2RenderingContextImpl::WaitSync(napi_env env, napi_value syncObj, GLbitfield flags, GLint64 timeout)
471 {
472 WebGLSync* webGlSync = WebGLObject::GetObjectInstance<WebGLSync>(env, syncObj);
473 if (webGlSync == nullptr) {
474 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "webGlSync is nullptr");
475 return NVal::CreateNull(env).val_;
476 }
477 int64_t syncId = webGlSync->GetSync();
478 if (timeout < WebGL2RenderingContextBase::TIMEOUT_IGNORED) {
479 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "timeout %{pulic}" PRIi64, timeout);
480 return NVal::CreateNull(env).val_;
481 }
482 GLuint64 timeout64 = (timeout == -1) ? GL_TIMEOUT_IGNORED : static_cast<GLuint64>(timeout);
483 glWaitSync(reinterpret_cast<GLsync>(syncId), flags, timeout64);
484 LOGD("WebGL2 waitSync GL_TIMEOUT_IGNORED %{public}u", GL_TIMEOUT_IGNORED);
485 return NVal::CreateNull(env).val_;
486 }
487
GetSyncParameter(napi_env env,napi_value syncObj,GLenum pname)488 napi_value WebGL2RenderingContextImpl::GetSyncParameter(napi_env env, napi_value syncObj, GLenum pname)
489 {
490 WebGLSync* webGlSync = WebGLObject::GetObjectInstance<WebGLSync>(env, syncObj);
491 if (webGlSync == nullptr) {
492 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
493 return NVal::CreateNull(env).val_;
494 }
495 int64_t syncId = webGlSync->GetSync();
496 LOGD("WebGL2 getSyncParameter syncId %{public}" PRIi64 " pname %{public}u ", syncId, pname);
497 if (CheckInList(pname, { GL_OBJECT_TYPE, GL_SYNC_STATUS, GL_SYNC_CONDITION, GL_SYNC_FLAGS })) {
498 GLint value = 0;
499 GLsizei length = -1;
500 glGetSynciv(reinterpret_cast<GLsync>(syncId), pname, 1, &length, &value);
501 LOGD("WebGL2 getSyncParameter value %{public}d ", value);
502 return NVal::CreateInt64(env, value).val_;
503 } else {
504 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
505 return NVal::CreateNull(env).val_;
506 }
507 }
508
CreateTransformFeedback(napi_env env)509 napi_value WebGL2RenderingContextImpl::CreateTransformFeedback(napi_env env)
510 {
511 WebGLTransformFeedback* webGlTransformFeedback = nullptr;
512 napi_value objTransformFeedback = WebGLTransformFeedback::CreateObjectInstance(env, &webGlTransformFeedback).val_;
513 if (!objTransformFeedback || webGlTransformFeedback == nullptr) {
514 return NVal::CreateNull(env).val_;
515 }
516 GLuint transformFeedbackId = 0;
517 glGenTransformFeedbacks(1, &transformFeedbackId);
518 webGlTransformFeedback->SetTransformFeedback(transformFeedbackId);
519 LOGD("WebGL2 createTransformFeedback transformFeedbackId %{public}u", transformFeedbackId);
520 AddObject<WebGLTransformFeedback>(env, transformFeedbackId, objTransformFeedback);
521 return objTransformFeedback;
522 }
523
DeleteTransformFeedback(napi_env env,napi_value obj)524 napi_value WebGL2RenderingContextImpl::DeleteTransformFeedback(napi_env env, napi_value obj)
525 {
526 uint32_t transformFeedbackId = WebGLTransformFeedback::DEFAULT_TRANSFORM_FEEDBACK;
527 WebGLTransformFeedback* webGlTransformFeedback = WebGLObject::GetObjectInstance<WebGLTransformFeedback>(env, obj);
528 if (webGlTransformFeedback == nullptr) {
529 return NVal::CreateNull(env).val_;
530 }
531 transformFeedbackId = webGlTransformFeedback->GetTransformFeedback();
532 DeleteObject<WebGLTransformFeedback>(env, transformFeedbackId);
533 glDeleteTransformFeedbacks(1, &transformFeedbackId);
534 LOGD("WebGL2 deleteTransformFeedback transformFeedbackId %{public}u", transformFeedbackId);
535 if (boundTransformFeedback_ != transformFeedbackId) {
536 LOGE("WebGL2 bindTransformFeedback bound %{public}u", boundTransformFeedback_);
537 }
538 boundTransformFeedback_ = 0;
539 return NVal::CreateNull(env).val_;
540 }
541
IsTransformFeedback(napi_env env,napi_value obj)542 napi_value WebGL2RenderingContextImpl::IsTransformFeedback(napi_env env, napi_value obj)
543 {
544 WebGLTransformFeedback* webGlTransformFeedback = WebGLObject::GetObjectInstance<WebGLTransformFeedback>(env, obj);
545 if (webGlTransformFeedback == nullptr) {
546 return NVal::CreateBool(env, false).val_;
547 }
548 GLuint transformFeedbackId = webGlTransformFeedback->GetTransformFeedback();
549 LOGD("WebGL2 isTransformFeedback transformFeedbackId %{public}u bound %{public}u",
550 transformFeedbackId, boundTransformFeedback_);
551 if (GetObjectInstance<WebGLTransformFeedback>(env, transformFeedbackId) != nullptr &&
552 boundTransformFeedback_ == transformFeedbackId) {
553 return NVal::CreateBool(env, true).val_;
554 }
555 return NVal::CreateBool(env, false).val_;
556 }
557
BindTransformFeedback(napi_env env,napi_value obj,GLenum target)558 napi_value WebGL2RenderingContextImpl::BindTransformFeedback(napi_env env, napi_value obj, GLenum target)
559 {
560 WebGLTransformFeedback* webGlTransformFeedback = WebGLObject::GetObjectInstance<WebGLTransformFeedback>(env, obj);
561 if (webGlTransformFeedback == nullptr) {
562 return NVal::CreateBool(env, false).val_;
563 }
564 GLuint transformFeedbackId = webGlTransformFeedback->GetTransformFeedback();
565 if (target != GL_TRANSFORM_FEEDBACK) {
566 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
567 return NVal::CreateNull(env).val_;
568 }
569 if (boundTransformFeedback_ && boundTransformFeedback_ != transformFeedbackId) {
570 LOGE("WebGL2 bindTransformFeedback has been bound %{public}u", boundTransformFeedback_);
571 }
572 boundTransformFeedback_ = transformFeedbackId;
573 glBindTransformFeedback(target, transformFeedbackId);
574 LOGD("WebGL2 bindTransformFeedback id %{public}u target %{public}u result %{public}u",
575 transformFeedbackId, target, GetError_());
576 if (webGlTransformFeedback) {
577 webGlTransformFeedback->SetTarget(target);
578 }
579 return NVal::CreateNull(env).val_;
580 }
581
GetTransformFeedbackVaryingType(GLuint programId,GLint index)582 static GLint GetTransformFeedbackVaryingType(GLuint programId, GLint index)
583 {
584 GLint params = 0;
585 glGetProgramiv(programId, WebGL2RenderingContextBase::TRANSFORM_FEEDBACK_VARYINGS, ¶ms);
586 LOGD("WebGL2 GetTransformFeedbackVaryingType programId %{public}u params %{public}d", programId, params);
587 return params;
588 }
589
BeginTransformFeedback(napi_env env,GLenum primitiveMode)590 napi_value WebGL2RenderingContextImpl::BeginTransformFeedback(napi_env env, GLenum primitiveMode)
591 {
592 if (!CheckInList(primitiveMode, { WebGLRenderingContextBase::POINTS, WebGLRenderingContextBase::LINES,
593 WebGLRenderingContextBase::TRIANGLES })) {
594 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
595 return NVal::CreateNull(env).val_;
596 }
597 if (GetTransformFeedbackVaryingType(currentProgramId_, boundTransformFeedback_) <= 0) {
598 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
599 return NVal::CreateNull(env).val_;
600 }
601 glBeginTransformFeedback(primitiveMode);
602 LOGD("WebGL2 beginTransformFeedback primitiveMode %{public}u result %{public}u", primitiveMode, GetError_());
603 return NVal::CreateNull(env).val_;
604 }
605
EndTransformFeedback(napi_env env)606 napi_value WebGL2RenderingContextImpl::EndTransformFeedback(napi_env env)
607 {
608 LOGD("WebGL2 endTransformFeedback");
609 if (GetTransformFeedbackVaryingType(currentProgramId_, boundTransformFeedback_) <= 0) {
610 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
611 return NVal::CreateNull(env).val_;
612 }
613 glEndTransformFeedback();
614 return NVal::CreateNull(env).val_;
615 }
616
GetTransformFeedbackVarying(napi_env env,napi_value programObj,GLuint index)617 napi_value WebGL2RenderingContextImpl::GetTransformFeedbackVarying(napi_env env, napi_value programObj, GLuint index)
618 {
619 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
620 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
621 if (webGLProgram == nullptr) {
622 return NVal::CreateNull(env).val_;
623 }
624 programId = webGLProgram->GetProgramId();
625
626 WebGLActiveInfo* webGLActiveInfo = nullptr;
627 napi_value objActiveInfo = WebGLActiveInfo::CreateObjectInstance(env, &webGLActiveInfo).val_;
628 if (!objActiveInfo) {
629 return NVal::CreateNull(env).val_;
630 }
631
632 GLsizei bufSize = WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH;
633 GLsizei length = 0;
634 GLsizei size = 0;
635 GLenum type = 0;
636 GLchar name[WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH] = { 0 };
637 glGetTransformFeedbackVarying(programId, index, bufSize, &length, &size, &type, name);
638 LOGD("WebGL2 getTransformFeedbackVarying: name '%{public}s' %{public}u length %{public}d %{public}d"
639 " index %{public}u", name, type, length, size, index);
640 if (type == 0) {
641 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
642 return NVal::CreateNull(env).val_;
643 }
644 webGLActiveInfo->SetActiveName(name, WEBGL_ACTIVE_INFO_NAME_MAX_LENGTH);
645 webGLActiveInfo->SetActiveSize(size);
646 webGLActiveInfo->SetActiveType(type);
647 return objActiveInfo;
648 }
649
TexStorage2D(napi_env env,const TexStorageArg & arg)650 napi_value WebGL2RenderingContextImpl::TexStorage2D(napi_env env, const TexStorageArg& arg)
651 {
652 arg.Dump("WebGL2 texStorage2D");
653 if (arg.target != GL_TEXTURE_2D && arg.target != GL_TEXTURE_CUBE_MAP) {
654 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
655 return NVal::CreateNull(env).val_;
656 }
657 WebGLTexture* texture = GetBoundTexture(env, arg.target, false);
658 if (texture == nullptr) {
659 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
660 return NVal::CreateNull(env).val_;
661 }
662 GLenum result = CheckTexStorage(env, arg);
663 if (result != WebGLRenderingContextBase::NO_ERROR) {
664 SET_ERROR_WITH_LOG(result, "CheckTexStorage failed");
665 return NVal::CreateNull(env).val_;
666 }
667 glTexStorage2D(arg.target, arg.levels, arg.internalFormat, arg.width, arg.height);
668 texture->SetTexStorageInfo(&arg);
669 return NVal::CreateNull(env).val_;
670 }
671
TexStorage3D(napi_env env,const TexStorageArg & arg)672 napi_value WebGL2RenderingContextImpl::TexStorage3D(napi_env env, const TexStorageArg& arg)
673 {
674 arg.Dump("WebGL texStorage3D");
675 if (arg.target != GL_TEXTURE_3D && arg.target != GL_TEXTURE_2D_ARRAY) {
676 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
677 return NVal::CreateNull(env).val_;
678 }
679 GLenum result = CheckTexStorage(env, arg);
680 if (result != WebGLRenderingContextBase::NO_ERROR) {
681 SET_ERROR_WITH_LOG(result, "CheckTexStorage failed");
682 return NVal::CreateNull(env).val_;
683 }
684 WebGLTexture* texture = GetBoundTexture(env, arg.target, false);
685 if (texture == nullptr) {
686 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
687 return NVal::CreateNull(env).val_;
688 }
689 glTexStorage3D(arg.target, arg.levels, arg.internalFormat, arg.width, arg.height, arg.depth);
690 texture->SetTexStorageInfo(&arg);
691 LOGD("WebGL texStorage3D result %{public}u", GetError_());
692 return NVal::CreateNull(env).val_;
693 }
694
CheckTexImage3D(napi_env env,const TexImageArg & imgArg)695 GLenum WebGL2RenderingContextImpl::CheckTexImage3D(napi_env env, const TexImageArg& imgArg)
696 {
697 switch (imgArg.target) {
698 case GL_TEXTURE_3D:
699 case GL_TEXTURE_2D_ARRAY:
700 break;
701 default:
702 return WebGLRenderingContextBase::INVALID_ENUM;
703 }
704 GLenum result = CheckTextureLevel(imgArg.target, imgArg.level);
705 if (result != WebGLRenderingContextBase::NO_ERROR) {
706 return result;
707 }
708 return CheckTextureFormatAndType(env, imgArg.internalFormat, imgArg.format, imgArg.type, imgArg.level);
709 }
710
TexImage3D(napi_env env,const TexImageArg & arg,napi_value source)711 napi_value WebGL2RenderingContextImpl::TexImage3D(napi_env env, const TexImageArg& arg, napi_value source)
712 {
713 TexImageArg imgArg(arg);
714 imgArg.Dump("WebGL2 texImage3D");
715 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
716 if (texture == nullptr) {
717 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
718 return NVal::CreateNull(env).val_;
719 }
720
721 GLenum result = CheckTexImage3D(env, imgArg);
722 if (result != WebGLRenderingContextBase::NO_ERROR) {
723 SET_ERROR_WITH_LOG(result, "CheckTexImage3D failed");
724 return NVal::CreateNull(env).val_;
725 }
726 GLvoid* data = nullptr;
727 WebGLImageSource imageSource(env, version_, unpackFlipY_, unpackPremultiplyAlpha_);
728 if (!NVal(env, source).IsNull()) {
729 result = imageSource.GenImageSource(
730 { imgArg.format, imgArg.type, imgArg.width, imgArg.height, imgArg.depth }, source);
731 if (result) {
732 SET_ERROR_WITH_LOG(result, "GenImageSource failed");
733 return NVal::CreateNull(env).val_;
734 }
735 data = imageSource.GetImageSourceData();
736 imgArg.width = imageSource.GetWidth();
737 imgArg.height = imageSource.GetHeight();
738 }
739
740 glTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height, imgArg.depth,
741 imgArg.border, imgArg.format, imgArg.type, data);
742 texture->SetTextureLevel({ imgArg.target, imgArg.level,
743 imgArg.internalFormat, imgArg.width, imgArg.height, imgArg.depth, imgArg.type });
744 LOGD("WebGL2 texImage3D result %{public}u", GetError_());
745 return NVal::CreateNull(env).val_;
746 }
747
TexImage3D(napi_env env,const TexImageArg & imgArg,napi_value dataObj,GLuint srcOffset)748 napi_value WebGL2RenderingContextImpl::TexImage3D(
749 napi_env env, const TexImageArg& imgArg, napi_value dataObj, GLuint srcOffset)
750 {
751 imgArg.Dump("WebGL2 texImage3D");
752 GLenum result = CheckTexImage3D(env, imgArg);
753 if (result != WebGLRenderingContextBase::NO_ERROR) {
754 SET_ERROR_WITH_LOG(result, "CheckTexImage3D failed");
755 return NVal::CreateNull(env).val_;
756 }
757
758 GLvoid* data = nullptr;
759 WebGLImageSource imageSource(env, version_, unpackFlipY_, unpackPremultiplyAlpha_);
760 if (!NVal(env, dataObj).IsNull()) {
761 result = imageSource.GenImageSource(
762 { imgArg.format, imgArg.type, imgArg.width, imgArg.height, imgArg.depth }, dataObj, srcOffset);
763 if (result) {
764 SET_ERROR_WITH_LOG(result, "GenImageSource failed");
765 return NVal::CreateNull(env).val_;
766 }
767 data = imageSource.GetImageSourceData();
768 }
769 if (data != nullptr) {
770 GLenum result = CheckTextureDataBuffer(imgArg, imageSource.GetWebGLReadBuffer());
771 if (result) {
772 SET_ERROR_WITH_LOG(result, "CheckTextureDataBuffer failed");
773 return NVal::CreateNull(env).val_;
774 }
775 }
776 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
777 if (texture == nullptr) {
778 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "texture is nullptr");
779 return NVal::CreateNull(env).val_;
780 }
781 glTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height, imgArg.depth,
782 imgArg.border, imgArg.format, imgArg.type, data);
783 texture->SetTextureLevel(imgArg);
784 LOGD("WebGL2 texImage3D result %{public}u", GetError_());
785 return NVal::CreateNull(env).val_;
786 }
787
TexImage3D(napi_env env,const TexImageArg & imgArg,GLintptr pboOffset)788 napi_value WebGL2RenderingContextImpl::TexImage3D(napi_env env, const TexImageArg& imgArg, GLintptr pboOffset)
789 {
790 imgArg.Dump("WebGL2 texImage3D");
791 GLenum result = CheckTexImage3D(env, imgArg);
792 if (result != WebGLRenderingContextBase::NO_ERROR) {
793 SET_ERROR(result);
794 return NVal::CreateNull(env).val_;
795 }
796 glTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height, imgArg.depth,
797 imgArg.border, imgArg.format, imgArg.type, reinterpret_cast<void*>(pboOffset));
798 LOGD("WebGL2 texImage3D result %{public}u", GetError_());
799 return NVal::CreateNull(env).val_;
800 }
801
CheckTexSubImage3D(napi_env env,const TexSubImage3DArg & arg)802 GLenum WebGL2RenderingContextImpl::CheckTexSubImage3D(napi_env env, const TexSubImage3DArg& arg)
803 {
804 switch (arg.target) {
805 case GL_TEXTURE_3D:
806 case GL_TEXTURE_2D_ARRAY:
807 break;
808 default:
809 return WebGLRenderingContextBase::INVALID_ENUM;
810 }
811 GLenum result = CheckTextureLevel(arg.target, arg.level);
812 if (result != WebGLRenderingContextBase::NO_ERROR) {
813 return result;
814 }
815 WebGLTexture* texture = GetBoundTexture(env, arg.target, false);
816 if (texture == nullptr) {
817 return WebGLRenderingContextBase::INVALID_VALUE;
818 }
819
820 if (!texture->CheckValid(arg.target, arg.level)) {
821 return WebGLRenderingContextBase::INVALID_OPERATION;
822 }
823
824 if (!WebGLTexture::CheckTextureSize(arg.xOffset, arg.width, texture->GetWidth(arg.target, arg.level)) ||
825 !WebGLTexture::CheckTextureSize(arg.yOffset, arg.height, texture->GetHeight(arg.target, arg.level)) ||
826 !WebGLTexture::CheckTextureSize(arg.zOffset, arg.depth, texture->GetDepth(arg.target, arg.level))) {
827 return WebGLRenderingContextBase::INVALID_VALUE;
828 }
829 GLenum internalFormat = texture->GetInternalFormat(arg.target, arg.level);
830 return CheckTextureFormatAndType(env, internalFormat, arg.format, arg.type, arg.level);
831 }
832
TexSubImage3D(napi_env env,const TexSubImage3DArg & arg,napi_value source)833 napi_value WebGL2RenderingContextImpl::TexSubImage3D(napi_env env, const TexSubImage3DArg& arg, napi_value source)
834 {
835 TexSubImage3DArg imgArg(arg);
836 imgArg.Dump("WebGL2 texSubImage3D source");
837 GLvoid* data = nullptr;
838 WebGLImageSource imageSource(env, version_, unpackFlipY_, unpackPremultiplyAlpha_);
839 if (!NVal(env, source).IsNull()) {
840 GLenum result = imageSource.GenImageSource(
841 { imgArg.format, imgArg.type, imgArg.width, imgArg.height, imgArg.depth }, source);
842 if (result) {
843 SET_ERROR_WITH_LOG(result, "GenImageSource failed");
844 return NVal::CreateNull(env).val_;
845 }
846 data = imageSource.GetImageSourceData();
847 imgArg.width = imageSource.GetWidth();
848 imgArg.height = imageSource.GetHeight();
849 } else {
850 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
851 return NVal::CreateNull(env).val_;
852 }
853 GLenum result = CheckTexSubImage3D(env, imgArg);
854 if (result != WebGLRenderingContextBase::NO_ERROR) {
855 SET_ERROR_WITH_LOG(result, "CheckTexSubImage3D failed");
856 return NVal::CreateNull(env).val_;
857 }
858 glTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
859 imgArg.height, imgArg.depth, imgArg.format, imgArg.type, data);
860 LOGD("WebGL2 texSubImage3D result %{public}u", GetError_());
861 return NVal::CreateNull(env).val_;
862 }
863
TexSubImage3D(napi_env env,const TexSubImage3DArg & imgArg,napi_value dataObj,GLuint srcOffset)864 napi_value WebGL2RenderingContextImpl::TexSubImage3D(
865 napi_env env, const TexSubImage3DArg& imgArg, napi_value dataObj, GLuint srcOffset)
866 {
867 imgArg.Dump("WebGL2 texSubImage3D data buffer");
868
869 WebGLImageSource imageSource(env, version_, unpackFlipY_, unpackPremultiplyAlpha_);
870 GLvoid* data = nullptr;
871 bool changeUnpackAlignment = false;
872 if (!NVal(env, dataObj).IsNull()) {
873 GLenum result = imageSource.GenImageSource(
874 { imgArg.format, imgArg.type, imgArg.width, imgArg.height, imgArg.depth }, dataObj, srcOffset);
875 if (result) {
876 SET_ERROR_WITH_LOG(result, "GenImageSource failed");
877 return NVal::CreateNull(env).val_;
878 }
879 data = imageSource.GetImageSourceData();
880 changeUnpackAlignment = unpackFlipY_ || unpackPremultiplyAlpha_;
881 } else {
882 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
883 return NVal::CreateNull(env).val_;
884 }
885
886 GLenum result = CheckTexSubImage3D(env, imgArg);
887 if (result != WebGLRenderingContextBase::NO_ERROR) {
888 SET_ERROR_WITH_LOG(result, "CheckTexSubImage3D failed");
889 return NVal::CreateNull(env).val_;
890 }
891
892 if (changeUnpackAlignment) {
893 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
894 }
895 glTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
896 imgArg.height, imgArg.depth, imgArg.format, imgArg.type, data);
897 if (changeUnpackAlignment) {
898 glPixelStorei(GL_UNPACK_ALIGNMENT, unpackAlignment_);
899 }
900 LOGD("WebGL2 texSubImage3D result %{public}u", GetError_());
901 return NVal::CreateNull(env).val_;
902 }
903
TexSubImage3D(napi_env env,const TexSubImage3DArg & imgArg,GLintptr pboOffset)904 napi_value WebGL2RenderingContextImpl::TexSubImage3D(napi_env env, const TexSubImage3DArg& imgArg, GLintptr pboOffset)
905 {
906 imgArg.Dump("WebGL2 texSubImage3D pboOffset");
907 GLenum result = CheckTexSubImage3D(env, imgArg);
908 if (result != WebGLRenderingContextBase::NO_ERROR) {
909 SET_ERROR(result);
910 return NVal::CreateNull(env).val_;
911 }
912 glTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
913 imgArg.height, imgArg.depth, imgArg.format, imgArg.type, reinterpret_cast<void*>(pboOffset));
914 LOGD("WebGL2 texSubImage3D result %{public}u", GetError_());
915 return NVal::CreateNull(env).val_;
916 }
917
CopyTexSubImage3D(napi_env env,const CopyTexSubImage3DArg & imgArg)918 napi_value WebGL2RenderingContextImpl::CopyTexSubImage3D(napi_env env, const CopyTexSubImage3DArg& imgArg)
919 {
920 imgArg.Dump("WebGL2 copyTexSubImage3D");
921 GLenum result = CheckCopyTexSubImage(env, imgArg);
922 if (result) {
923 SET_ERROR_WITH_LOG(result, "CheckCopyTexSubImage failed");
924 return NVal::CreateNull(env).val_;
925 }
926 GLuint frameBufferId = 0;
927 result = CheckReadBufferAndGetInfo(env, &frameBufferId, nullptr, nullptr);
928 if (result != WebGLRenderingContextBase::NO_ERROR) {
929 SET_ERROR_WITH_LOG(result, "CheckReadBufferAndGetInfo failed");
930 return NVal::CreateNull(env).val_;
931 }
932 glCopyTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.x, imgArg.y,
933 imgArg.width, imgArg.height);
934 LOGD("WebGL2 copyTexSubImage3D result %{public}u", GetError_());
935 return NVal::CreateNull(env).val_;
936 }
937
CompressedTexImage3D(napi_env env,const TexImageArg & imgArg,GLsizei imageSize,GLintptr offset)938 napi_value WebGL2RenderingContextImpl::CompressedTexImage3D(
939 napi_env env, const TexImageArg& imgArg, GLsizei imageSize, GLintptr offset)
940 {
941 imgArg.Dump("WebGL2 compressedTexImage3D");
942 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
943 if (texture == nullptr) {
944 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "texture is nullptr");
945 return NVal::CreateNull(env).val_;
946 }
947 if (texture->CheckImmutable()) {
948 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckImmutable failed");
949 return NVal::CreateNull(env).val_;
950 }
951
952 glCompressedTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height,
953 imgArg.depth, imgArg.border, imageSize, reinterpret_cast<void*>(offset));
954 LOGD("WebGL2 copyTexSubImage3D result %{public}u", GetError_());
955 return NVal::CreateNull(env).val_;
956 }
957
CompressedTexImage3D(napi_env env,const TexImageArg & imgArg,napi_value dataObj,GLuint srcOffset,GLuint srcLengthOverride)958 napi_value WebGL2RenderingContextImpl::CompressedTexImage3D(
959 napi_env env, const TexImageArg& imgArg, napi_value dataObj, GLuint srcOffset, GLuint srcLengthOverride)
960 {
961 imgArg.Dump("WebGL2 compressedTexImage3D");
962 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
963 if (texture == nullptr) {
964 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "texture is nullptr");
965 return NVal::CreateNull(env).val_;
966 }
967 if (texture->CheckImmutable()) {
968 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckImmutable failed");
969 return NVal::CreateNull(env).val_;
970 }
971 WebGLReadBufferArg readData(env);
972 GLvoid* data = nullptr;
973 GLsizei length = 0;
974 if (NVal(env, dataObj).IsNull()) {
975 napi_status status = readData.GenBufferData(dataObj, BUFFER_DATA_FLOAT_32);
976 if (status != napi_ok) {
977 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "GenBufferData failed");
978 return NVal::CreateNull(env).val_;
979 }
980 readData.DumpBuffer(readData.GetBufferDataType());
981 data = reinterpret_cast<void*>(readData.GetBuffer() + srcOffset);
982 length = static_cast<GLsizei>((srcLengthOverride == 0) ? readData.GetBufferLength() : srcLengthOverride);
983 }
984 glCompressedTexImage3D(imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height,
985 imgArg.depth, imgArg.border, length, data);
986 texture->SetTextureLevel({ imgArg.target, imgArg.level, imgArg.internalFormat, imgArg.width, imgArg.height,
987 imgArg.depth, GL_UNSIGNED_BYTE });
988 LOGD("WebGL2 compressedTexImage3D result %{public}u", GetError_());
989 return NVal::CreateNull(env).val_;
990 }
991
CompressedTexSubImage3D(napi_env env,const TexSubImage3DArg & imgArg,GLsizei imageSize,GLintptr offset)992 napi_value WebGL2RenderingContextImpl::CompressedTexSubImage3D(
993 napi_env env, const TexSubImage3DArg& imgArg, GLsizei imageSize, GLintptr offset)
994 {
995 imgArg.Dump("WebGL2 compressedTexSubImage3D");
996 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
997 if (texture == nullptr) {
998 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "texture is nullptr");
999 return NVal::CreateNull(env).val_;
1000 }
1001 if (imgArg.format != texture->GetInternalFormat(imgArg.target, imgArg.level)) {
1002 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
1003 return NVal::CreateNull(env).val_;
1004 }
1005 glCompressedTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
1006 imgArg.height, imgArg.depth, imgArg.format, imageSize, reinterpret_cast<void*>(offset));
1007 LOGD("WebGL2 compressedTexSubImage3D result %{public}u", GetError_());
1008 return NVal::CreateNull(env).val_;
1009 }
1010
CompressedTexSubImage3D(napi_env env,const TexSubImage3DArg & imgArg,napi_value dataObj,GLuint srcOffset,GLuint srcLengthOverride)1011 napi_value WebGL2RenderingContextImpl::CompressedTexSubImage3D(
1012 napi_env env, const TexSubImage3DArg& imgArg, napi_value dataObj, GLuint srcOffset, GLuint srcLengthOverride)
1013 {
1014 imgArg.Dump("WebGL2 compressedTexSubImage3D");
1015 WebGLTexture* texture = GetBoundTexture(env, imgArg.target, true);
1016 if (texture == nullptr) {
1017 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "texture is nullptr");
1018 return NVal::CreateNull(env).val_;
1019 }
1020 if (imgArg.format != texture->GetInternalFormat(imgArg.target, imgArg.level)) {
1021 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
1022 return NVal::CreateNull(env).val_;
1023 }
1024
1025 WebGLReadBufferArg readData(env);
1026 GLvoid* data = nullptr;
1027 GLsizei length = 0;
1028 if (NVal(env, dataObj).IsNull()) {
1029 napi_status status = readData.GenBufferData(dataObj, BUFFER_DATA_FLOAT_32);
1030 if (status != napi_ok) {
1031 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1032 return NVal::CreateNull(env).val_;
1033 }
1034 readData.DumpBuffer(readData.GetBufferDataType());
1035 data = reinterpret_cast<void*>(readData.GetBuffer() + srcOffset);
1036 length = static_cast<GLsizei>((srcLengthOverride == 0) ? readData.GetBufferLength() : srcLengthOverride);
1037 }
1038
1039 glCompressedTexSubImage3D(imgArg.target, imgArg.level, imgArg.xOffset, imgArg.yOffset, imgArg.zOffset, imgArg.width,
1040 imgArg.height, imgArg.depth, imgArg.format, length, data);
1041 LOGD("WebGL2 compressedTexSubImage3D result %{public}u", GetError_());
1042 return NVal::CreateNull(env).val_;
1043 }
1044
ClearBufferV(napi_env env,GLenum buffer,GLint drawBuffer,napi_value value,int64_t srcOffset,BufferDataType type)1045 napi_value WebGL2RenderingContextImpl::ClearBufferV(
1046 napi_env env, GLenum buffer, GLint drawBuffer, napi_value value, int64_t srcOffset, BufferDataType type)
1047 {
1048 LOGD("WebGL2 clearBuffer buffer %{public}u %{public}d srcOffset %{public}" PRIi64, buffer, drawBuffer, srcOffset);
1049 WebGLReadBufferArg bufferData(env);
1050 napi_status status = bufferData.GenBufferData(value, type);
1051 if (status != 0) {
1052 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "WebGL2 clearBuffer failed to getbuffer data");
1053 return NVal::CreateNull(env).val_;
1054 }
1055 if (bufferData.GetBufferDataType() != type) {
1056 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1057 "WebGL2 clearBuffer invalid buffer data type %{public}d", bufferData.GetBufferDataType());
1058 return NVal::CreateNull(env).val_;
1059 }
1060
1061 GLenum result = CheckClearBuffer(env, buffer, bufferData);
1062 if (result != WebGLRenderingContextBase::NO_ERROR) {
1063 SET_ERROR_WITH_LOG(result, "WebGL2 clearBuffer invalid clear buffer");
1064 return NVal::CreateNull(env).val_;
1065 }
1066
1067 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1068 switch (type) {
1069 case BUFFER_DATA_FLOAT_32:
1070 glClearBufferfv(buffer, drawBuffer, reinterpret_cast<GLfloat*>(bufferData.GetBuffer() + srcOffset));
1071 break;
1072 case BUFFER_DATA_INT_32:
1073 glClearBufferiv(buffer, drawBuffer, reinterpret_cast<GLint*>(bufferData.GetBuffer() + srcOffset));
1074 break;
1075 case BUFFER_DATA_UINT_32:
1076 glClearBufferuiv(buffer, drawBuffer, reinterpret_cast<GLuint*>(bufferData.GetBuffer() + srcOffset));
1077 break;
1078 default:
1079 break;
1080 }
1081 LOGD("WebGL2 clearBuffer buffer %{public}u result %{public}u", buffer, GetError_());
1082 return NVal::CreateNull(env).val_;
1083 }
1084
ClearBufferfi(napi_env env,GLenum buffer,GLint drawBuffer,GLfloat depth,GLint stencil)1085 napi_value WebGL2RenderingContextImpl::ClearBufferfi(
1086 napi_env env, GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil)
1087 {
1088 if (buffer != WebGLRenderingContextBase::DEPTH_STENCIL) {
1089 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1090 return NVal::CreateNull(env).val_;
1091 }
1092 glClearBufferfi(buffer, drawBuffer, depth, stencil);
1093 LOGD("WebGL2 clearBufferfi buffer %{public}u %{public}d depth %{public}f %{public}d result %{public}u",
1094 buffer, drawBuffer, depth, stencil, GetError_());
1095 return NVal::CreateNull(env).val_;
1096 }
1097
GetIndexedParameter(napi_env env,GLenum target,GLuint index)1098 napi_value WebGL2RenderingContextImpl::GetIndexedParameter(napi_env env, GLenum target, GLuint index)
1099 {
1100 LOGD("WebGL2 getIndexedParameter index %{public}u", index);
1101 switch (target) {
1102 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: {
1103 if (index >= maxBoundTransformFeedbackBufferIndex_) {
1104 return NVal::CreateNull(env).val_;
1105 }
1106 return GetObject<WebGLBuffer>(env, boundIndexedTransformFeedbackBuffers_[index]);
1107 }
1108 case GL_UNIFORM_BUFFER_BINDING: {
1109 if (index >= maxBoundUniformBufferIndex_) {
1110 return NVal::CreateNull(env).val_;
1111 }
1112 return GetObject<WebGLBuffer>(env, boundIndexedUniformBuffers_[index]);
1113 }
1114 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1115 case GL_UNIFORM_BUFFER_SIZE:
1116 case GL_UNIFORM_BUFFER_START: {
1117 int64_t data;
1118 glGetInteger64i_v(target, index, &data);
1119 LOGD("WebGL getIndexedParameter end");
1120 return NVal::CreateInt64(env, data).val_;
1121 }
1122 default :
1123 LOGD("WebGL getIndexedParameter get nullptr");
1124 return NVal::CreateNull(env).val_;
1125 }
1126 }
1127
GetFragDataLocation(napi_env env,napi_value programObj,const std::string & name)1128 napi_value WebGL2RenderingContextImpl::GetFragDataLocation(napi_env env, napi_value programObj, const std::string& name)
1129 {
1130 GLuint program = WebGLProgram::DEFAULT_PROGRAM_ID;
1131 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1132 if (webGLProgram == nullptr) {
1133 return NVal::CreateInt64(env, -1).val_;
1134 }
1135 program = webGLProgram->GetProgramId();
1136
1137 GLint res = glGetFragDataLocation(program, const_cast<char*>(name.c_str()));
1138 LOGD("WebGL2 getFragDataLocation name %{public}s result %{public}d", name.c_str(), res);
1139 return NVal::CreateInt64(env, res).val_;
1140 }
1141
VertexAttribI4i(napi_env env,GLuint index,GLint * data)1142 napi_value WebGL2RenderingContextImpl::VertexAttribI4i(napi_env env, GLuint index, GLint* data)
1143 {
1144 VertexAttribInfo* info = GetVertexAttribInfo(index);
1145 if (info == nullptr) {
1146 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1147 return NVal::CreateNull(env).val_;
1148 }
1149
1150 glVertexAttribI4i(index, data[0], data[1], data[2], data[3]); // 2, 3 index for data
1151 info->type = BUFFER_DATA_INT_32;
1152 LOGD("WebGL2 vertexAttribI4i index %{public}u [%{public}d %{public}d %{public}d %{public}d] result %{public}u",
1153 index, data[0], data[1], data[2], data[3], GetError_()); // 2, 3 index for data
1154 return NVal::CreateNull(env).val_;
1155 }
1156
VertexAttribI4ui(napi_env env,GLuint index,GLuint * data)1157 napi_value WebGL2RenderingContextImpl::VertexAttribI4ui(napi_env env, GLuint index, GLuint* data)
1158 {
1159 VertexAttribInfo* info = GetVertexAttribInfo(index);
1160 if (info == nullptr) {
1161 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1162 return NVal::CreateNull(env).val_;
1163 }
1164
1165 glVertexAttribI4ui(index, data[0], data[1], data[2], data[3]); // 2, 3 index for data
1166 info->type = BUFFER_DATA_UINT_32;
1167 LOGD("WebGL2 vertexAttribI4ui index %{public}u [%{public}u %{public}u %{public}u %{public}u] result %{public}u",
1168 index, data[0], data[1], data[2], data[3], GetError_()); // 2, 3 index for data
1169 return NVal::CreateNull(env).val_;
1170 }
1171
VertexAttribI4iv(napi_env env,GLuint index,napi_value data)1172 napi_value WebGL2RenderingContextImpl::VertexAttribI4iv(napi_env env, GLuint index, napi_value data)
1173 {
1174 VertexAttribInfo* info = GetVertexAttribInfo(index);
1175 if (info == nullptr) {
1176 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1177 return NVal::CreateNull(env).val_;
1178 }
1179
1180 WebGLReadBufferArg bufferData(env);
1181 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_INT_32);
1182 if (status != 0) {
1183 LOGE("WebGL vertexAttribI4iv failed to getbuffer data");
1184 return NVal::CreateNull(env).val_;
1185 }
1186 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1187 if (bufferData.GetBufferDataType() != BUFFER_DATA_INT_32) {
1188 LOGE("WebGL vertexAttribI4iv invalid data type %{public}u", bufferData.GetBufferDataType());
1189 return NVal::CreateNull(env).val_;
1190 }
1191 glVertexAttribI4iv(index, reinterpret_cast<GLint*>(bufferData.GetBuffer()));
1192 info->type = BUFFER_DATA_INT_32;
1193 return NVal::CreateNull(env).val_;
1194 }
1195
VertexAttribI4uiv(napi_env env,GLuint index,napi_value data)1196 napi_value WebGL2RenderingContextImpl::VertexAttribI4uiv(napi_env env, GLuint index, napi_value data)
1197 {
1198 VertexAttribInfo* info = GetVertexAttribInfo(index);
1199 if (info == nullptr) {
1200 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1201 return NVal::CreateNull(env).val_;
1202 }
1203 WebGLReadBufferArg bufferData(env);
1204 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_UINT_32);
1205 if (status != 0) {
1206 LOGE("WebGL vertexAttribI4uiv failed to getbuffer data");
1207 return NVal::CreateNull(env).val_;
1208 }
1209 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1210 if (bufferData.GetBufferDataType() != BUFFER_DATA_UINT_32) {
1211 LOGE("WebGL2 vertexAttribI4uiv invalid data type %{public}d", bufferData.GetBufferDataType());
1212 return NVal::CreateNull(env).val_;
1213 }
1214 glVertexAttribI4uiv(index, reinterpret_cast<const GLuint*>(bufferData.GetBuffer()));
1215 info->type = BUFFER_DATA_UINT_32;
1216 return NVal::CreateNull(env).val_;
1217 }
1218
VertexAttribIPointer(napi_env env,const VertexAttribArg & vertexInfo)1219 napi_value WebGL2RenderingContextImpl::VertexAttribIPointer(napi_env env, const VertexAttribArg& vertexInfo)
1220 {
1221 vertexInfo.Dump("WebGL2 vertexAttribPointer");
1222 if (!CheckGLenum(vertexInfo.type,
1223 { GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT }, {})) {
1224 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1225 "WebGL vertexAttribPointer invalid type %{public}u", vertexInfo.type);
1226 }
1227
1228 GLenum result = CheckVertexAttribPointer(env, vertexInfo);
1229 if (result) {
1230 SET_ERROR(result);
1231 return NVal::CreateNull(env).val_;
1232 }
1233
1234 glVertexAttribIPointer(vertexInfo.index, vertexInfo.size, vertexInfo.type, vertexInfo.stride,
1235 reinterpret_cast<GLvoid*>(vertexInfo.offset));
1236 LOGD("WebGL vertexAttribPointer index %{public}u offset %{public}u", vertexInfo.index, vertexInfo.offset);
1237 return NVal::CreateNull(env).val_;
1238 }
1239
VertexAttribDivisor(napi_env env,GLuint index,GLuint divisor)1240 napi_value WebGL2RenderingContextImpl::VertexAttribDivisor(napi_env env, GLuint index, GLuint divisor)
1241 {
1242 LOGD("WebGL2 vertexAttribDivisor index %{public}u divisor %{public}u", index, divisor);
1243 if (index >= GetMaxVertexAttribs()) {
1244 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1245 "WebGL2 vertexAttribDivisor invalid index %{public}u", index);
1246 return NVal::CreateNull(env).val_;
1247 }
1248 glVertexAttribDivisor(index, divisor);
1249 return NVal::CreateNull(env).val_;
1250 }
1251
DrawBuffers(napi_env env,napi_value dataObj)1252 napi_value WebGL2RenderingContextImpl::DrawBuffers(napi_env env, napi_value dataObj)
1253 {
1254 WebGLReadBufferArg bufferData(env);
1255 napi_status status = bufferData.GenBufferData(dataObj, BUFFER_DATA_GLENUM);
1256 if (status != 0) {
1257 LOGE("WebGL glDrawBuffers failed to getbuffer data");
1258 return NVal::CreateNull(env).val_;
1259 }
1260 if (bufferData.GetBufferType() != BUFFER_ARRAY) {
1261 LOGE("WebGL glDrawBuffers invalid buffer type %d", bufferData.GetBufferType());
1262 return NVal::CreateNull(env).val_;
1263 }
1264 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1265 GLenum* data = reinterpret_cast<GLenum*>(bufferData.GetBuffer());
1266 GLsizei length = static_cast<GLsizei>(bufferData.GetBufferLength() / sizeof(GLenum));
1267 glDrawBuffers(length, data);
1268 return NVal::CreateNull(env).val_;
1269 }
1270
DrawArraysInstanced(napi_env env,GLenum mode,GLint first,GLsizei count,GLsizei instanceCount)1271 napi_value WebGL2RenderingContextImpl::DrawArraysInstanced(
1272 napi_env env, GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1273 {
1274 LOGD("WebGL drawArraysInstanced mode %{public}u %{public}d %{public}d %{public}d",
1275 mode, first, count, instanceCount);
1276 GLenum result = CheckDrawArrays(env, mode, first, count);
1277 if (result != WebGLRenderingContextBase::NO_ERROR) {
1278 SET_ERROR_WITH_LOG(result, "CheckDrawArrays failed");
1279 return NVal::CreateNull(env).val_;
1280 }
1281 if (instanceCount < 0) {
1282 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "instanceCount < 0");
1283 return NVal::CreateNull(env).val_;
1284 }
1285 glDrawArraysInstanced(mode, first, count, instanceCount);
1286 return NVal::CreateNull(env).val_;
1287 }
1288
DrawElementsInstanced(napi_env env,const DrawElementArg & arg,GLsizei instanceCount)1289 napi_value WebGL2RenderingContextImpl::DrawElementsInstanced(
1290 napi_env env, const DrawElementArg& arg, GLsizei instanceCount)
1291 {
1292 LOGD("WebGL2 drawElementsInstanced mode %{public}u %{public}d %{public}u", arg.mode, arg.count, arg.type);
1293 GLenum result = CheckDrawElements(env, arg.mode, arg.count, arg.type, arg.offset);
1294 if (result != WebGLRenderingContextBase::NO_ERROR) {
1295 SET_ERROR_WITH_LOG(result, "CheckDrawElements failed");
1296 return NVal::CreateNull(env).val_;
1297 }
1298 if (instanceCount < 0) {
1299 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "instanceCount < 0");
1300 return NVal::CreateNull(env).val_;
1301 }
1302 glDrawElementsInstanced(arg.mode, arg.count, arg.type, reinterpret_cast<GLvoid*>(arg.offset), instanceCount);
1303 return NVal::CreateNull(env).val_;
1304 }
1305
DrawRangeElements(napi_env env,const DrawElementArg & arg,GLuint start,GLuint end)1306 napi_value WebGL2RenderingContextImpl::DrawRangeElements(
1307 napi_env env, const DrawElementArg& arg, GLuint start, GLuint end)
1308 {
1309 LOGD("WebGL2 drawRangeElements mode %{public}u %{public}d %{public}u start [%{public}u %{public}u]"
1310 "%{public}d" PRIi64, arg.mode, arg.count, arg.type, start, end, arg.offset);
1311 GLenum result = CheckDrawElements(env, arg.mode, arg.count, arg.type, arg.offset);
1312 if (result != WebGLRenderingContextBase::NO_ERROR) {
1313 SET_ERROR(result);
1314 return NVal::CreateNull(env).val_;
1315 }
1316 glDrawRangeElements(arg.mode, start, end, arg.count, arg.type, reinterpret_cast<GLvoid*>(arg.offset));
1317 return NVal::CreateNull(env).val_;
1318 }
1319
CopyBufferSubData(napi_env env,GLenum targets[2],int64_t readOffset,int64_t writeOffset,int64_t size)1320 napi_value WebGL2RenderingContextImpl::CopyBufferSubData(
1321 napi_env env, GLenum targets[2], int64_t readOffset, int64_t writeOffset, int64_t size)
1322 {
1323 LOGD("WebGL2 copyBufferSubData targets [%{public}u %{public}u] offset"
1324 " [%{public}" PRIi64 " %{public}" PRIi64 "] %{public}" PRIi64,
1325 targets[0], targets[1], readOffset, writeOffset, size);
1326 if (!WebGLArg::CheckNoneNegInt<GLint>(readOffset) || !WebGLArg::CheckNoneNegInt<GLint>(writeOffset) ||
1327 !WebGLArg::CheckNoneNegInt<GLint>(size)) {
1328 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "CheckNoneNegInt failed");
1329 return NVal::CreateNull(env).val_;
1330 }
1331 WebGLBuffer* readBuffer = GetBoundBuffer(env, targets[0]); // read
1332 if (readBuffer == nullptr || readBuffer->GetBufferSize() == 0) {
1333 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "readBuffer is nullptr or size is 0");
1334 return NVal::CreateNull(env).val_;
1335 }
1336 WebGLBuffer* writeBuffer = GetBoundBuffer(env, targets[1]); // write
1337 if (writeBuffer == nullptr || writeBuffer->GetBufferSize() == 0) {
1338 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "writeBuffer is nullptr or size is 0");
1339 return NVal::CreateNull(env).val_;
1340 }
1341 if (readOffset + size > static_cast<int64_t>(readBuffer->GetBufferSize()) ||
1342 writeOffset + size > static_cast<int64_t>(writeBuffer->GetBufferSize())) {
1343 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "readOffset or writeOffset size error");
1344 return NVal::CreateNull(env).val_;
1345 }
1346 if ((writeBuffer->GetTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffer->GetTarget() != GL_ELEMENT_ARRAY_BUFFER) ||
1347 (writeBuffer->GetTarget() != GL_ELEMENT_ARRAY_BUFFER && readBuffer->GetTarget() == GL_ELEMENT_ARRAY_BUFFER)) {
1348 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "readOffset or writeOffset GetTarget failed");
1349 return NVal::CreateNull(env).val_;
1350 }
1351 if (writeBuffer->GetTarget() == 0) {
1352 writeBuffer->SetTarget(readBuffer->GetTarget());
1353 }
1354 glCopyBufferSubData(targets[0], targets[1], static_cast<GLintptr>(readOffset), static_cast<GLintptr>(writeOffset),
1355 static_cast<GLsizeiptr>(size));
1356 LOGD("WebGL2 copyBufferSubData result %{public}u", GetError_());
1357 return NVal::CreateNull(env).val_;
1358 }
1359
GetBufferSubData(napi_env env,GLenum target,int64_t offset,napi_value data,const BufferExt & ext)1360 napi_value WebGL2RenderingContextImpl::GetBufferSubData(
1361 napi_env env, GLenum target, int64_t offset, napi_value data, const BufferExt& ext)
1362 {
1363 LOGD("WebGL2 getBufferSubData target %{public}u %{public}" PRIi64, target, offset);
1364 WebGLReadBufferArg bufferData(env);
1365 napi_status status = bufferData.GenBufferData(data);
1366 if (status != 0 || bufferData.GetBufferType() == BUFFER_ARRAY) {
1367 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "check buffer failed");
1368 return NVal::CreateNull(env).val_;
1369 }
1370 if (!WebGLArg::CheckNoneNegInt<GLint>(offset)) {
1371 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "CheckNoneNegInt failed");
1372 return NVal::CreateNull(env).val_;
1373 }
1374 WebGLBuffer* writeBuffer = GetBoundBuffer(env, target);
1375 if (writeBuffer == nullptr || writeBuffer->GetBufferSize() == 0) {
1376 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "no buffer");
1377 return NVal::CreateNull(env).val_;
1378 }
1379 if (static_cast<size_t>(offset) + bufferData.GetBufferLength() > writeBuffer->GetBufferSize()) {
1380 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "check buffer size failed");
1381 return NVal::CreateNull(env).val_;
1382 }
1383 GLsizeiptr dstSize = (ext.length == 0) ? static_cast<GLsizeiptr>(bufferData.GetBufferLength())
1384 : static_cast<GLsizeiptr>(ext.length * bufferData.GetBufferDataSize());
1385 GLuint dstOffset = static_cast<GLuint>(ext.offset * bufferData.GetBufferDataSize());
1386 LOGD("WebGL2 getBufferSubData dstSize %{public}u dstOffset %{public}p", dstSize, writeBuffer->bufferData_);
1387
1388 void *mapBuffer = glMapBufferRange(target, static_cast<GLintptr>(offset), dstSize, GL_MAP_READ_BIT);
1389 if (mapBuffer == nullptr ||
1390 memcpy_s(bufferData.GetBuffer() + dstOffset, bufferData.GetBufferLength(), mapBuffer, dstSize) != 0) {
1391 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "mapBuffer is nullptr");
1392 }
1393 glUnmapBuffer(target);
1394 LOGD("WebGL2 getBufferSubData target %{public}u result %{public}u ", target, GetError_());
1395 return NVal::CreateNull(env).val_;
1396 }
1397
BlitFrameBuffer(napi_env env,GLint data[8],GLbitfield mask,GLenum filter)1398 napi_value WebGL2RenderingContextImpl::BlitFrameBuffer(napi_env env, GLint data[8], GLbitfield mask, GLenum filter)
1399 {
1400 // 0,1,2,3,4,5,6,7 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1
1401 glBlitFramebuffer(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], mask, filter);
1402 LOGD("WebGL2 blitFrameBuffer filter %{public}u result %{public}u ", filter, GetError_());
1403 return NVal::CreateNull(env).val_;
1404 }
1405
FrameBufferTextureLayer(napi_env env,GLenum target,GLenum attachment,napi_value textureObj,const TextureLayerArg & layer)1406 napi_value WebGL2RenderingContextImpl::FrameBufferTextureLayer(
1407 napi_env env, GLenum target, GLenum attachment, napi_value textureObj, const TextureLayerArg& layer)
1408 {
1409 int32_t textureId = WebGLTexture::DEFAULT_TEXTURE;
1410 WebGLTexture* webGlTexture = WebGLTexture::GetObjectInstance(env, textureObj);
1411 if (webGlTexture == nullptr) {
1412 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1413 return NVal::CreateNull(env).val_;
1414 }
1415 textureId = static_cast<int32_t>(webGlTexture->GetTexture());
1416 glFramebufferTextureLayer(target, attachment, textureId, layer.level, layer.layer);
1417 LOGD("WebGL frameBufferTextureLayer texture %{public}d result %{public}u", textureId, GetError_());
1418
1419 WebGLFramebuffer* frameBuffer = GetBoundFrameBuffer(env, target);
1420 if (frameBuffer == nullptr) {
1421 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "can not find bind frame buffer");
1422 return NVal::CreateNull(env).val_;
1423 }
1424 frameBuffer->AddAttachment(
1425 target, attachment, static_cast<GLuint>(textureId), webGlTexture->GetTarget(), layer.level);
1426 return NVal::CreateNull(env).val_;
1427 }
1428
ReadBuffer(napi_env env,GLenum mode)1429 napi_value WebGL2RenderingContextImpl::ReadBuffer(napi_env env, GLenum mode)
1430 {
1431 LOGD("WebGL2 readBuffer mode %{public}u", mode);
1432 if (!CheckReadBufferMode(mode)) {
1433 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckReadBufferMode failed");
1434 return NVal::CreateNull(env).val_;
1435 }
1436
1437 WebGLFramebuffer* readFrameBuffer = GetBoundFrameBuffer(env, WebGL2RenderingContextBase::READ_FRAMEBUFFER);
1438 if (readFrameBuffer == nullptr) {
1439 if (mode != WebGLRenderingContextBase::BACK && mode != WebGLRenderingContextBase::NONE) {
1440 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION,
1441 "readFrameBuffer is nullptr, mode %{public}u", mode);
1442 return NVal::CreateNull(env).val_;
1443 }
1444 defaultReadBufferMode_ = mode;
1445 if (mode == WebGLRenderingContextBase::BACK) {
1446 mode = WebGLRenderingContextBase::COLOR_ATTACHMENT0;
1447 }
1448 } else {
1449 if (mode == WebGLRenderingContextBase::BACK) {
1450 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "mode %{public}u", mode);
1451 return NVal::CreateNull(env).val_;
1452 }
1453 readFrameBuffer->SetReadBufferMode(mode);
1454 }
1455 glReadBuffer(mode);
1456 return NVal::CreateNull(env).val_;
1457 }
1458
RenderBufferStorageMultiSample(napi_env env,const TexStorageArg & arg,GLsizei samples)1459 napi_value WebGL2RenderingContextImpl::RenderBufferStorageMultiSample(
1460 napi_env env, const TexStorageArg& arg, GLsizei samples)
1461 {
1462 arg.Dump("WebGL2 renderbufferStorageMultisample");
1463 LOGD("WebGL2 renderbufferStorageMultisample samples %{public}d", samples);
1464
1465 WebGLRenderbuffer* renderBuffer = CheckRenderBufferStorage(env, arg);
1466 if (renderBuffer == nullptr) {
1467 return NVal::CreateNull(env).val_;
1468 }
1469 if (samples < 0) {
1470 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "samples < 0");
1471 return NVal::CreateNull(env).val_;
1472 }
1473 if (arg.internalFormat == GL_DEPTH_STENCIL) {
1474 if (samples > 0) {
1475 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "GL_DEPTH_STENCIL samples > 0");
1476 return NVal::CreateNull(env).val_;
1477 }
1478 glRenderbufferStorage(arg.target, GL_DEPTH24_STENCIL8, arg.width, arg.height);
1479 } else {
1480 if (CheckInList(arg.internalFormat, WebGLTexture::GetSupportInternalFormatGroup1())) {
1481 if (samples > 0) {
1482 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckInList group1 failed");
1483 return NVal::CreateNull(env).val_;
1484 }
1485 } else if (!CheckInList(arg.internalFormat, WebGLTexture::GetSupportInternalFormatGroup2())) {
1486 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckInList group2 failed");
1487 return NVal::CreateNull(env).val_;
1488 }
1489 if (samples == 0) {
1490 glRenderbufferStorage(arg.target, arg.internalFormat, arg.width, arg.height);
1491 } else {
1492 glRenderbufferStorageMultisample(arg.target, samples, arg.internalFormat, arg.width, arg.height);
1493 }
1494 }
1495 renderBuffer->SetInternalFormat(arg.internalFormat);
1496 renderBuffer->SetSize(arg.width, arg.height);
1497 LOGD("WebGL2 renderbufferStorageMultisample result %{public}u", GetError_());
1498 return NVal::CreateNull(env).val_;
1499 }
1500
BindBuffer(napi_env env,GLenum target,napi_value object)1501 napi_value WebGL2RenderingContextImpl::BindBuffer(napi_env env, GLenum target, napi_value object)
1502 {
1503 // support default value
1504 uint32_t bufferId = WebGLBuffer::DEFAULT_BUFFER;
1505 WebGLBuffer* webGlBuffer = GetValidBuffer(env, object);
1506 if (webGlBuffer != nullptr) {
1507 bufferId = webGlBuffer->GetBufferId();
1508 }
1509 uint32_t index = BoundBufferType::ARRAY_BUFFER;
1510 if (!CheckBufferTarget(env, target, index)) {
1511 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1512 return NVal::CreateNull(env).val_;
1513 }
1514 if (webGlBuffer != nullptr && !CheckBufferTargetCompatibility(env, target, webGlBuffer)) {
1515 SET_ERROR(WebGLRenderingContextBase::INVALID_OPERATION);
1516 return NVal::CreateNull(env).val_;
1517 }
1518 if (boundBufferIds_[index] && boundBufferIds_[index] != bufferId) {
1519 LOGD("WebGL2 bindBuffer has been bound bufferId %{public}u", boundBufferIds_[index]);
1520 }
1521 boundBufferIds_[index] = bufferId;
1522
1523 glBindBuffer(target, static_cast<GLuint>(bufferId));
1524 if (webGlBuffer) {
1525 webGlBuffer->SetTarget(target);
1526 }
1527 LOGD("WebGL2 bindBuffer target %{public}u bufferId %{public}u result %{public}u",
1528 target, bufferId, GetError_());
1529 return NVal::CreateNull(env).val_;
1530 }
1531
BindBufferBase(napi_env env,const BufferBaseArg & arg,napi_value bufferObj)1532 napi_value WebGL2RenderingContextImpl::BindBufferBase(napi_env env, const BufferBaseArg& arg, napi_value bufferObj)
1533 {
1534 GLuint bufferId = WebGLBuffer::DEFAULT_BUFFER;
1535 WebGLBuffer* webGlBuffer = GetValidBuffer(env, bufferObj);
1536 if (webGlBuffer != nullptr) {
1537 bufferId = webGlBuffer->GetBufferId();
1538 }
1539 if (!CheckBufferBindTarget(arg.target)) {
1540 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckBufferBindTarget failed");
1541 return NVal::CreateNull(env).val_;
1542 }
1543 if (webGlBuffer != nullptr && !CheckBufferTargetCompatibility(env, arg.target, webGlBuffer)) {
1544 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckBufferTargetCompatibility failed");
1545 return NVal::CreateNull(env).val_;
1546 }
1547 if (!UpdateBaseTargetBoundBuffer(env, arg.target, arg.index, bufferId)) {
1548 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "UpdateBaseTargetBoundBuffer failed");
1549 return NVal::CreateNull(env).val_;
1550 }
1551 if (webGlBuffer != nullptr && !webGlBuffer->GetTarget()) {
1552 webGlBuffer->SetTarget(arg.target);
1553 }
1554 glBindBufferBase(arg.target, arg.index, bufferId);
1555 LOGD("WebGL2 bindBufferBase target %{public}u %{public}u %{public}u result %{public}u ",
1556 arg.target, arg.index, bufferId, GetError_());
1557 return NVal::CreateNull(env).val_;
1558 }
1559
BindBufferRange(napi_env env,const BufferBaseArg & arg,napi_value bufferObj,GLintptr offset,GLsizeiptr size)1560 napi_value WebGL2RenderingContextImpl::BindBufferRange(
1561 napi_env env, const BufferBaseArg& arg, napi_value bufferObj, GLintptr offset, GLsizeiptr size)
1562 {
1563 GLuint bufferId = WebGLBuffer::DEFAULT_BUFFER;
1564 WebGLBuffer* webGlBuffer = GetValidBuffer(env, bufferObj);
1565 if (webGlBuffer != nullptr) {
1566 bufferId = webGlBuffer->GetBufferId();
1567 }
1568 if (!CheckBufferBindTarget(arg.target)) {
1569 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckBufferBindTarget failed");
1570 return NVal::CreateNull(env).val_;
1571 }
1572 if (webGlBuffer != nullptr && !CheckBufferTargetCompatibility(env, arg.target, webGlBuffer)) {
1573 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "CheckBufferTargetCompatibility failed");
1574 return NVal::CreateNull(env).val_;
1575 }
1576 if (!UpdateBaseTargetBoundBuffer(env, arg.target, arg.index, bufferId)) {
1577 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_OPERATION, "UpdateBaseTargetBoundBuffer failed");
1578 return NVal::CreateNull(env).val_;
1579 }
1580 if (webGlBuffer != nullptr && !webGlBuffer->GetTarget()) {
1581 webGlBuffer->SetTarget(arg.target);
1582 }
1583 LOGD("WebGL2 bindBufferRange target %{public}u %{public}u %{public}u", arg.target, arg.index, bufferId);
1584 glBindBufferRange(arg.target, arg.index, bufferId, offset, size);
1585 return NVal::CreateNull(env).val_;
1586 }
1587
DeleteBuffer(napi_env env,napi_value object)1588 napi_value WebGL2RenderingContextImpl::DeleteBuffer(napi_env env, napi_value object)
1589 {
1590 return WebGLRenderingContextBaseImpl::DeleteBuffer(env, object);
1591 }
1592
GetUniformBlockIndex(napi_env env,napi_value programObj,const std::string & uniformBlockName)1593 napi_value WebGL2RenderingContextImpl::GetUniformBlockIndex(
1594 napi_env env, napi_value programObj, const std::string& uniformBlockName)
1595 {
1596 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1597 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1598 if (webGLProgram == nullptr) {
1599 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "webGLProgram is nullptr");
1600 return NVal::CreateInt64(env, -1).val_;
1601 }
1602 programId = webGLProgram->GetProgramId();
1603 if (!WebGLArg::CheckString(uniformBlockName)) {
1604 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "CheckString failed");
1605 return NVal::CreateInt64(env, -1).val_;
1606 }
1607 GLuint returnValue = glGetUniformBlockIndex(programId, uniformBlockName.c_str());
1608 LOGD("WebGL2 getUniformBlockIndex name %{public}s programId %{public}u result %{public}u",
1609 uniformBlockName.c_str(), programId, returnValue);
1610 return NVal::CreateInt64(env, returnValue).val_;
1611 }
1612
UniformBlockBinding(napi_env env,napi_value programObj,GLuint uniformBlockIndex,GLuint uniformBlockBinding)1613 napi_value WebGL2RenderingContextImpl::UniformBlockBinding(
1614 napi_env env, napi_value programObj, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
1615 {
1616 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1617 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1618 if (webGLProgram == nullptr) {
1619 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1620 return NVal::CreateNull(env).val_;
1621 }
1622 programId = webGLProgram->GetProgramId();
1623 glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding);
1624 LOGD("WebGL2 uniformBlockBinding programId %{public}u %{public}u %{public}u result %{public}u",
1625 programId, uniformBlockIndex, uniformBlockBinding, GetError_());
1626 return NVal::CreateNull(env).val_;
1627 }
1628
InvalidateFrameBuffer(napi_env env,GLenum target,napi_value data)1629 napi_value WebGL2RenderingContextImpl::InvalidateFrameBuffer(napi_env env, GLenum target, napi_value data)
1630 {
1631 LOGD("WebGL2 invalidate Framebuffer target %{public}u", target);
1632 WebGLReadBufferArg bufferData(env);
1633 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_GLENUM);
1634 if (status != 0) {
1635 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1636 "WebGL2 invalidateFramebuffer failed to getbuffer data");
1637 return NVal::CreateNull(env).val_;
1638 }
1639 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1640 if (bufferData.GetBufferDataType() != BUFFER_DATA_GLENUM) {
1641 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1642 "WebGL2 invalidateFramebuffer invalid data type %{public}u", bufferData.GetBufferDataType());
1643 return NVal::CreateNull(env).val_;
1644 }
1645 if (bufferData.GetBufferType() != BUFFER_ARRAY) {
1646 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1647 "WebGL2 invalidateFramebuffer invalid type %{public}u", bufferData.GetBufferType());
1648 return NVal::CreateNull(env).val_;
1649 }
1650 glInvalidateFramebuffer(target, static_cast<GLsizei>(bufferData.GetBufferLength() / sizeof(GLenum)),
1651 reinterpret_cast<GLenum*>(bufferData.GetBuffer()));
1652 return NVal::CreateNull(env).val_;
1653 }
1654
InvalidateSubFrameBuffer(napi_env env,GLenum target,napi_value data,const BufferPosition & position,const BufferSize & size)1655 napi_value WebGL2RenderingContextImpl::InvalidateSubFrameBuffer(
1656 napi_env env, GLenum target, napi_value data, const BufferPosition& position, const BufferSize& size)
1657 {
1658 WebGLReadBufferArg bufferData(env);
1659 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_GLENUM);
1660 if (status != 0) {
1661 LOGE("WebGL2 invalidateFramebuffer failed to getbuffer data");
1662 return NVal::CreateNull(env).val_;
1663 }
1664 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1665 if (bufferData.GetBufferDataType() != BUFFER_DATA_GLENUM) {
1666 LOGE("WebGL2 invalidateFramebuffer invalid data type %{public}d", bufferData.GetBufferDataType());
1667 return NVal::CreateNull(env).val_;
1668 }
1669 if (bufferData.GetBufferType() != BUFFER_ARRAY) {
1670 LOGE("WebGL2 invalidateFramebuffer invalid type %{public}d", bufferData.GetBufferType());
1671 return NVal::CreateNull(env).val_;
1672 }
1673
1674 glInvalidateSubFramebuffer(target, static_cast<GLsizei>(bufferData.GetBufferLength() / sizeof(GLenum)),
1675 reinterpret_cast<GLenum*>(bufferData.GetBuffer()), position.x, position.y, size.width, size.height);
1676 return NVal::CreateNull(env).val_;
1677 }
1678
GetInternalFormatParameter(napi_env env,GLenum target,GLenum internalFormat,GLenum pname)1679 napi_value WebGL2RenderingContextImpl::GetInternalFormatParameter(
1680 napi_env env, GLenum target, GLenum internalFormat, GLenum pname)
1681 {
1682 if (target != WebGLRenderingContextBase::RENDERBUFFER) {
1683 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "target %{publuc}u", target);
1684 return NVal::CreateNull(env).val_;
1685 }
1686 LOGD("WebGL2 getInternalformatParameter target %{public}u %{public}u %{public}u", target, internalFormat, pname);
1687 WebGLWriteBufferArg writeBuffer(env);
1688 if (CheckInList(internalFormat, WebGLTexture::GetSupportInternalFormatGroup1())) {
1689 return writeBuffer.ToExternalArray(BUFFER_DATA_INT_32);
1690 } else if (!CheckInList(internalFormat, WebGLTexture::GetSupportInternalFormatGroup2())) {
1691 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "CheckInList failed");
1692 return NVal::CreateNull(env).val_;
1693 }
1694
1695 GLint length = -1;
1696 if (pname == GL_SAMPLES) {
1697 glGetInternalformativ(target, internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &length);
1698 LOGD("WebGL2 getInternalformatParameter length %{public}u", length);
1699 } else {
1700 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_ENUM, "pname %{publuc}u", pname);
1701 return NVal::CreateNull(env).val_;
1702 }
1703 if (length > 0) {
1704 GLint* params = reinterpret_cast<GLint*>(writeBuffer.AllocBuffer(length * sizeof(GLint)));
1705 if (params == nullptr) {
1706 return NVal::CreateNull(env).val_;
1707 }
1708 glGetInternalformativ(target, internalFormat, pname, length, params);
1709 writeBuffer.DumpBuffer(BUFFER_DATA_INT_32);
1710 }
1711 return writeBuffer.ToExternalArray(BUFFER_DATA_INT_32);
1712 }
1713
TransformFeedbackVaryings(napi_env env,napi_value programObj,napi_value data,GLenum bufferMode)1714 napi_value WebGL2RenderingContextImpl::TransformFeedbackVaryings(
1715 napi_env env, napi_value programObj, napi_value data, GLenum bufferMode)
1716 {
1717 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1718 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1719 if (webGLProgram == nullptr) {
1720 return NVal::CreateNull(env).val_;
1721 }
1722 programId = webGLProgram->GetProgramId();
1723 if (bufferMode != GL_INTERLEAVED_ATTRIBS && bufferMode != GL_SEPARATE_ATTRIBS) {
1724 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1725 return NVal::CreateNull(env).val_;
1726 }
1727 std::vector<char*> list = {};
1728 bool succ = WebGLArg::GetStringList(env, data, list);
1729 if (!succ) {
1730 WebGLArg::FreeStringList(list);
1731 return NVal::CreateNull(env).val_;
1732 }
1733 glTransformFeedbackVaryings(programId, static_cast<GLsizei>(list.size()), list.data(), bufferMode);
1734 WebGLArg::FreeStringList(list);
1735 return NVal::CreateNull(env).val_;
1736 }
1737
GetUniformIndices(napi_env env,napi_value programObj,napi_value data)1738 napi_value WebGL2RenderingContextImpl::GetUniformIndices(napi_env env, napi_value programObj, napi_value data)
1739 {
1740 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1741 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1742 if (webGLProgram == nullptr) {
1743 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1744 return NVal::CreateNull(env).val_;
1745 }
1746 programId = webGLProgram->GetProgramId();
1747
1748 std::vector<char*> list = {};
1749 bool succ = WebGLArg::GetStringList(env, data, list);
1750 if (!succ) {
1751 WebGLArg::FreeStringList(list);
1752 return NVal::CreateNull(env).val_;
1753 }
1754 LOGD("WebGL2 getUniformIndices uniformCount %{public}zu", list.size());
1755
1756 WebGLWriteBufferArg writeBuffer(env);
1757 napi_value result = NVal::CreateNull(env).val_;
1758 GLuint* uniformIndices = reinterpret_cast<GLuint*>(writeBuffer.AllocBuffer(list.size() * sizeof(GLuint)));
1759 if (uniformIndices != nullptr) {
1760 glGetUniformIndices(programId, static_cast<GLsizei>(list.size()), const_cast<const GLchar**>(list.data()),
1761 static_cast<GLuint*>(uniformIndices));
1762 writeBuffer.DumpBuffer(BUFFER_DATA_UINT_32);
1763 result = writeBuffer.ToNormalArray(BUFFER_DATA_UINT_32, BUFFER_DATA_UINT_32);
1764 }
1765 WebGLArg::FreeStringList(list);
1766 return result;
1767 }
1768
GetActiveUniforms(napi_env env,napi_value programObj,napi_value data,GLenum pname)1769 napi_value WebGL2RenderingContextImpl::GetActiveUniforms(
1770 napi_env env, napi_value programObj, napi_value data, GLenum pname)
1771 {
1772 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1773 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1774 if (webGLProgram == nullptr) {
1775 SET_ERROR(WebGLRenderingContextBase::INVALID_VALUE);
1776 return NVal::CreateNull(env).val_;
1777 }
1778 if (pname == GL_UNIFORM_NAME_LENGTH) {
1779 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1780 return NVal::CreateNull(env).val_;
1781 }
1782
1783 programId = webGLProgram->GetProgramId();
1784 LOGD("WebGL2 getActiveUniforms programId %{public}u pname %{public}u", programId, pname);
1785 WebGLReadBufferArg bufferData(env);
1786 napi_status status = bufferData.GenBufferData(data, BUFFER_DATA_UINT_32);
1787 if (status != 0) {
1788 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE,
1789 "WebGL2 invalidateFramebuffer failed to getbuffer data");
1790 return NVal::CreateNull(env).val_;
1791 }
1792 bufferData.DumpBuffer(bufferData.GetBufferDataType());
1793 GLsizei size = static_cast<GLsizei>(bufferData.GetBufferLength() / bufferData.GetBufferDataSize());
1794
1795 WebGLWriteBufferArg writeBuffer(env);
1796 GLint* params = reinterpret_cast<GLint*>(writeBuffer.AllocBuffer(size * sizeof(GLint)));
1797 if (params == nullptr) {
1798 return NVal::CreateNull(env).val_;
1799 }
1800 glGetActiveUniformsiv(
1801 programId, size, reinterpret_cast<GLuint*>(bufferData.GetBuffer()), pname, reinterpret_cast<GLint*>(params));
1802 switch (pname) {
1803 case GL_UNIFORM_TYPE:
1804 case GL_UNIFORM_SIZE:
1805 return writeBuffer.ToNormalArray(BUFFER_DATA_INT_32, BUFFER_DATA_BIGUINT_64);
1806 case GL_UNIFORM_BLOCK_INDEX:
1807 case GL_UNIFORM_OFFSET:
1808 case GL_UNIFORM_ARRAY_STRIDE:
1809 case GL_UNIFORM_MATRIX_STRIDE:
1810 return writeBuffer.ToNormalArray(BUFFER_DATA_INT_32, BUFFER_DATA_INT_32);
1811 case GL_UNIFORM_IS_ROW_MAJOR:
1812 return writeBuffer.ToNormalArray(BUFFER_DATA_INT_32, BUFFER_DATA_BOOLEAN);
1813 default:
1814 break;
1815 }
1816 return NVal::CreateNull(env).val_;
1817 }
1818
GetActiveUniformBlockParameter(napi_env env,napi_value programObj,GLuint uniformBlockIndex,GLenum pname)1819 napi_value WebGL2RenderingContextImpl::GetActiveUniformBlockParameter(
1820 napi_env env, napi_value programObj, GLuint uniformBlockIndex, GLenum pname)
1821 {
1822 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1823 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1824 if (webGLProgram == nullptr) {
1825 return NVal::CreateInt64(env, -1).val_;
1826 }
1827 programId = webGLProgram->GetProgramId();
1828 LOGD("WebGL2 getActiveUniformBlockParameter programId %{public}u %{public}u %{public}u",
1829 programId, uniformBlockIndex, pname);
1830 switch (pname) {
1831 case GL_UNIFORM_BLOCK_BINDING:
1832 case GL_UNIFORM_BLOCK_DATA_SIZE:
1833 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
1834 GLint params;
1835 glGetActiveUniformBlockiv(programId, uniformBlockIndex, pname, ¶ms);
1836 return NVal::CreateInt64(env, params).val_;
1837 }
1838 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
1839 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: {
1840 GLint params;
1841 glGetActiveUniformBlockiv(programId, uniformBlockIndex, pname, ¶ms);
1842 return NVal::CreateBool(env, params != GL_FALSE).val_;
1843 }
1844 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: {
1845 WebGLWriteBufferArg writeBuffer(env);
1846 GLint uniformCount = 1;
1847 glGetActiveUniformBlockiv(programId, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformCount);
1848 LOGD("WebGL2 getActiveUniformBlockParameter uniformCount %{public}d", uniformCount);
1849 GLint* params = reinterpret_cast<GLint*>(writeBuffer.AllocBuffer(uniformCount * sizeof(GLint)));
1850 if (params == nullptr) {
1851 return NVal::CreateNull(env).val_;
1852 }
1853 glGetActiveUniformBlockiv(programId, uniformBlockIndex, pname, params);
1854 return writeBuffer.ToNormalArray(BUFFER_DATA_INT_32, BUFFER_DATA_UINT_32);
1855 }
1856 default:
1857 SET_ERROR(WebGLRenderingContextBase::INVALID_ENUM);
1858 return NVal::CreateNull(env).val_;
1859 }
1860 return NVal::CreateInt64(env, -1).val_;
1861 }
1862
GetActiveUniformBlockName(napi_env env,napi_value programObj,GLuint uniformBlockIndex)1863 napi_value WebGL2RenderingContextImpl::GetActiveUniformBlockName(
1864 napi_env env, napi_value programObj, GLuint uniformBlockIndex)
1865 {
1866 GLuint programId = WebGLProgram::DEFAULT_PROGRAM_ID;
1867 WebGLProgram* webGLProgram = WebGLProgram::GetObjectInstance(env, programObj);
1868 if (webGLProgram == nullptr) {
1869 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "webGLProgram is nullptr");
1870 return NVal::CreateUTF8String(env, "").val_;
1871 }
1872 programId = webGLProgram->GetProgramId();
1873
1874 GLint length = 0;
1875 GLsizei size = 0;
1876 glGetProgramiv(programId, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &length);
1877 if (length <= 0) {
1878 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "length < 0");
1879 return NVal::CreateUTF8String(env, "").val_;
1880 }
1881 std::unique_ptr<char[]> buf = std::make_unique<char[]>(length + 1);
1882 if (buf == nullptr) {
1883 SET_ERROR_WITH_LOG(WebGLRenderingContextBase::INVALID_VALUE, "buf is nullptr");
1884 return NVal::CreateNull(env).val_;
1885 }
1886 glGetActiveUniformBlockName(programId, uniformBlockIndex, length, &size, buf.get());
1887 LOGD("WebGL2 getActiveUniformBlockName programId %{public}u uniformBlockIndex %{public}u name %{public}s",
1888 programId, uniformBlockIndex, buf.get());
1889 string str(buf.get(), size);
1890 return NVal::CreateUTF8String(env, str).val_;
1891 }
1892
CheckClearBuffer(napi_env env,GLenum buffer,const WebGLReadBufferArg & bufferData)1893 GLenum WebGL2RenderingContextImpl::CheckClearBuffer(napi_env env, GLenum buffer, const WebGLReadBufferArg& bufferData)
1894 {
1895 size_t size = bufferData.GetBufferLength() / bufferData.GetBufferDataSize();
1896 switch (buffer) {
1897 case WebGL2RenderingContextBase::COLOR:
1898 case WebGLRenderingContextBase::FRONT:
1899 case WebGLRenderingContextBase::BACK:
1900 case WebGLRenderingContextBase::FRONT_AND_BACK:
1901 if (size < 4) { // 4 max element
1902 return WebGLRenderingContextBase::INVALID_VALUE;
1903 }
1904 break;
1905 case WebGL2RenderingContextBase::DEPTH:
1906 case WebGL2RenderingContextBase::STENCIL:
1907 case WebGLRenderingContextBase::DEPTH_STENCIL:
1908 if (size < 1) {
1909 return WebGLRenderingContextBase::INVALID_VALUE;
1910 }
1911 break;
1912 default:
1913 return WebGLRenderingContextBase::INVALID_ENUM;
1914 }
1915 return WebGLRenderingContextBase::NO_ERROR;
1916 }
1917
CheckQueryTarget(napi_env env,GLenum target,uint32_t & index)1918 bool WebGL2RenderingContextImpl::CheckQueryTarget(napi_env env, GLenum target, uint32_t& index)
1919 {
1920 switch (target) {
1921 case WebGL2RenderingContextBase::ANY_SAMPLES_PASSED:
1922 case WebGL2RenderingContextBase::ANY_SAMPLES_PASSED_CONSERVATIVE:
1923 index = BoundQueryType::ANY_SAMPLES_PASSED;
1924 break;
1925 case WebGL2RenderingContextBase::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1926 index = BoundQueryType::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1927 break;
1928 default:
1929 return false;
1930 }
1931 return true;
1932 }
1933
CheckTexStorage(napi_env env,const TexStorageArg & arg)1934 GLenum WebGL2RenderingContextImpl::CheckTexStorage(napi_env env, const TexStorageArg& arg)
1935 {
1936 WebGLTexture* texture = GetBoundTexture(env, arg.target, false);
1937 if (!texture) {
1938 LOGE("CheckTexStorage %{public}u", arg.target);
1939 return WebGLRenderingContextBase::INVALID_OPERATION;
1940 }
1941
1942 if (!CheckStorageInternalFormat(env, arg.internalFormat)) {
1943 return WebGLRenderingContextBase::INVALID_ENUM;
1944 }
1945
1946 if (arg.width <= 0 || arg.height <= 0 || arg.depth <= 0) {
1947 LOGE("CheckTexStorage invalid width %{public}d, height %{public}d, depth %{public}d",
1948 arg.width, arg.height, arg.depth);
1949 return WebGLRenderingContextBase::INVALID_VALUE;
1950 }
1951
1952 if (arg.levels <= 0) {
1953 LOGE("CheckTexStorage invalid levels %{public}d", arg.levels);
1954 return WebGLRenderingContextBase::INVALID_VALUE;
1955 }
1956
1957 if (arg.target == GL_TEXTURE_3D) {
1958 if (arg.levels > log2(std::max(std::max(arg.width, arg.height), arg.depth)) + 1) {
1959 LOGE("CheckTexStorage invalid levels %{public}d", arg.levels);
1960 return WebGLRenderingContextBase::INVALID_OPERATION;
1961 }
1962 } else {
1963 if (arg.levels > log2(std::max(arg.width, arg.height)) + 1) {
1964 LOGE("CheckTexStorage invalid %{public}d %{public}d",
1965 arg.levels, log2(std::max(arg.width, arg.height)) + 1);
1966 return WebGLRenderingContextBase::INVALID_OPERATION;
1967 }
1968 }
1969 return WebGLRenderingContextBase::NO_ERROR;
1970 }
1971
CheckBufferBindTarget(GLenum target)1972 bool WebGL2RenderingContextImpl::CheckBufferBindTarget(GLenum target)
1973 {
1974 if (target == GL_TRANSFORM_FEEDBACK_BUFFER || target == GL_UNIFORM_BUFFER) {
1975 return true;
1976 }
1977 return false;
1978 }
1979
CheckTransformFeedbackBuffer(GLenum target,WebGLBuffer * buffer)1980 bool WebGL2RenderingContextImpl::CheckTransformFeedbackBuffer(GLenum target, WebGLBuffer* buffer)
1981 {
1982 if (target == GL_TRANSFORM_FEEDBACK_BUFFER) {
1983 for (size_t i = 0; i < sizeof(boundBufferIds_) / boundBufferIds_[0]; i++) {
1984 if (i == BoundBufferType::TRANSFORM_FEEDBACK_BUFFER) {
1985 continue;
1986 }
1987 if (boundBufferIds_[i] == buffer->GetBufferId()) {
1988 LOGD("boundBufferIds_ %{public}u %{public}zu", boundBufferIds_[i], i);
1989 return false;
1990 }
1991 }
1992 LOGD("boundIndexedUniformBuffers_ %{public}zu", boundIndexedUniformBuffers_.size());
1993 for (size_t i = 0; i < boundIndexedUniformBuffers_.size(); ++i) {
1994 if (boundIndexedUniformBuffers_[i] == buffer->GetBufferId()) {
1995 return false;
1996 }
1997 }
1998 } else {
1999 LOGD("Get TRANSFORM_FEEDBACK_BUFFER id %{public}u ",
2000 boundBufferIds_[BoundBufferType::TRANSFORM_FEEDBACK_BUFFER]);
2001 if (boundBufferIds_[BoundBufferType::TRANSFORM_FEEDBACK_BUFFER] == buffer->GetBufferId()) {
2002 return false;
2003 }
2004 for (size_t i = 0; i < boundIndexedTransformFeedbackBuffers_.size(); ++i) {
2005 if (boundIndexedTransformFeedbackBuffers_[i] == buffer->GetBufferId()) {
2006 return false;
2007 }
2008 }
2009 }
2010 return true;
2011 }
2012
CheckBufferTargetCompatibility(napi_env env,GLenum target,WebGLBuffer * buffer)2013 bool WebGL2RenderingContextImpl::CheckBufferTargetCompatibility(napi_env env, GLenum target, WebGLBuffer* buffer)
2014 {
2015 LOGD("buffer target %{public}u %{public}u id %{public}u", buffer->GetTarget(), target, buffer->GetBufferId());
2016 switch (buffer->GetTarget()) {
2017 case GL_ELEMENT_ARRAY_BUFFER:
2018 switch (target) {
2019 case GL_ARRAY_BUFFER:
2020 case GL_PIXEL_PACK_BUFFER:
2021 case GL_PIXEL_UNPACK_BUFFER:
2022 case GL_TRANSFORM_FEEDBACK_BUFFER:
2023 case GL_UNIFORM_BUFFER:
2024 return false;
2025 default:
2026 break;
2027 }
2028 break;
2029 case GL_ARRAY_BUFFER:
2030 case GL_COPY_READ_BUFFER:
2031 case GL_COPY_WRITE_BUFFER:
2032 case GL_PIXEL_PACK_BUFFER:
2033 case GL_PIXEL_UNPACK_BUFFER:
2034 case GL_UNIFORM_BUFFER:
2035 case GL_TRANSFORM_FEEDBACK_BUFFER:
2036 if (target == GL_ELEMENT_ARRAY_BUFFER) {
2037 return false;
2038 }
2039 break;
2040 default:
2041 break;
2042 }
2043 return CheckTransformFeedbackBuffer(target, buffer);
2044 }
2045
UpdateBaseTargetBoundBuffer(napi_env env,GLenum target,GLuint index,GLuint bufferId)2046 bool WebGL2RenderingContextImpl::UpdateBaseTargetBoundBuffer(
2047 napi_env env, GLenum target, GLuint index, GLuint bufferId)
2048 {
2049 if (target == GL_TRANSFORM_FEEDBACK_BUFFER) {
2050 if (index >= maxBoundTransformFeedbackBufferIndex_) {
2051 LOGE("Out of bound indexed transform feedback buffer %{public}u", index);
2052 return false;
2053 }
2054 boundIndexedTransformFeedbackBuffers_[index] = bufferId;
2055 boundBufferIds_[BoundBufferType::TRANSFORM_FEEDBACK_BUFFER] = bufferId;
2056 if (!bufferId) { // for delete
2057 boundIndexedTransformFeedbackBuffers_.erase(index);
2058 }
2059 return true;
2060 }
2061 if (target == GL_UNIFORM_BUFFER) {
2062 if (index >= maxBoundUniformBufferIndex_) {
2063 LOGE("Out of bound indexed uniform buffer %{public}u", index);
2064 return false;
2065 }
2066 boundIndexedUniformBuffers_[index] = bufferId;
2067 boundBufferIds_[BoundBufferType::UNIFORM_BUFFER] = bufferId;
2068 if (!bufferId) { // for delete
2069 boundIndexedUniformBuffers_.erase(index);
2070 }
2071 return true;
2072 }
2073 return false;
2074 }
2075
CheckStorageInternalFormat(napi_env env,GLenum internalFormat)2076 bool WebGL2RenderingContextImpl::CheckStorageInternalFormat(napi_env env, GLenum internalFormat)
2077 {
2078 return CheckInList(internalFormat, {
2079 GL_R8,
2080 GL_R8_SNORM,
2081 GL_R16F,
2082 GL_R32F,
2083 GL_R8UI,
2084 GL_R8I,
2085 GL_R16UI,
2086 GL_R16I,
2087 GL_R32UI,
2088 GL_R32I,
2089 GL_RG8,
2090 GL_RG8_SNORM,
2091 GL_RG16F,
2092 GL_RG32F,
2093 GL_RG8UI,
2094 GL_RG8I,
2095 GL_RG16UI,
2096 GL_RG16I,
2097 GL_RG32UI,
2098 GL_RG32I,
2099 GL_RGB8,
2100 GL_SRGB8,
2101 GL_RGB565,
2102 GL_RGB8_SNORM,
2103 GL_R11F_G11F_B10F,
2104 GL_RGB9_E5,
2105 GL_RGB16F,
2106 GL_RGB32F,
2107 GL_RGB8UI,
2108 GL_RGB8I,
2109 GL_RGB16UI,
2110 GL_RGB16I,
2111 GL_RGB32UI,
2112 GL_RGB32I,
2113 GL_RGBA8,
2114 GL_SRGB8_ALPHA8,
2115 GL_RGBA8_SNORM,
2116 GL_RGB5_A1,
2117 GL_RGBA4,
2118 GL_RGB10_A2,
2119 GL_RGBA16F,
2120 GL_RGBA32F,
2121 GL_RGBA8UI,
2122 GL_RGBA8I,
2123 GL_RGB10_A2UI,
2124 GL_RGBA16UI,
2125 GL_RGBA16I,
2126 GL_RGBA32UI,
2127 GL_RGBA32I,
2128 GL_DEPTH_COMPONENT16,
2129 GL_DEPTH_COMPONENT24,
2130 GL_DEPTH_COMPONENT32F,
2131 GL_DEPTH24_STENCIL8,
2132 GL_DEPTH32F_STENCIL8,
2133 GL_COMPRESSED_R11_EAC,
2134 GL_COMPRESSED_SIGNED_R11_EAC,
2135 GL_COMPRESSED_RG11_EAC,
2136 GL_COMPRESSED_SIGNED_RG11_EAC,
2137 GL_COMPRESSED_RGB8_ETC2,
2138 GL_COMPRESSED_SRGB8_ETC2,
2139 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
2140 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
2141 GL_COMPRESSED_RGBA8_ETC2_EAC,
2142 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
2143 });
2144 }
2145 } // namespace Impl
2146 } // namespace Rosen
2147 } // namespace OHOS
2148