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