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 WEBGL_ARG_H 17 #define WEBGL_ARG_H 18 19 #include <climits> 20 #include "securec.h" 21 #include "napi/n_class.h" 22 #include "napi/n_func_arg.h" 23 #include "napi/n_val.h" 24 #include "util/log.h" 25 #include "image_source.h" 26 27 namespace OHOS { 28 namespace Rosen { 29 using BufferDataType = enum { 30 BUFFER_DATA_INT_8 = napi_int8_array, 31 BUFFER_DATA_UINT_8 = napi_uint8_array, 32 BUFFER_DATA_UINT_8_CLAMPED = napi_uint8_clamped_array, 33 BUFFER_DATA_INT_16 = napi_int16_array, 34 BUFFER_DATA_UINT_16 = napi_uint16_array, 35 BUFFER_DATA_INT_32 = napi_int32_array, 36 BUFFER_DATA_UINT_32 = napi_uint32_array, 37 BUFFER_DATA_FLOAT_32 = napi_float32_array, 38 BUFFER_DATA_FLOAT_64 = napi_float64_array, 39 BUFFER_DATA_BIGINT_64 = napi_bigint64_array, 40 BUFFER_DATA_BIGUINT_64 = napi_biguint64_array, 41 BUFFER_DATA_BOOLEAN, 42 BUFFER_DATA_GLENUM, 43 BUFFER_DATA_INVALID 44 }; 45 46 using BufferType = enum { 47 BUFFER_DATA_VIEW, 48 BUFFER_ARRAY_BUFFER, 49 BUFFER_TYPED_ARRAY, 50 BUFFER_ARRAY, 51 }; 52 53 using WebGLArgType = enum : int { 54 ARG_FLOAT, 55 ARG_UINT, 56 ARG_INT, 57 ARG_ENUM, 58 ARG_INTPTR, 59 ARG_SIZE, 60 ARG_BOOL, 61 ARG_SIZEPTR, 62 }; 63 64 union WebGLArgValue { 65 GLboolean glBool; 66 GLfloat glFloat; 67 GLuint glUint; 68 GLint glInt; 69 GLenum glEnum; 70 GLintptr glIntptr; 71 GLsizei glSizei; 72 GLsizeiptr glSizeptr; 73 }; 74 75 struct WebGLArgInfo { 76 WebGLArgType argType; 77 uint32_t argIndex; 78 const char* argName; WebGLArgInfoWebGLArgInfo79 WebGLArgInfo(uint32_t index, WebGLArgType type, const char* name) 80 : argType(type), argIndex(index), argName(name) {} ~WebGLArgInfoWebGLArgInfo81 ~WebGLArgInfo() {} 82 }; 83 84 struct WebGLImageOption { 85 GLenum format; 86 GLenum type; 87 GLsizei width; 88 GLsizei height; 89 GLsizei depth; 90 WebGLImageOptionWebGLImageOption91 WebGLImageOption() : format(0), type(0), width(0), height(0) {} WebGLImageOptionWebGLImageOption92 WebGLImageOption(GLenum format, GLenum type, GLsizei width, GLsizei height) 93 { 94 this->format = format; 95 this->type = type; 96 this->width = width; 97 this->height = height; 98 this->depth = 1; 99 } WebGLImageOptionWebGLImageOption100 WebGLImageOption(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth) 101 { 102 this->format = format; 103 this->type = type; 104 this->width = width; 105 this->height = height; 106 this->depth = depth; 107 } AssignWebGLImageOption108 void Assign(const WebGLImageOption& opt) 109 { 110 this->format = opt.format; 111 this->type = opt.type; 112 this->width = opt.width; 113 this->height = opt.height; 114 this->depth = opt.depth; 115 } 116 void Dump(); 117 }; 118 119 using ImageDecodeFunc = enum { 120 DECODE_RGBA_UBYTE, 121 DECODE_RGB_UBYTE, 122 DECODE_RGBA_USHORT_4444, 123 DECODE_RGBA_USHORT_5551, 124 DECODE_RGB_USHORT_565, 125 DECODE_LUMINANCE_ALPHA_UBYTE, 126 DECODE_LUMINANCE_UBYTE, 127 DECODE_ALPHA_UBYTE 128 }; 129 130 struct WebGLFormatMap { 131 GLenum format; 132 GLenum type; 133 uint8_t channels; 134 uint8_t bytesPrePixel; 135 uint16_t decodeFunc; 136 BufferDataType dataType; WebGLFormatMapWebGLFormatMap137 WebGLFormatMap(GLenum format, GLenum type, uint8_t channels, uint8_t bytesPrePixel, BufferDataType dataType, 138 uint16_t decodeFunc) 139 { 140 this->format = format; 141 this->type = type; 142 this->channels = channels; 143 this->bytesPrePixel = bytesPrePixel; 144 this->dataType = dataType; 145 this->decodeFunc = decodeFunc; 146 } 147 }; 148 149 union ColorParam { 150 #if BIG_ENDIANNESS 151 struct { 152 uint8_t alpha; 153 uint8_t red; 154 uint8_t green; 155 uint8_t blue; 156 } argb; 157 #else 158 struct { 159 uint8_t blue; 160 uint8_t green; 161 uint8_t red; 162 uint8_t alpha; 163 } argb; 164 #endif 165 uint32_t value; 166 }; 167 168 union ColorParam_4_4_4_4 { 169 #if BIG_ENDIANNESS 170 struct { 171 uint8_t alpha : 4; 172 uint8_t blue : 4; 173 uint8_t green : 4; 174 uint8_t red : 4; 175 } rgba; 176 #else 177 struct { 178 uint8_t red : 4; 179 uint8_t green : 4; 180 uint8_t blue : 4; 181 uint8_t alpha : 4; 182 } rgba; 183 #endif 184 uint16_t value; 185 }; 186 187 union ColorParam_5_5_5_1 { 188 #if BIG_ENDIANNESS 189 struct { 190 uint8_t alpha : 1; 191 uint8_t blue : 5; 192 uint8_t green : 5; 193 uint8_t red : 5; 194 } rgba; 195 #else 196 struct { 197 uint8_t red : 5; 198 uint8_t green : 5; 199 uint8_t blue : 5; 200 uint8_t alpha : 1; 201 } rgba; 202 #endif 203 uint16_t value; 204 }; 205 206 union ColorParam_5_6_5 { 207 #if BIG_ENDIANNESS 208 struct { 209 uint8_t blue : 5; 210 uint8_t green : 6; 211 uint8_t red : 5; 212 } rgb; 213 #else 214 struct { 215 uint8_t red : 5; 216 uint8_t green : 6; 217 uint8_t blue : 5; 218 } rgb; 219 #endif 220 uint16_t value; 221 }; 222 223 struct TexImageArg { 224 int func; 225 GLenum target; 226 GLint level; 227 GLenum internalFormat; 228 GLenum format; 229 GLenum type; 230 GLsizei width; 231 GLsizei height; 232 GLsizei border; 233 GLsizei depth; 234 TexImageArgTexImageArg235 TexImageArg() 236 : func(0), target(0), level(0), internalFormat(0), 237 format(0), type(0), width(0), height(0), border(0), depth(0) {} 238 TexImageArgTexImageArg239 TexImageArg(const TexImageArg& arg) 240 { 241 func = arg.func; 242 target = arg.target; 243 level = arg.level; 244 internalFormat = arg.internalFormat; 245 format = arg.format; 246 type = arg.type; 247 width = arg.width; 248 height = arg.height; 249 border = arg.border; 250 depth = arg.depth; 251 } 252 TexImageArgTexImageArg253 TexImageArg( 254 GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum type) 255 { 256 this->target = target; 257 this->level = level; 258 this->internalFormat = internalFormat; 259 this->type = type; 260 this->width = width; 261 this->height = height; 262 this->depth = depth; 263 this->border = 0; 264 this->func = 0; 265 this->format = 0; 266 } 267 virtual void Dump(const std::string& info) const; 268 }; 269 270 struct TexStorageArg { 271 int func; 272 GLenum target; 273 GLsizei levels; 274 GLenum internalFormat; 275 GLsizei width; 276 GLsizei height; 277 GLsizei depth; TexStorageArgTexStorageArg278 TexStorageArg() : func(0), target(0), levels(0), internalFormat(0), width(0), height(0), depth(0) {} TexStorageArgTexStorageArg279 TexStorageArg(const TexStorageArg& arg) 280 { 281 func = arg.func; 282 target = arg.target; 283 levels = arg.levels; 284 internalFormat = arg.internalFormat; 285 width = arg.width; 286 height = arg.height; 287 depth = arg.depth; 288 } 289 void Dump(const std::string& info) const; 290 }; 291 292 struct TexSubImage2DArg : public TexImageArg { 293 GLint xOffset; 294 GLint yOffset; TexSubImage2DArgTexSubImage2DArg295 TexSubImage2DArg() : TexImageArg(), xOffset(0), yOffset{0} {} TexSubImage2DArgTexSubImage2DArg296 TexSubImage2DArg(const TexSubImage2DArg& arg) : TexImageArg(arg) 297 { 298 xOffset = arg.xOffset; 299 yOffset = arg.yOffset; 300 } 301 void Dump(const std::string& info) const override; 302 }; 303 304 struct TexSubImage3DArg : public TexSubImage2DArg { 305 GLint zOffset; TexSubImage3DArgTexSubImage3DArg306 TexSubImage3DArg() : TexSubImage2DArg(), zOffset(0) {} TexSubImage3DArgTexSubImage3DArg307 TexSubImage3DArg(const TexSubImage3DArg& arg) : TexSubImage2DArg(arg) 308 { 309 zOffset = arg.zOffset; 310 } 311 void Dump(const std::string& info) const override; 312 }; 313 314 struct CopyTexImage2DArg : public TexImageArg { 315 GLint x; 316 GLint y; CopyTexImage2DArgCopyTexImage2DArg317 CopyTexImage2DArg() : TexImageArg(), x(0), y{0} {} 318 }; 319 320 struct CopyTexSubImageArg : public TexImageArg { 321 GLint xOffset; 322 GLint yOffset; 323 GLint x; 324 GLint y; CopyTexSubImageArgCopyTexSubImageArg325 CopyTexSubImageArg() : TexImageArg(), xOffset(0), yOffset{0}, x(0), y(0) {} 326 }; 327 328 struct CopyTexSubImage3DArg : public CopyTexSubImageArg { 329 GLint zOffset; CopyTexSubImage3DArgCopyTexSubImage3DArg330 CopyTexSubImage3DArg() : CopyTexSubImageArg(), zOffset(0) {} 331 }; 332 333 struct TextureLayerArg { 334 GLint level; 335 GLint layer; 336 }; 337 338 struct BufferBaseArg { 339 GLenum target; 340 GLuint index; 341 }; 342 343 struct VertexAttribArg { 344 GLuint index; 345 GLint size; 346 GLenum type; 347 GLboolean normalized; 348 GLsizei stride; 349 GLintptr offset; 350 void Dump(const std::string& info) const; 351 }; 352 353 struct PixelsArg { 354 GLint x; 355 GLint y; 356 GLsizei width; 357 GLsizei height; 358 GLenum format; 359 GLenum type; 360 void Dump(const std::string& info) const; 361 }; 362 363 struct UniformExtInfo { 364 GLuint dimension; 365 GLuint elemCount; 366 GLuint srcOffset; 367 GLuint srcLength; UniformExtInfoUniformExtInfo368 UniformExtInfo(GLuint dimension) : dimension(dimension), elemCount(dimension), srcOffset(0), srcLength(0) {} UniformExtInfoUniformExtInfo369 UniformExtInfo(GLuint dimension, GLuint real) 370 : dimension(dimension), elemCount(real), srcOffset(0), srcLength(0) {} 371 bool GetUniformExtInfo(napi_env env, const NFuncArg& funcArg, int32_t start); 372 }; 373 374 struct UniformTypeMap { 375 GLenum type; 376 GLenum baseType; 377 GLsizei length; 378 BufferDataType srcType; 379 BufferDataType dstType; 380 }; 381 382 // getVertexAttrib 383 struct VertexAttribDesc { 384 bool enabled; 385 bool normalized; 386 // VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 387 GLuint boundBufferId; 388 // VERTEX_ATTRIB_ARRAY_NORMALIZED 389 GLsizei bytesPerElement; 390 // VERTEX_ATTRIB_ARRAY_SIZE 391 GLint size; 392 // VERTEX_ATTRIB_ARRAY_TYPE 393 GLenum type; 394 // VERTEX_ATTRIB_ARRAY_STRIDE 395 GLsizei stride; 396 GLsizei originalStride; 397 GLintptr offset; 398 // by this func VertexAttribDivisor 399 GLuint divisor; 400 }; 401 402 struct VertexAttribInfo { 403 BufferDataType type; 404 }; 405 406 struct BufferPosition { 407 GLint x; 408 GLint y; 409 }; 410 411 struct BufferSize { 412 GLsizei width; 413 GLsizei height; 414 }; 415 416 struct DrawElementArg { 417 GLenum mode; 418 GLsizei count; 419 GLenum type; 420 int64_t offset; 421 }; 422 423 struct BufferExt { 424 GLuint offset; 425 GLuint length; BufferExtBufferExt426 BufferExt() : offset(0), length(0) {} 427 bool GetBufferExt(napi_env env, napi_value offsetArg, napi_value lenArg); 428 }; 429 430 class WebGLArg { 431 public: 432 static const GLsizei MATRIX_2X2_REQUIRE_MIN_SIZE = 4; 433 static const GLsizei MATRIX_3X3_REQUIRE_MIN_SIZE = 9; 434 static const GLsizei MATRIX_4X4_REQUIRE_MIN_SIZE = 16; 435 436 static const GLsizei MATRIX_3X2_REQUIRE_MIN_SIZE = 100 + 6; 437 static const GLsizei MATRIX_4X2_REQUIRE_MIN_SIZE = 100 + 8; 438 static const GLsizei MATRIX_2X3_REQUIRE_MIN_SIZE = 200 + 6; 439 static const GLsizei MATRIX_4X3_REQUIRE_MIN_SIZE = 200 + 12; 440 static const GLsizei MATRIX_2X4_REQUIRE_MIN_SIZE = 300 + 8; 441 static const GLsizei MATRIX_3X4_REQUIRE_MIN_SIZE = 300 + 12; 442 443 static const GLsizei UNIFORM_1V_REQUIRE_MIN_SIZE = 1; 444 static const GLsizei UNIFORM_2V_REQUIRE_MIN_SIZE = 2; 445 static const GLsizei UNIFORM_3V_REQUIRE_MIN_SIZE = 3; 446 static const GLsizei UNIFORM_4V_REQUIRE_MIN_SIZE = 4; 447 WebGLArg(napi_env env,napi_value thisVar)448 WebGLArg(napi_env env, napi_value thisVar) : env_(env) {} ~WebGLArg()449 virtual ~WebGLArg() {} 450 451 static bool GetStringList(napi_env env, napi_value array, std::vector<char *>& list); 452 static void FreeStringList(std::vector<char *>& list); 453 static std::tuple<GLenum, GLintptr> ToGLintptr(napi_env env, napi_value data); 454 static uint32_t GetWebGLDataSize(GLenum type); 455 template<class T1, class T2> CheckOverflow(T1 arg1,T2 arg2)456 static bool CheckOverflow(T1 arg1, T2 arg2) 457 { 458 int64_t t = static_cast<int64_t>(arg1) + static_cast<int64_t>(arg2); 459 if (t >= std::numeric_limits<T1>::max()) { 460 return true; 461 } 462 return false; 463 } 464 465 template<class T> CheckNoneNegInt(int64_t data)466 static bool CheckNoneNegInt(int64_t data) 467 { 468 if (data < 0) { 469 return false; 470 } 471 if (data > static_cast<int64_t>(std::numeric_limits<T>::max())) { 472 return false; 473 } 474 return true; 475 } 476 477 static napi_value GetUint32Parameter(napi_env env, GLenum pname); 478 static napi_value GetInt32Parameter(napi_env env, GLenum pname); 479 static napi_value GetInt64Parameter(napi_env env, GLenum pname); 480 static napi_value GetFloatParameter(napi_env env, GLenum pname); 481 static napi_value GetBoolParameter(napi_env env, GLenum pname); 482 static bool CheckString(const std::string& str); 483 static bool CheckReservedPrefix(const std::string& name); 484 private: 485 napi_env env_; 486 bool GetWebGLArg(napi_value data, WebGLArgValue& args, const WebGLArgInfo& func); 487 WebGLArg(const WebGLArg&) = delete; 488 WebGLArg& operator=(const WebGLArg&) = delete; 489 }; 490 491 class WebGLCommBuffer { 492 public: 493 const static int32_t MAX_DUMP = 12; WebGLCommBuffer(napi_env env)494 WebGLCommBuffer(napi_env env) : env_(env) {} ~WebGLCommBuffer()495 ~WebGLCommBuffer() {} 496 497 size_t GetBufferDataSize() const; 498 void DumpBuffer(BufferDataType destDataType) const; GetBufferDataType()499 BufferDataType GetBufferDataType() const 500 { 501 return type_; 502 } GetBufferType()503 BufferType GetBufferType() const 504 { 505 return bufferType_; 506 } GetBufferLength()507 size_t GetBufferLength() const 508 { 509 return dataLen_; 510 } 511 protected: 512 WebGLCommBuffer(const WebGLCommBuffer&) = delete; 513 WebGLCommBuffer& operator=(const WebGLCommBuffer&) = delete; 514 515 template<class T> 516 void DumpDataBuffer(const char* format) const; 517 napi_env env_; 518 uint8_t* data_ = { nullptr }; 519 BufferDataType type_ { BUFFER_DATA_UINT_8 }; 520 size_t dataLen_ { 0 }; 521 BufferType bufferType_ { BUFFER_ARRAY }; 522 std::vector<uint8_t> buffer_ {}; 523 }; 524 525 class WebGLReadBufferArg : public WebGLCommBuffer { 526 public: WebGLReadBufferArg(napi_env env)527 WebGLReadBufferArg(napi_env env) : WebGLCommBuffer(env) {} ~WebGLReadBufferArg()528 ~WebGLReadBufferArg() {} 529 530 napi_status GenBufferData(napi_value data, BufferDataType destDataType = BUFFER_DATA_FLOAT_32); GetBuffer()531 uint8_t* GetBuffer() const 532 { 533 return data_; 534 } 535 private: 536 WebGLReadBufferArg(const WebGLReadBufferArg&) = delete; 537 WebGLReadBufferArg& operator=(const WebGLReadBufferArg&) = delete; 538 539 template<class srcT, class dstT> 540 napi_status GetArrayElement(napi_value data, dstT defaultValue, 541 napi_status (*getElementValue)(napi_env env, napi_value element, srcT* value)); 542 napi_status GetArrayData(napi_value data, BufferDataType destDataType); 543 }; 544 545 class WebGLWriteBufferArg : public WebGLCommBuffer { 546 public: 547 const static int32_t MAX_ALLOC_BUFFER_SIZE = 1024 * 1024; WebGLWriteBufferArg(napi_env env)548 explicit WebGLWriteBufferArg(napi_env env) : WebGLCommBuffer(env) {} ~WebGLWriteBufferArg()549 ~WebGLWriteBufferArg() 550 { 551 if (data_ != nullptr) { 552 delete[] data_; 553 } 554 } 555 AllocBuffer(uint32_t size)556 uint8_t* AllocBuffer(uint32_t size) 557 { 558 if (size > MAX_ALLOC_BUFFER_SIZE) { 559 return nullptr; 560 } 561 if (data_ != nullptr) { 562 delete[] data_; 563 data_ = nullptr; 564 } 565 dataLen_ = size; 566 data_ = new uint8_t[dataLen_]; 567 return data_; 568 } 569 570 napi_value ToExternalArray(BufferDataType dstDataType); 571 napi_value ToNormalArray(BufferDataType srcDataType, BufferDataType dstDataType); 572 573 private: 574 template<class dstT> 575 napi_value GenExternalArray(); 576 template<class srcT, class dstT> 577 napi_value GenNormalArray(napi_status (*getNApiValue)(napi_env env, dstT value, napi_value* element)); 578 579 WebGLWriteBufferArg(const WebGLWriteBufferArg&) = delete; 580 WebGLWriteBufferArg& operator=(const WebGLWriteBufferArg&) = delete; 581 }; 582 583 class WebGLImageSource { 584 public: WebGLImageSource(napi_env env,int version,bool unpackFlipY,bool unpackPremultiplyAlpha)585 WebGLImageSource(napi_env env, int version, bool unpackFlipY, bool unpackPremultiplyAlpha) 586 : webGLVersion_(version), env_(env), unpackFlipY_(unpackFlipY), 587 unpackPremultiplyAlpha_(unpackPremultiplyAlpha) {} 588 ~WebGLImageSource(); 589 GetWidth()590 GLsizei GetWidth() const 591 { 592 return imageOption_.width; 593 } GetHeight()594 GLsizei GetHeight() const 595 { 596 return imageOption_.height; 597 } GetWebGLImageOption()598 const WebGLImageOption& GetWebGLImageOption() const 599 { 600 return imageOption_; 601 } 602 603 WebGLReadBufferArg* GetWebGLReadBuffer() const; 604 GLvoid* GetImageSourceData() const; 605 GLenum GenImageSource(const WebGLImageOption& opt, napi_value pixels, GLuint srcOffset); 606 GLenum GenImageSource(const WebGLImageOption& opt, napi_value sourceImage); 607 608 static std::tuple<size_t, BufferDataType> GetBytesPrePixel(GLenum type); FromARGB(uint8_t alpha,uint8_t red,uint8_t green,uint8_t blue)609 inline static ColorParam FromARGB(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue) 610 { 611 ColorParam colorValue { 612 #if BIG_ENDIANNESS 613 .argb = { .alpha = alpha, .red = red, .green = green, .blue = blue } 614 #else 615 .argb = { .blue = blue, .green = green, .red = red, .alpha = alpha } 616 #endif 617 }; 618 return colorValue; 619 } 620 FromRGBO(uint8_t red,uint8_t green,uint8_t blue,double opacity)621 inline static ColorParam FromRGBO(uint8_t red, uint8_t green, uint8_t blue, double opacity) 622 { 623 return FromARGB(static_cast<uint8_t>(round(opacity * 0xff)) & 0xff, red, green, blue); 624 } 625 FromRGB(uint8_t red,uint8_t green,uint8_t blue)626 inline static ColorParam FromRGB(uint8_t red, uint8_t green, uint8_t blue) 627 { 628 return FromARGB(0xff, red, green, blue); 629 } 630 static const WebGLFormatMap* GetWebGLFormatMap(GLenum type, GLenum format); 631 private: 632 void DecodeData(const WebGLFormatMap* map, uint8_t* array); 633 void DecodeDataForRGB_UBYTE(const WebGLFormatMap* formatMap, uint8_t* array); 634 void DecodeDataForRGBA_USHORT_4444(const WebGLFormatMap* formatMap, uint8_t* array); 635 void DecodeDataForRGBA_USHORT_5551(const WebGLFormatMap* formatMap, uint8_t* array); 636 void DecodeDataForRGB_USHORT_565(const WebGLFormatMap* formatMap, uint8_t* array); 637 bool DecodeImageData(const WebGLFormatMap* formatMap, const WebGLReadBufferArg* bufferDataArg, GLuint srcOffset); 638 639 template<class T> 640 std::tuple<bool, T> GetObjectIntField(napi_value resultObject, const std::string& name); 641 bool HandleImageSourceData(napi_value resultData, napi_valuetype valueType); 642 643 int webGLVersion_ { 0 }; 644 napi_env env_ { nullptr }; 645 bool unpackFlipY_ { false }; 646 bool unpackPremultiplyAlpha_ { false }; 647 GLuint srcOffset_ { 0 }; 648 WebGLImageOption imageOption_ {}; 649 std::vector<uint32_t> imageData_ {}; 650 std::unique_ptr<OHOS::Media::PixelMap> pixelMap_ { nullptr }; 651 std::unique_ptr<WebGLReadBufferArg> readBuffer_ { nullptr }; 652 653 WebGLImageSource(const WebGLImageSource&) = delete; 654 WebGLImageSource& operator=(const WebGLImageSource&) = delete; 655 }; 656 } // namespace Rosen 657 } // namespace OHOS 658 #endif // WEBGL_ARG_H 659