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 
16 #ifndef ROSENRENDER_ROSEN_WEBGL_RENDERING_CONTEXT_BASE_IMPL
17 #define ROSENRENDER_ROSEN_WEBGL_RENDERING_CONTEXT_BASE_IMPL
18 
19 #include <GLES2/gl2.h>
20 #include <GLES2/gl2ext.h>
21 #include <GLES3/gl31.h>
22 #include <vector>
23 
24 #include "napi/n_exporter.h"
25 #include "securec.h"
26 #include "util/log.h"
27 #include "webgl_rendering_context_basic_base.h"
28 #include "webgl/webgl_active_info.h"
29 #include "webgl/webgl_arg.h"
30 #include "webgl/webgl_buffer.h"
31 #include "webgl/webgl_framebuffer.h"
32 #include "webgl/webgl_program.h"
33 #include "webgl/webgl_renderbuffer.h"
34 #include "webgl/webgl_shader.h"
35 #include "webgl/webgl_shader_precision_format.h"
36 #include "webgl/webgl_texture.h"
37 #include "webgl/webgl_uniform_location.h"
38 
39 namespace OHOS {
40 namespace Rosen {
41 namespace Impl {
42 using Image2DFunc = enum : int32_t {
43     IMAGE_TEX_IMAGE_2D,
44     IMAGE_TEX_SUB_IMAGE_2D,
45     IMAGE_COMPRESSED_TEX_IMAGE_2D,
46     IMAGE_COMPRESSED_TEX_SUB_IMAGE_2D,
47     IMAGE_COPY_TEX_IMAGE_2D,
48     IMAGE_COPY_TEX_SUB_IMAGE_2D,
49     IMAGE_TEX_IMAGE_3D,
50     IMAGE_SUB_TEX_IMAGE_3D,
51     IMAGE_COMPRESSED_TEX_IMAGE_3D,
52     IMAGE_COMPRESSED_TEX_SUB_IMAGE_3D,
53     IMAGE_COPY_TEX_IMAGE_3D,
54     IMAGE_COPY_TEX_SUB_IMAGE_3D,
55 };
56 enum BoundBufferType : uint32_t {
57     ARRAY_BUFFER,
58     ELEMENT_ARRAY_BUFFER,
59     COPY_READ_BUFFER,
60     COPY_WRITE_BUFFER,
61     TRANSFORM_FEEDBACK_BUFFER,
62     UNIFORM_BUFFER,
63     PIXEL_PACK_BUFFER,
64     PIXEL_UNPACK_BUFFER,
65     BUFFER_MAX
66 };
67 
68 enum BoundFrameBufferType : uint32_t {
69     FRAMEBUFFER,
70     DRAW_FRAMEBUFFER,
71     READ_FRAMEBUFFER,
72     FRAMEBUFFER_MAX
73 };
74 
75 enum BoundRenderBufferType : uint32_t {
76     RENDERBUFFER,
77     RENDERBUFFER_MAX
78 };
79 
80 enum BoundTextureType : uint32_t {
81     TEXTURE_2D,
82     TEXTURE_CUBE_MAP,
83     TEXTURE_3D,
84     TEXTURE_2D_ARRAY,
85     TEXTURE_MAX
86 };
87 
88 enum BoundShaderType : uint32_t {
89     VERTEX_SHADER,
90     FRAGMENT_SHADER,
91     SHADER_MAX
92 };
93 
94 class WebGLRenderingContextBaseImpl {
95 public:
96     inline static const int32_t MAX_COUNT_ATTACHED_SHADER = 128;
97     inline static const GLuint MAX_LOCATION_LENGTH = 512;
98     static const int32_t PARAMETERS_NUM_1 = 1;
99     static const int32_t PARAMETERS_NUM_2 = 2;
100     static const int32_t PARAMETERS_NUM_3 = 3;
101     static const int32_t PARAMETERS_NUM_4 = 4;
102 
WebGLRenderingContextBaseImpl(int32_t version,WebGLRenderingContextBasicBase * base)103     explicit WebGLRenderingContextBaseImpl(int32_t version, WebGLRenderingContextBasicBase *base)
104         : version_(version), webGLRenderingContext_(base) {}
105     virtual ~WebGLRenderingContextBaseImpl();
106 
107     virtual void Init();
108 
109     // common interface
IsHighWebGL()110     bool IsHighWebGL()
111     {
112         return version_ > WEBGL_1_0;
113     }
114 
SetError(GLenum error)115     void SetError(GLenum error)
116     {
117         lastError_ = error;
118     }
119 
120     napi_value GetContextAttributes(napi_env env);
121     // webgl  Texture
122     napi_value CreateTextureObject(napi_env env);
123     napi_value ActiveTexture(napi_env env, GLenum texture);
124     napi_value DeleteTexture(napi_env env, napi_value object);
125     napi_value BindTexture(napi_env env, GLenum target, napi_value texture);
126     napi_value TexParameteri(napi_env env, GLenum target, GLenum pname, GLint param);
127     napi_value TexParameterf(napi_env env, GLenum target, GLenum pname, GLfloat param);
128 
129     napi_value TexImage2D(napi_env env, const TexImageArg& info, GLintptr pbOffset);
130     napi_value TexImage2D(napi_env env, const TexImageArg& info, napi_value pixels, GLuint srcOffset);
131     napi_value TexImage2D(napi_env env, const TexImageArg& info, napi_value imageData);
132 
133     napi_value TexSubImage2D(napi_env env, const TexSubImage2DArg& info, GLintptr pbOffset);
134     napi_value TexSubImage2D(napi_env env, const TexSubImage2DArg& imgArg, napi_value pixels, GLuint srcOffset);
135     napi_value TexSubImage2D(napi_env env, const TexSubImage2DArg& info, napi_value imageData);
136     napi_value CompressedTexImage2D(napi_env env, const TexImageArg& arg, GLsizei imageSize, GLintptr offset);
137     napi_value CompressedTexImage2D(
138         napi_env env, const TexImageArg& arg, napi_value srcData, GLuint srcOffset, GLuint srcLengthOverride);
139     napi_value CompressedTexSubImage2D(napi_env env, const TexSubImage2DArg& imgArg,
140         napi_value srcData, GLuint srcOffset, GLuint srcLengthOverride);
141     napi_value CompressedTexSubImage2D(napi_env env, const TexSubImage2DArg& imgArg,
142         GLsizei imageSize, GLintptr offset);
143 
144     napi_value CopyTexImage2D(napi_env env, const CopyTexImage2DArg& imgArg);
145     napi_value CopyTexSubImage2D(napi_env env, const CopyTexSubImageArg& imgArg);
146 
147     napi_value ReadPixels(napi_env env, const PixelsArg& arg, GLintptr offset);
148     napi_value ReadPixels(napi_env env, const PixelsArg& arg, napi_value buffer, GLuint dstOffset);
149 
150     // for buffer
151     napi_value CreateBuffer(napi_env env);
152     virtual napi_value BindBuffer(napi_env env, GLenum target, napi_value object);
153     napi_value IsBuffer(napi_env env, napi_value object);
154     virtual napi_value DeleteBuffer(napi_env env, napi_value object);
155 
156     napi_value CreateFrameBuffer(napi_env env);
157     napi_value IsFrameBuffer(napi_env env, napi_value object);
158     napi_value BindFrameBuffer(napi_env env, GLenum target, napi_value object);
159     napi_value DeleteFrameBuffer(napi_env env, napi_value object);
160     napi_value GetBufferParameter(napi_env env, GLenum target, GLenum pname);
161 
162     napi_value CreateRenderBuffer(napi_env env);
163     napi_value BindRenderBuffer(napi_env env, GLenum target, napi_value object);
164     napi_value DeleteRenderBuffer(napi_env env, napi_value object);
165     napi_value GetRenderBufferParameter(napi_env env, GLenum target, GLenum pname);
166     napi_value RenderBufferStorage(napi_env env, const TexStorageArg& arg);
167 
168     napi_value CreateShader(napi_env env, GLenum type);
169     napi_value GetAttachedShaders(napi_env env, napi_value program);
170     napi_value CompileShader(napi_env env, napi_value object);
171     napi_value ShaderSource(napi_env env, napi_value object, const std::string& source);
172     napi_value AttachShader(napi_env env, napi_value programObj, napi_value shaderObj);
173     napi_value DetachShader(napi_env env, napi_value programObj, napi_value shaderObj);
174     napi_value DeleteShader(napi_env env, napi_value object);
175     napi_value GetShaderParameter(napi_env env, napi_value object, GLenum pname);
176     napi_value GetShaderPrecisionFormat(napi_env env, GLenum shaderType, GLenum precisionType);
177 
178     napi_value CreateProgram(napi_env env);
179     napi_value DeleteProgram(napi_env env, napi_value object);
180     napi_value GetProgramParameter(napi_env env, napi_value object, GLenum pname);
181     napi_value UseProgram(napi_env env, napi_value object);
182     napi_value ValidateProgram(napi_env env, napi_value object);
183     napi_value LinkProgram(napi_env env, napi_value object);
184 
185     napi_value GetUniformLocation(napi_env env, napi_value object, const std::string& name);
186     napi_value GetUniform(napi_env env, napi_value programObj, napi_value uniformObj);
187 
188     napi_value CheckFrameBufferStatus(napi_env env, GLenum target);
189 
190     napi_value FrameBufferRenderBuffer(
191         napi_env env, GLenum target, GLenum attachment, GLenum renderBufferTarget, napi_value object);
192     napi_value FrameBufferTexture2D(
193         napi_env env, GLenum target, GLenum attachment, GLenum textarget, napi_value texture, GLint level);
194 
195     napi_value DrawElements(napi_env env, GLenum mode, GLsizei count, GLenum type, GLintptr offset);
196     napi_value DrawArrays(napi_env env, GLenum mode, GLint first, GLsizei count);
197 
198     // webgl 1
199     napi_value BufferData(napi_env env, GLenum target, int64_t size, GLenum usage);
200     // webgl 2
201     napi_value BufferData(napi_env env, GLenum target, napi_value buffer, GLenum usage, const BufferExt& ext);
202 
203     napi_value BufferSubData(napi_env env, GLenum target, GLintptr offset, napi_value buffer, const BufferExt& ext);
204 
205     napi_value PixelStorei(napi_env env, GLenum pname, GLint param);
206 
207     // Vertex Attrib
208     napi_value VertexAttribPointer(napi_env env, const VertexAttribArg& vertexInfo);
209     napi_value EnableVertexAttribArray(napi_env env, int64_t index);
210     napi_value DisableVertexAttribArray(napi_env env, int64_t index);
211     napi_value GetVertexAttribOffset(napi_env env, GLuint index, GLenum pname);
212     napi_value VertexAttribfv(napi_env env, GLuint index, int32_t count, napi_value dataObj);
213     napi_value VertexAttribf(napi_env env, GLuint index, int32_t count, GLfloat* data);
214     napi_value GetAttribLocation(napi_env env, napi_value object, const std::string& name);
215     napi_value GetVertexAttrib(napi_env env, GLenum pname, GLuint index, VertexAttribInfo* info);
216     napi_value GetVertexAttrib(napi_env env, GLenum pname, GLuint index);
217     napi_value IsEnabled(napi_env env, GLenum cap);
218     napi_value Disable(napi_env env, GLenum cap);
219     napi_value Enable(napi_env env, GLenum cap);
220 
221     napi_value BindAttribLocation(napi_env env, napi_value program, GLuint index, const std::string& name);
222 
223     napi_value GenerateMipmap(napi_env env, GLenum target);
224 
225     napi_value UniformF(napi_env env, napi_value location, uint32_t count, const GLfloat* data);
226     napi_value UniformI(napi_env env, napi_value location, uint32_t count, const GLint* data);
227     napi_value UniformUi(napi_env env, napi_value locationObj, uint32_t count, const GLuint* data);
228 
229     napi_value UniformUiv(napi_env env, napi_value locationObj, napi_value data, const UniformExtInfo* info);
230     napi_value UniformFv(napi_env env, napi_value locationObj, napi_value data, const UniformExtInfo* info);
231     napi_value UniformIv(napi_env env, napi_value locationObj, napi_value data, const UniformExtInfo* info);
232     napi_value UniformMatrixFv(
233         napi_env env, napi_value locationObj, napi_value data, GLboolean transpose, const UniformExtInfo* info);
234 
235     napi_value StencilMaskSeparate(napi_env env, GLenum face, GLuint mask);
236     napi_value StencilMask(napi_env env, GLuint mask);
237     napi_value StencilFunc(napi_env env, GLenum func, GLint ref, GLuint mask);
238     napi_value StencilFuncSeparate(napi_env env, GLenum face, GLenum func, GLint ref, GLuint mask);
239     napi_value DepthMask(napi_env env, bool flag);
240 
241     napi_value ClearColor(napi_env env, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
242     napi_value Clear(napi_env env, GLbitfield mask);
243     napi_value ColorMask(napi_env env, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
244     napi_value ClearDepth(napi_env env, GLclampf depth);
245     napi_value ClearStencil(napi_env env, GLint s);
246     napi_value GetError(napi_env env);
247 
GetMaxVertexAttribs()248     GLuint GetMaxVertexAttribs()
249     {
250         return maxVertexAttribs_;
251     }
252 
253     GLint GetMaxColorAttachments();
254 
255     // virtual
256     virtual napi_value GetTexParameter(napi_env env, GLenum target, GLenum pname);
257     virtual napi_value GetFrameBufferAttachmentParameter(napi_env env, GLenum target, GLenum attachment, GLenum pname);
258     virtual napi_value GetParameter(napi_env env, GLenum pname);
DoObjectDelete(int32_t type,WebGLObject * obj)259     virtual void DoObjectDelete(int32_t type, WebGLObject *obj) {}
260 
261     // object mananger
262     template<class T>
263     bool AddObject(napi_env env, uint64_t key, napi_value obj);
264     template<class T>
265     napi_value GetNapiValue(napi_env env, uint64_t key);
266     template<class T>
267     napi_value GetObject(napi_env env, uint64_t key);
268     template<class T>
269     void DeleteObject(napi_env env, uint64_t key);
270     template<class T>
271     T* GetObjectInstance(napi_env env, uint64_t id);
272     WebGLBuffer* GetValidBuffer(napi_env env, napi_value object);
273     WebGLFramebuffer* GetValidFrameBuffer(napi_env env, napi_value object);
274     WebGLRenderbuffer* GetValidRenderBuffer(napi_env env, napi_value object);
275     bool CheckGLenum(GLenum type, const std::vector<GLenum>& glSupport, const std::vector<GLenum>& g2Support);
276 protected:
277     VertexAttribInfo* GetVertexAttribInfo(GLint index);
278     // private interface
279     WebGLTexture* GetBoundTexture(napi_env env, GLenum target, bool cubeMapExt);
280     WebGLFramebuffer* GetBoundFrameBuffer(napi_env env, GLenum target);
281     WebGLRenderbuffer* GetBoundRenderBuffer(napi_env env, GLenum target);
282     WebGLBuffer* GetBoundBuffer(napi_env env, GLenum target);
283     WebGLRenderbuffer* CheckRenderBufferStorage(napi_env env, const TexStorageArg& arg);
284 
285     void TexImage2D_(const TexImageArg& imgArg, WebGLTexture* texture, const void* pixels, bool);
286     void TexSubImage2D_(const TexSubImage2DArg& imgArg, WebGLTexture* texture, const void* pixels, bool);
287     napi_value BufferData_(napi_env env, GLenum target, GLsizeiptr size, GLenum usage, const uint8_t* bufferData);
288 
289     // check
290     bool CheckInList(GLenum type, const std::vector<GLenum>& glSupport);
291     bool CheckBufferTarget(napi_env env, GLenum target, uint32_t& index);
292     bool CheckFrameBufferTarget(napi_env env, GLenum target, uint32_t& index);
293     bool CheckRenderBufferTarget(napi_env env, GLenum target, uint32_t& index);
294     bool CheckTextureTarget(napi_env env, GLenum target, uint32_t& index);
295     bool CheckShaderType(napi_env env, GLenum type, uint32_t& index);
296     bool CheckInternalFormat(napi_env env, GLenum internalFormat);
297     bool CheckBufferDataUsage(napi_env env, GLenum usage);
298     bool CheckDrawMode(napi_env env, GLenum mode);
299     bool CheckAttachment(napi_env env, GLenum attachment);
300     bool CheckTexture2DTarget(napi_env env, GLenum target);
301     bool CheckCap(napi_env env, GLenum cap);
302     bool CheckPixelsFormat(napi_env env, GLenum format);
303     bool CheckPixelsType(napi_env env, GLenum type);
304     bool CheckReadBufferMode(GLenum mode);
305     bool CheckCompressedTexSubDimensions(const TexSubImage2DArg& imgArg, WebGLTexture* texture);
306     bool CheckTexImageInternalFormat(napi_env env, int32_t func, GLenum internalFormat);
307     bool CheckTexInternalFormatColorBufferCombination(GLenum texInternalFormat, GLenum colorBufferFormat);
308     bool CheckStencil(napi_env env);
309     bool CheckLocationName(const std::string& name);
310     bool CheckProgramLinkStatus(WebGLProgram* program);
311     bool CheckCompressedTexSubImage2D(napi_env env, const TexSubImage2DArg& imgArg, size_t imageSize);
312 
313     GLenum GetError_();
314     GLenum CheckTextureFormatAndType(napi_env env, GLenum internalFormat, GLenum format, GLenum type, GLint level);
315     GLenum CheckFrameBufferBoundComplete(napi_env env);
316     GLenum CheckTextureLevel(GLenum target, GLint level);
317     GLenum CheckTexImage(napi_env env, const TexImageArg& imgArg, WebGLTexture* texture);
318     GLenum CheckTexSubImage2D(napi_env env, const TexSubImage2DArg& textureInfo, WebGLTexture* texture);
319     GLenum CheckCompressedTexImage2D(napi_env env, const TexImageArg& textureInfo, size_t imageSize);
320     GLenum CheckTexFuncDimensions(const TexImageArg& textureInfo);
321     GLenum CheckCompressedTexDimensions(const TexImageArg& textureInfo);
322     GLenum CheckCompressedTexData(const TexImageArg& imgArg, size_t dataLen);
323     GLenum CheckDrawElements(napi_env env, GLenum mode, GLsizei count, GLenum type, int64_t offset);
324     GLenum CheckDrawArrays(napi_env env, GLenum mode, GLint first, GLsizei count);
325     GLenum CheckVertexAttribPointer(napi_env env, const VertexAttribArg& vertexInfo);
326     GLenum CheckCopyTexSubImage(napi_env env, const CopyTexSubImageArg& imgArg);
327     GLenum CheckTextureDataBuffer(const TexImageArg& info, const WebGLReadBufferArg *bufferData);
328     GLenum GetBoundFrameBufferColorFormat(napi_env env);
329     GLenum CheckReadBufferAndGetInfo(napi_env env, GLuint* frameBufferId, GLenum* format, GLenum* type);
330     GLenum CheckReadPixelsArg(napi_env env, const PixelsArg& arg, uint64_t bufferSize);
331 
332     template<class T>
333     GLenum CheckTexParameter(napi_env env, GLenum target, GLenum pname, T param, bool isFloat);
334 
335     bool GetReadBufferFormatAndType(napi_env env, const WebGLFramebuffer* frameBuffer, GLenum* format, GLenum* type);
336     const UniformTypeMap* GetUniformTypeMap(GLenum type);
337     GLenum GetUniformType(napi_env env, GLuint programId, GLint locationId);
338 
339     template <class T>
340     napi_value GetObjectParameter(napi_env env, GLenum pname);
341     template <class T>
342     napi_value GetIntegerVectorParameter(napi_env env, GLenum pname, GLuint count, BufferDataType dstDataType);
343     napi_value GetFloatVectorParameter(napi_env env, GLenum pname, GLuint count, BufferDataType dstDataType);
344     napi_value GetBoolVectorParameter(napi_env env, GLenum pname, GLuint count, BufferDataType dstDataType);
345     const std::vector<GLenum> &GetTexImageInternalFormat();
346     const std::vector<GLenum>& GetExtentionAstcTexImageInternal();
347     const std::vector<GLenum>& GetIntegerParaName();
348     const std::vector<GLenum>& GetBoolParaName();
349 
350     int32_t version_ = WEBGL_1_0;
351     // error process
352     GLenum lastError_ = 0;
353 
354     // for texture
355     GLint maxColorAttachments_ {};
356     GLint maxTextureImageUnits_ = 0;
357     GLint maxTextureSize_ = 0;
358     GLint maxCubeMapTextureSize_ = 0;
359     GLint maxRenderBufferSize_ = 0;
360     uint32_t activeTextureIndex_ = 0;
361     std::vector<uint32_t> boundTexture_[BoundTextureType::TEXTURE_MAX] = {};
362 
363     // for buffer 0: ARRAY_BUFFER 1:ELEMENT_ARRAY_BUFFER
364     GLuint boundBufferIds_[BoundBufferType::BUFFER_MAX] = { 0 };
365     GLuint boundFrameBufferIds_[BoundFrameBufferType::FRAMEBUFFER_MAX] = { 0 };
366     GLuint boundRenderBufferIds_[BoundRenderBufferType::RENDERBUFFER_MAX] = { 0 };
367 
368     GLuint currentProgramId_ { 0 };
369     GLuint maxVertexAttribs_ { 0 };
370     std::vector<VertexAttribInfo> arrayVertexAttribs_ {};
371 
372     bool unpackFlipY_ { false };
373     bool unpackPremultiplyAlpha_ { false };
374     GLenum unpackColorspaceConversion_ { 0 };
375     GLint packAlignment_ { 4 };
376     GLint unpackAlignment_ { 4 };
377     GLenum defaultReadBufferMode_ { GL_BACK };
378 
379     bool stencilEnabled_ { false };
380     bool scissorEnabled_ { false };
381     // for FRONT and BACK
382     GLuint stencilMask_[2] { 0 };
383     GLint stencilFuncRef_[2] { 0 };
384     GLuint stencilFuncMask_[2] { 0 };
385 
386     // for color
387     GLfloat clearColor_[4] { 0 };
388     GLboolean colorMask_[4] { false };
389     GLint clearStencil_ { 0 };
390     GLfloat clearDepth_ { 0 };
391     bool depthMask_ { false };
392 
393     std::map<uint64_t, napi_ref> objects_[WebGLObject::WEBGL_OBJECT_MAX] {};
394     WebGLRenderingContextBasicBase *webGLRenderingContext_ { nullptr };
395 private:
396     WebGLRenderingContextBaseImpl(const WebGLRenderingContextBaseImpl&) = delete;
397     WebGLRenderingContextBaseImpl& operator=(const WebGLRenderingContextBaseImpl&) = delete;
398     void HandleUniformMatrixInfo(
399         GLboolean transpose, const UniformExtInfo* info, GLint location, GLsizei count, GLfloat* srcData);
400     napi_value HandleFrameBufferAttachmentPname(
401         napi_env env, GLenum target, GLenum attachment, GLenum pname, GLint type);
402 #define SET_ERROR(error)                                \
403     do {                                                \
404         LOGE("WebGL set error code %{public}u", error); \
405         SetError(error);                                \
406     } while (0)
407 
408 #define SET_ERROR_WITH_LOG(error, info, ...)                                \
409     do {                                                                    \
410         LOGE("WebGL set error code %{public}u" info, error, ##__VA_ARGS__); \
411         SetError(error);                                                    \
412     } while (0)
413 };
414 
415 template<class T>
AddObject(napi_env env,uint64_t key,napi_value obj)416 bool WebGLRenderingContextBaseImpl::AddObject(napi_env env, uint64_t key, napi_value obj)
417 {
418     if (T::objectType < 0 || T::objectType > WebGLObject::WEBGL_OBJECT_MAX) {
419         return false;
420     }
421     if (objects_[T::objectType].find(key) != objects_[T::objectType].end()) {
422         LOGE("AddObject exit %{public}u %{public}" PRIu64, T::objectType, key);
423         return false;
424     }
425     napi_ref ref;
426     napi_status status = napi_create_reference(env, obj, 1, &ref);
427     if (status != napi_ok) {
428         LOGE("AddObject %{public}" PRIu64 " status %{public}u", key, status);
429         return false;
430     }
431     LOGD("AddObject %{public}u %{public}p %{public}" PRIu64, T::objectType, obj, key);
432     objects_[T::objectType].insert({ key, ref });
433     return true;
434 }
435 
436 template<class T>
GetNapiValue(napi_env env,uint64_t key)437 napi_value WebGLRenderingContextBaseImpl::GetNapiValue(napi_env env, uint64_t key)
438 {
439     if (T::objectType < 0 || T::objectType > WebGLObject::WEBGL_OBJECT_MAX) {
440         return nullptr;
441     }
442     auto it = objects_[T::objectType].find(key);
443     if (it == objects_[T::objectType].end()) {
444         LOGD("GetObject %{public}u %{public}" PRIu64, T::objectType, key);
445         return nullptr;
446     }
447     napi_value obj;
448     napi_status status = napi_get_reference_value(env, it->second, &obj);
449     LOGD("GetNapiValue %{public}u %{public}p %{public}" PRIu64, T::objectType, obj, key);
450     if (status != napi_ok) {
451         return nullptr;
452     }
453     return obj;
454 }
455 
456 template<class T>
GetObject(napi_env env,uint64_t key)457 napi_value WebGLRenderingContextBaseImpl::GetObject(napi_env env, uint64_t key)
458 {
459     napi_value retNull = nullptr;
460     napi_get_null(env, &retNull);
461     napi_value obj = GetNapiValue<T>(env, key);
462     if (obj == nullptr) {
463         return retNull;
464     }
465     return obj;
466 }
467 
468 template<class T>
DeleteObject(napi_env env,uint64_t key)469 void WebGLRenderingContextBaseImpl::DeleteObject(napi_env env, uint64_t key)
470 {
471     if (T::objectType < 0 || T::objectType > WebGLObject::WEBGL_OBJECT_MAX) {
472         return;
473     }
474     auto it = objects_[T::objectType].find(key);
475     if (it == objects_[T::objectType].end()) {
476         LOGE("WebGL can not delete %{public}u %{public}" PRIu64, T::objectType, key);
477         return;
478     }
479     napi_value obj;
480     napi_status status = napi_get_reference_value(env, it->second, &obj);
481     auto ref = it->second;
482     objects_[T::objectType].erase(it);
483     napi_delete_reference(env, ref);
484     LOGD("DeleteObject %{public}u %{public}" PRIu64 " status %{public}u", T::objectType, key, status);
485 }
486 
487 template<class T>
GetObjectInstance(napi_env env,uint64_t id)488 T* WebGLRenderingContextBaseImpl::GetObjectInstance(napi_env env, uint64_t id)
489 {
490     napi_value tmp = GetNapiValue<T>(env, id);
491     return NClass::GetEntityOf<T>(env, tmp);
492 }
493 } // namespace Impl
494 } // namespace Rosen
495 } // namespace OHOS
496 #endif // ROSENRENDER_ROSEN_WEBGL_RENDERING_CONTEXT_BASE_IMPL
497