@nativescript/canvas 2.0.0-webgpu.2 → 2.0.0-webgpu.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/Canvas/common.d.ts +3 -4
  2. package/Canvas/common.js +35 -125
  3. package/Canvas/common.js.map +1 -1
  4. package/Canvas/index.android.d.ts +0 -1
  5. package/Canvas/index.android.js +45 -38
  6. package/Canvas/index.android.js.map +1 -1
  7. package/Canvas/index.d.ts +11 -3
  8. package/Canvas/index.ios.js +49 -40
  9. package/Canvas/index.ios.js.map +1 -1
  10. package/Canvas/utils.d.ts +3 -0
  11. package/Canvas/utils.js +85 -0
  12. package/Canvas/utils.js.map +1 -0
  13. package/Canvas2D/CanvasRenderingContext2D/index.d.ts +1 -0
  14. package/Canvas2D/CanvasRenderingContext2D/index.js +1 -0
  15. package/Canvas2D/CanvasRenderingContext2D/index.js.map +1 -1
  16. package/Dom/Group.d.ts +1 -2
  17. package/Dom/Group.js.map +1 -1
  18. package/Dom/Image.js +0 -1
  19. package/Dom/Image.js.map +1 -1
  20. package/Dom/Paint.d.ts +1 -1
  21. package/Dom/shapes/Path.d.ts +1 -1
  22. package/ImageAsset/index.js +77 -33
  23. package/ImageAsset/index.js.map +1 -1
  24. package/ImageBitmap/index.js +107 -20
  25. package/ImageBitmap/index.js.map +1 -1
  26. package/README.md +2 -4
  27. package/WebGL/WebGLRenderingContext/index.js +73 -31
  28. package/WebGL/WebGLRenderingContext/index.js.map +1 -1
  29. package/WebGL2/WebGL2RenderingContext/index.js +4 -4
  30. package/WebGL2/WebGL2RenderingContext/index.js.map +1 -1
  31. package/WebGPU/GPU.js +4 -3
  32. package/WebGPU/GPU.js.map +1 -1
  33. package/WebGPU/GPUAdapter.d.ts +6 -3
  34. package/WebGPU/GPUAdapter.js +31 -0
  35. package/WebGPU/GPUAdapter.js.map +1 -1
  36. package/WebGPU/GPUBindGroup.d.ts +1 -0
  37. package/WebGPU/GPUBindGroup.js +3 -0
  38. package/WebGPU/GPUBindGroup.js.map +1 -1
  39. package/WebGPU/GPUBindGroupLayout.d.ts +1 -0
  40. package/WebGPU/GPUBindGroupLayout.js +3 -0
  41. package/WebGPU/GPUBindGroupLayout.js.map +1 -1
  42. package/WebGPU/GPUBuffer.js +10 -2
  43. package/WebGPU/GPUBuffer.js.map +1 -1
  44. package/WebGPU/GPUCanvasContext.d.ts +3 -2
  45. package/WebGPU/GPUCanvasContext.js +52 -10
  46. package/WebGPU/GPUCanvasContext.js.map +1 -1
  47. package/WebGPU/GPUCommandBuffer.d.ts +1 -0
  48. package/WebGPU/GPUCommandBuffer.js +3 -0
  49. package/WebGPU/GPUCommandBuffer.js.map +1 -1
  50. package/WebGPU/GPUCommandEncoder.d.ts +3 -9
  51. package/WebGPU/GPUCommandEncoder.js +94 -41
  52. package/WebGPU/GPUCommandEncoder.js.map +1 -1
  53. package/WebGPU/GPUComputePassEncoder.d.ts +1 -0
  54. package/WebGPU/GPUComputePassEncoder.js +3 -0
  55. package/WebGPU/GPUComputePassEncoder.js.map +1 -1
  56. package/WebGPU/GPUComputePipeline.d.ts +1 -0
  57. package/WebGPU/GPUComputePipeline.js +3 -0
  58. package/WebGPU/GPUComputePipeline.js.map +1 -1
  59. package/WebGPU/GPUDevice.d.ts +17 -79
  60. package/WebGPU/GPUDevice.js +72 -91
  61. package/WebGPU/GPUDevice.js.map +1 -1
  62. package/WebGPU/GPUExternalTexture.d.ts +1 -0
  63. package/WebGPU/GPUExternalTexture.js +3 -0
  64. package/WebGPU/GPUExternalTexture.js.map +1 -1
  65. package/WebGPU/GPUPipelineLayout.d.ts +1 -0
  66. package/WebGPU/GPUPipelineLayout.js +3 -0
  67. package/WebGPU/GPUPipelineLayout.js.map +1 -1
  68. package/WebGPU/GPUQuerySet.d.ts +1 -0
  69. package/WebGPU/GPUQuerySet.js +3 -0
  70. package/WebGPU/GPUQuerySet.js.map +1 -1
  71. package/WebGPU/GPUQueue.d.ts +1 -0
  72. package/WebGPU/GPUQueue.js +45 -7
  73. package/WebGPU/GPUQueue.js.map +1 -1
  74. package/WebGPU/GPURenderBundle.d.ts +1 -0
  75. package/WebGPU/GPURenderBundle.js +3 -0
  76. package/WebGPU/GPURenderBundle.js.map +1 -1
  77. package/WebGPU/GPURenderBundleEncoder.d.ts +4 -2
  78. package/WebGPU/GPURenderBundleEncoder.js +7 -3
  79. package/WebGPU/GPURenderBundleEncoder.js.map +1 -1
  80. package/WebGPU/GPURenderPassEncoder.d.ts +2 -1
  81. package/WebGPU/GPURenderPassEncoder.js +5 -2
  82. package/WebGPU/GPURenderPassEncoder.js.map +1 -1
  83. package/WebGPU/GPURenderPipeline.d.ts +1 -0
  84. package/WebGPU/GPURenderPipeline.js +3 -0
  85. package/WebGPU/GPURenderPipeline.js.map +1 -1
  86. package/WebGPU/GPUSampler.d.ts +1 -0
  87. package/WebGPU/GPUSampler.js +3 -0
  88. package/WebGPU/GPUSampler.js.map +1 -1
  89. package/WebGPU/GPUShaderModule.d.ts +1 -1
  90. package/WebGPU/GPUShaderModule.js +2 -2
  91. package/WebGPU/GPUShaderModule.js.map +1 -1
  92. package/WebGPU/GPUTexture.d.ts +1 -0
  93. package/WebGPU/GPUTexture.js +3 -0
  94. package/WebGPU/GPUTexture.js.map +1 -1
  95. package/WebGPU/GPUTextureView.d.ts +1 -0
  96. package/WebGPU/GPUTextureView.js +3 -0
  97. package/WebGPU/GPUTextureView.js.map +1 -1
  98. package/WebGPU/Interfaces.d.ts +95 -4
  99. package/WebGPU/Types.d.ts +9 -1
  100. package/WebGPU/Utils.d.ts +6 -0
  101. package/WebGPU/Utils.js +221 -0
  102. package/WebGPU/Utils.js.map +1 -1
  103. package/angular/esm2022/index.mjs +4 -4
  104. package/angular/fesm2022/nativescript-canvas-angular.mjs +4 -4
  105. package/angular/package.json +20 -0
  106. package/package.json +1 -3
  107. package/platforms/android/canvas-release.aar +0 -0
  108. package/platforms/ios/CanvasNative.xcframework/Info.plist +5 -5
  109. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/CanvasNative +0 -0
  110. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/CanvasNative-Swift.h +9 -0
  111. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/canvas_ios.h +7 -0
  112. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/canvas_native.h +226 -61
  113. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Info.plist +0 -0
  114. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
  115. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.abi.json +6871 -5995
  116. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.private.swiftinterface +7 -0
  117. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.swiftinterface +7 -0
  118. package/platforms/ios/CanvasNative.xcframework/ios-arm64/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/DWARF/CanvasNative +0 -0
  119. package/platforms/ios/CanvasNative.xcframework/ios-arm64/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/aarch64/CanvasNative.yml +656 -644
  120. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/CanvasNative +0 -0
  121. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/CanvasNative-Swift.h +18 -0
  122. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/canvas_ios.h +7 -0
  123. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/canvas_native.h +226 -61
  124. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Info.plist +0 -0
  125. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
  126. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo +0 -0
  127. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.abi.json +6871 -5995
  128. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +7 -0
  129. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.swiftinterface +7 -0
  130. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.abi.json +6871 -5995
  131. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +7 -0
  132. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +7 -0
  133. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/_CodeSignature/CodeResources +27 -27
  134. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/DWARF/CanvasNative +0 -0
  135. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/aarch64/CanvasNative.yml +658 -646
  136. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/x86_64/CanvasNative.yml +696 -684
  137. package/platforms/ios/src/NSOperationQueueWrapper.h +3 -1
  138. package/platforms/ios/src/NSOperationQueueWrapper.mm +41 -9
  139. package/platforms/ios/src/cpp/AsyncCallback.h +214 -0
  140. package/platforms/ios/src/cpp/CanvasJSIModule.cpp +123 -47
  141. package/platforms/ios/src/cpp/Helpers.h +2 -164
  142. package/platforms/ios/src/cpp/ImageAssetImpl.cpp +18 -26
  143. package/platforms/ios/src/cpp/ImageAssetImpl.h +3 -3
  144. package/platforms/ios/src/cpp/ImageBitmapImpl.cpp +60 -3
  145. package/platforms/ios/src/cpp/ImageBitmapImpl.h +12 -4
  146. package/platforms/ios/src/cpp/NativeType.h +87 -0
  147. package/platforms/ios/src/cpp/ObjectWrapperImpl.h +50 -0
  148. package/platforms/ios/src/cpp/PromiseCallback.h +197 -0
  149. package/platforms/ios/src/cpp/canvas2d/CanvasGradient.h +7 -6
  150. package/platforms/ios/src/cpp/canvas2d/CanvasPattern.cpp +1 -1
  151. package/platforms/ios/src/cpp/canvas2d/CanvasPattern.h +1 -1
  152. package/platforms/ios/src/cpp/canvas2d/CanvasRenderingContext2DImpl.cpp +6 -6
  153. package/platforms/ios/src/cpp/canvas2d/CanvasRenderingContext2DImpl.h +18 -13
  154. package/platforms/ios/src/cpp/canvas2d/ImageDataImpl.cpp +2 -2
  155. package/platforms/ios/src/cpp/canvas2d/ImageDataImpl.h +1 -1
  156. package/platforms/ios/src/cpp/canvas2d/MatrixImpl.cpp +10 -10
  157. package/platforms/ios/src/cpp/canvas2d/Path2D.cpp +6 -3
  158. package/platforms/ios/src/cpp/canvas2d/Path2D.h +5 -5
  159. package/platforms/ios/src/cpp/webgl/WebGLActiveInfoImpl.h +1 -1
  160. package/platforms/ios/src/cpp/webgl/WebGLBuffer.h +1 -1
  161. package/platforms/ios/src/cpp/webgl/WebGLFramebuffer.h +1 -1
  162. package/platforms/ios/src/cpp/webgl/WebGLProgram.h +3 -3
  163. package/platforms/ios/src/cpp/webgl/WebGLRenderbuffer.h +3 -3
  164. package/platforms/ios/src/cpp/webgl/WebGLRenderingContext.cpp +106 -1
  165. package/platforms/ios/src/cpp/webgl/WebGLRenderingContext.h +1 -1
  166. package/platforms/ios/src/cpp/webgl/WebGLShader.h +1 -1
  167. package/platforms/ios/src/cpp/webgl/WebGLShaderPrecisionFormatImpl.h +5 -5
  168. package/platforms/ios/src/cpp/webgl/WebGLTexture.h +3 -2
  169. package/platforms/ios/src/cpp/webgl/WebGLUniformLocation.h +2 -2
  170. package/platforms/ios/src/cpp/webgl/extensions/ANGLE_instanced_arraysImpl.h +1 -1
  171. package/platforms/ios/src/cpp/webgl/extensions/EXT_blend_minmaxImpl.h +1 -1
  172. package/platforms/ios/src/cpp/webgl/extensions/EXT_color_buffer_half_floatImpl.h +1 -1
  173. package/platforms/ios/src/cpp/webgl/extensions/EXT_disjoint_timer_queryImpl.h +1 -1
  174. package/platforms/ios/src/cpp/webgl/extensions/EXT_sRGBImpl.h +1 -1
  175. package/platforms/ios/src/cpp/webgl/extensions/EXT_shader_texture_lodImpl.h +1 -1
  176. package/platforms/ios/src/cpp/webgl/extensions/EXT_texture_filter_anisotropicImpl.h +1 -1
  177. package/platforms/ios/src/cpp/webgl/extensions/OES_element_index_uintImpl.h +2 -2
  178. package/platforms/ios/src/cpp/webgl/extensions/OES_fbo_render_mipmap.h +5 -5
  179. package/platforms/ios/src/cpp/webgl/extensions/OES_standard_derivativesImpl.h +1 -1
  180. package/platforms/ios/src/cpp/webgl/extensions/OES_texture_floatImpl.h +1 -1
  181. package/platforms/ios/src/cpp/webgl/extensions/OES_texture_float_linearImpl.h +1 -1
  182. package/platforms/ios/src/cpp/webgl/extensions/OES_texture_half_floatImpl.h +1 -1
  183. package/platforms/ios/src/cpp/webgl/extensions/OES_texture_half_float_linearImpl.h +1 -1
  184. package/platforms/ios/src/cpp/webgl/extensions/OES_vertex_array_objectImpl.h +1 -1
  185. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_color_buffer_floatImpl.h +1 -1
  186. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_atcImpl.h +1 -1
  187. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_etc1Impl.h +1 -1
  188. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_etcImpl.h +2 -2
  189. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_pvrtcImpl.h +1 -1
  190. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_s3tcImpl.h +1 -1
  191. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_s3tc_srgbImpl.h +1 -1
  192. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_depth_textureImpl.h +1 -1
  193. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_draw_buffersImpl.h +1 -1
  194. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_lose_contextImpl.h +1 -1
  195. package/platforms/ios/src/cpp/webgl2/WebGL2RenderingContext.h +1 -1
  196. package/platforms/ios/src/cpp/webgl2/WebGLQuery.h +1 -1
  197. package/platforms/ios/src/cpp/webgl2/WebGLSampler.h +1 -1
  198. package/platforms/ios/src/cpp/webgl2/WebGLSyncImpl.h +1 -1
  199. package/platforms/ios/src/cpp/webgl2/WebGLTransformFeedback.h +1 -1
  200. package/platforms/ios/src/cpp/webgl2/WebGLVertexArrayObject.h +2 -2
  201. package/platforms/ios/src/cpp/webgpu/GPUAdapterImpl.cpp +142 -73
  202. package/platforms/ios/src/cpp/webgpu/GPUAdapterImpl.h +1 -1
  203. package/platforms/ios/src/cpp/webgpu/GPUAdapterInfoImpl.cpp +1 -1
  204. package/platforms/ios/src/cpp/webgpu/GPUAdapterInfoImpl.h +1 -1
  205. package/platforms/ios/src/cpp/webgpu/GPUBindGroupImpl.cpp +32 -6
  206. package/platforms/ios/src/cpp/webgpu/GPUBindGroupImpl.h +5 -2
  207. package/platforms/ios/src/cpp/webgpu/GPUBindGroupLayoutImpl.cpp +27 -1
  208. package/platforms/ios/src/cpp/webgpu/GPUBindGroupLayoutImpl.h +4 -1
  209. package/platforms/ios/src/cpp/webgpu/GPUBufferImpl.cpp +80 -32
  210. package/platforms/ios/src/cpp/webgpu/GPUBufferImpl.h +8 -4
  211. package/platforms/ios/src/cpp/webgpu/GPUCanvasContextImpl.cpp +11 -5
  212. package/platforms/ios/src/cpp/webgpu/GPUCanvasContextImpl.h +1 -1
  213. package/platforms/ios/src/cpp/webgpu/GPUCommandBufferImpl.cpp +29 -2
  214. package/platforms/ios/src/cpp/webgpu/GPUCommandBufferImpl.h +4 -1
  215. package/platforms/ios/src/cpp/webgpu/GPUCommandEncoderImpl.cpp +101 -106
  216. package/platforms/ios/src/cpp/webgpu/GPUCommandEncoderImpl.h +5 -1
  217. package/platforms/ios/src/cpp/webgpu/GPUComputePassEncoderImpl.cpp +42 -14
  218. package/platforms/ios/src/cpp/webgpu/GPUComputePassEncoderImpl.h +4 -1
  219. package/platforms/ios/src/cpp/webgpu/GPUComputePipelineImpl.cpp +26 -1
  220. package/platforms/ios/src/cpp/webgpu/GPUComputePipelineImpl.h +3 -1
  221. package/platforms/ios/src/cpp/webgpu/GPUDeviceImpl.cpp +1683 -733
  222. package/platforms/ios/src/cpp/webgpu/GPUDeviceImpl.h +3 -1
  223. package/platforms/ios/src/cpp/webgpu/GPUImpl.cpp +53 -39
  224. package/platforms/ios/src/cpp/webgpu/GPUImpl.h +2 -2
  225. package/platforms/ios/src/cpp/webgpu/GPULabel.h +33 -0
  226. package/platforms/ios/src/cpp/webgpu/GPUPipelineLayoutImpl.cpp +27 -1
  227. package/platforms/ios/src/cpp/webgpu/GPUPipelineLayoutImpl.h +8 -5
  228. package/platforms/ios/src/cpp/webgpu/GPUQuerySetImpl.cpp +2 -3
  229. package/platforms/ios/src/cpp/webgpu/GPUQuerySetImpl.h +2 -2
  230. package/platforms/ios/src/cpp/webgpu/GPUQueueImpl.cpp +88 -36
  231. package/platforms/ios/src/cpp/webgpu/GPUQueueImpl.h +4 -1
  232. package/platforms/ios/src/cpp/webgpu/GPURenderBundleEncoderImpl.cpp +43 -14
  233. package/platforms/ios/src/cpp/webgpu/GPURenderBundleEncoderImpl.h +4 -1
  234. package/platforms/ios/src/cpp/webgpu/GPURenderBundleImpl.cpp +26 -1
  235. package/platforms/ios/src/cpp/webgpu/GPURenderBundleImpl.h +4 -1
  236. package/platforms/ios/src/cpp/webgpu/GPURenderPassEncoderImpl.cpp +40 -14
  237. package/platforms/ios/src/cpp/webgpu/GPURenderPassEncoderImpl.h +4 -1
  238. package/platforms/ios/src/cpp/webgpu/GPURenderPipelineImpl.cpp +26 -1
  239. package/platforms/ios/src/cpp/webgpu/GPURenderPipelineImpl.h +4 -1
  240. package/platforms/ios/src/cpp/webgpu/GPUSamplerImpl.cpp +27 -1
  241. package/platforms/ios/src/cpp/webgpu/GPUSamplerImpl.h +5 -2
  242. package/platforms/ios/src/cpp/webgpu/GPUShaderModuleImpl.cpp +25 -1
  243. package/platforms/ios/src/cpp/webgpu/GPUShaderModuleImpl.h +5 -2
  244. package/platforms/ios/src/cpp/webgpu/GPUSupportedLimitsImpl.cpp +2 -2
  245. package/platforms/ios/src/cpp/webgpu/GPUSupportedLimitsImpl.h +2 -2
  246. package/platforms/ios/src/cpp/webgpu/GPUTextureImpl.cpp +34 -8
  247. package/platforms/ios/src/cpp/webgpu/GPUTextureImpl.h +6 -4
  248. package/platforms/ios/src/cpp/webgpu/GPUTextureViewImpl.cpp +27 -1
  249. package/platforms/ios/src/cpp/webgpu/GPUTextureViewImpl.h +5 -2
  250. package/platforms/ios/src/cpp/webgpu/GPUUtils.h +511 -0
  251. package/utils.d.ts +1 -1
@@ -21,6 +21,7 @@
21
21
  #include "GPUQuerySetImpl.h"
22
22
  #include "GPURenderBundleEncoderImpl.h"
23
23
  #include "GPUUtils.h"
24
+ #include "GPULabel.h"
24
25
 
25
26
  GPUDeviceImpl::GPUDeviceImpl(const CanvasGPUDevice *device) : device_(device) {}
26
27
 
@@ -38,7 +39,7 @@ void GPUDeviceImpl::Init(v8::Local<v8::Object> canvasModule, v8::Isolate *isolat
38
39
  auto context = isolate->GetCurrentContext();
39
40
  auto func = ctor->GetFunction(context).ToLocalChecked();
40
41
 
41
- canvasModule->Set(context, ConvertToV8String(isolate, "GPUDevice"), func).FromJust();;
42
+ canvasModule->Set(context, ConvertToV8String(isolate, "GPUDevice"), func).FromJust();
42
43
  }
43
44
 
44
45
  GPUDeviceImpl *GPUDeviceImpl::GetPointer(const v8::Local<v8::Object> &object) {
@@ -63,6 +64,11 @@ v8::Local<v8::FunctionTemplate> GPUDeviceImpl::GetCtor(v8::Isolate *isolate) {
63
64
  auto tmpl = ctorTmpl->InstanceTemplate();
64
65
  tmpl->SetInternalFieldCount(2);
65
66
 
67
+ tmpl->SetLazyDataProperty(
68
+ ConvertToV8String(isolate, "label"),
69
+ GetLabel
70
+ );
71
+
66
72
  tmpl->SetLazyDataProperty(
67
73
  ConvertToV8String(isolate, "features"),
68
74
  GetFeatures
@@ -103,6 +109,10 @@ v8::Local<v8::FunctionTemplate> GPUDeviceImpl::GetCtor(v8::Isolate *isolate) {
103
109
  ConvertToV8String(isolate, "createComputePipeline"),
104
110
  v8::FunctionTemplate::New(isolate, &CreateComputePipeline));
105
111
 
112
+ tmpl->Set(
113
+ ConvertToV8String(isolate, "createComputePipelineAsync"),
114
+ v8::FunctionTemplate::New(isolate, &CreateComputePipelineAsync));
115
+
106
116
  tmpl->Set(
107
117
  ConvertToV8String(isolate, "createPipelineLayout"),
108
118
  v8::FunctionTemplate::New(isolate, &CreatePipelineLayout));
@@ -119,6 +129,10 @@ v8::Local<v8::FunctionTemplate> GPUDeviceImpl::GetCtor(v8::Isolate *isolate) {
119
129
  ConvertToV8String(isolate, "createRenderPipeline"),
120
130
  v8::FunctionTemplate::New(isolate, &CreateRenderPipeline));
121
131
 
132
+ tmpl->Set(
133
+ ConvertToV8String(isolate, "createRenderPipelineAsync"),
134
+ v8::FunctionTemplate::New(isolate, &CreateRenderPipelineAsync));
135
+
122
136
  tmpl->Set(
123
137
  ConvertToV8String(isolate, "createSampler"),
124
138
  v8::FunctionTemplate::New(isolate, &CreateSampler));
@@ -154,6 +168,26 @@ v8::Local<v8::FunctionTemplate> GPUDeviceImpl::GetCtor(v8::Isolate *isolate) {
154
168
  return ctorTmpl;
155
169
  }
156
170
 
171
+ void
172
+ GPUDeviceImpl::GetLabel(v8::Local<v8::Name> name,
173
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
174
+ auto ptr = GetPointer(info.This());
175
+ if (ptr != nullptr) {
176
+ auto label = canvas_native_webgpu_device_get_label(ptr->device_);
177
+ if (label == nullptr) {
178
+ info.GetReturnValue().SetEmptyString();
179
+ return;
180
+ }
181
+ info.GetReturnValue().Set(
182
+ ConvertToV8String(info.GetIsolate(), label)
183
+ );
184
+ canvas_native_string_destroy(label);
185
+ return;
186
+ }
187
+
188
+ info.GetReturnValue().SetEmptyString();
189
+ }
190
+
157
191
  void
158
192
  GPUDeviceImpl::SetUncapturedError(const v8::FunctionCallbackInfo<v8::Value> &args) {
159
193
  auto *ptr = GetPointer(args.This());
@@ -244,19 +278,19 @@ GPUDeviceImpl::GetFeatures(v8::Local<v8::Name> name,
244
278
 
245
279
  auto len = canvas_native_string_buffer_get_length(features);
246
280
 
247
- auto map = v8::Map::New(isolate);
281
+ auto set = v8::Set::New(isolate);
248
282
  for (int i = 0; i < len; ++i) {
249
283
  auto item = canvas_native_string_buffer_get_value_at(features, i);
250
284
  if (item != nullptr) {
251
285
  auto keyValue = ConvertToV8String(isolate, (char *) item);
252
- map->Set(context, keyValue, keyValue);
286
+ set->Add(context, keyValue);
253
287
  canvas_native_string_destroy(item);
254
288
  }
255
289
 
256
290
  }
257
291
  canvas_native_string_buffer_release(features);
258
292
 
259
- info.GetReturnValue().Set(map);
293
+ info.GetReturnValue().Set(set);
260
294
 
261
295
  return;
262
296
  }
@@ -296,6 +330,11 @@ GPUDeviceImpl::GetQueue(v8::Local<v8::Name> name,
296
330
  }
297
331
 
298
332
 
333
+ struct LostData {
334
+ int32_t reason;
335
+ char *message;
336
+ };
337
+
299
338
  void
300
339
  GPUDeviceImpl::GetLost(v8::Local<v8::Name> name,
301
340
  const v8::PropertyCallbackInfo<v8::Value> &info) {
@@ -304,64 +343,84 @@ GPUDeviceImpl::GetLost(v8::Local<v8::Name> name,
304
343
  auto resolver = v8::Promise::Resolver::New(isolate->GetCurrentContext()).ToLocalChecked();
305
344
  info.GetReturnValue().Set(resolver->GetPromise());
306
345
  if (ptr != nullptr) {
307
- v8::Global<v8::Promise::Resolver> promise(isolate, resolver);
308
346
  auto callback = new PromiseCallback{
309
347
  isolate,
310
- std::move(promise)
348
+ resolver,
349
+ [](bool done, void *data) {
350
+ if (data != nullptr) {
351
+ auto async_data = static_cast<PromiseCallback *>(data);
352
+ auto func = async_data->inner_.get();
353
+ if (func != nullptr && func->isolate_ != nullptr) {
354
+ v8::Isolate *isolate = func->isolate_;
355
+ v8::Locker locker(isolate);
356
+ v8::Isolate::Scope isolate_scope(
357
+ isolate);
358
+ v8::HandleScope handle_scope(
359
+ isolate);
360
+ v8::Local<v8::Promise::Resolver> callback = func->callback_.Get(
361
+ isolate);
362
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
363
+ v8::Context::Scope context_scope(
364
+ context);
365
+
366
+ auto ret = v8::Object::New(
367
+ isolate);
368
+ LostData *lostData = nullptr;
369
+ if (func->data != nullptr) {
370
+ lostData = static_cast<LostData *>(func->data);
371
+ }
372
+
373
+ if (lostData != nullptr) {
374
+
375
+ if (lostData->message != nullptr) {
376
+ ret->Set(context,
377
+ ConvertToV8String(
378
+ isolate,
379
+ "message"),
380
+ ConvertToV8String(
381
+ isolate,
382
+ lostData->message));
383
+ canvas_native_string_destroy(
384
+ lostData->message);
385
+ }
386
+
387
+ ret->Set(context,
388
+ ConvertToV8String(
389
+ isolate,
390
+ "reason"),
391
+ v8::Int32::New(isolate,
392
+ lostData->reason)).IsJust();
393
+ } else {
394
+ ret->Set(context,
395
+ ConvertToV8String(
396
+ isolate,
397
+ "message"),
398
+ v8::String::Empty(
399
+ isolate));
400
+ }
401
+
402
+ callback->Resolve(context, ret);
403
+ delete static_cast<PromiseCallback *>(data);
404
+ }
405
+ }
406
+ }
311
407
  };
312
408
 
409
+ callback->prepare();
410
+
313
411
  canvas_native_webgpu_device_set_lost_callback(ptr->GetGPUDevice(),
314
412
  [](int32_t reason, char *message,
315
413
  void *data) {
316
414
  if (data != nullptr) {
317
- auto func = static_cast<PromiseCallback *>(data);
318
- if (func->isolate != nullptr) {
319
- v8::Isolate *isolate = func->isolate;
320
- v8::Locker locker(isolate);
321
- v8::Isolate::Scope isolate_scope(
322
- isolate);
323
- v8::HandleScope handle_scope(
324
- isolate);
325
- v8::Local<v8::Promise::Resolver> callback = func->callback.Get(
326
- isolate);
327
- v8::Local<v8::Context> context = callback->GetCreationContextChecked();
328
- v8::Context::Scope context_scope(
329
- context);
330
-
331
- auto ret = v8::Object::New(
332
- isolate);
333
- if (message == nullptr) {
334
- ret->Set(context,
335
- ConvertToV8String(
336
- isolate,
337
- "message"),
338
- v8::String::Empty(
339
- isolate));
340
- } else {
341
- ret->Set(context,
342
- ConvertToV8String(
343
- isolate,
344
- "message"),
345
- ConvertToV8String(
346
- isolate,
347
- message));
348
- canvas_native_string_destroy(
349
- message);
350
- }
351
-
352
- ret->Set(context,
353
- ConvertToV8String(
354
- isolate,
355
- "reason"),
356
- v8::Int32::New(isolate,
357
- reason)).IsJust();
358
-
359
-
360
- callback->Resolve(context, ret);
361
- delete static_cast<PromiseCallback *>(data);
415
+ auto async_data = static_cast<PromiseCallback *>(data);
416
+ auto inner = async_data->inner_.get();
417
+ if (inner != nullptr) {
418
+ inner->data = new LostData{
419
+ reason, message
420
+ };
421
+ async_data->execute(true);
362
422
  }
363
423
  }
364
-
365
424
  }, callback);
366
425
  }
367
426
  }
@@ -374,7 +433,7 @@ void GPUDeviceImpl::CreateBindGroup(const v8::FunctionCallbackInfo<v8::Value> &a
374
433
  }
375
434
  auto isolate = args.GetIsolate();
376
435
  auto context = isolate->GetCurrentContext();
377
- char *label = nullptr;
436
+ GPULabel label;
378
437
 
379
438
  auto optionsVal = args[0];
380
439
 
@@ -385,12 +444,10 @@ void GPUDeviceImpl::CreateBindGroup(const v8::FunctionCallbackInfo<v8::Value> &a
385
444
  v8::Local<v8::Value> labelVal;
386
445
  options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
387
446
 
388
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
389
- label = *v8::String::Utf8Value(isolate, labelVal);
390
- }
391
447
 
392
- const CanvasGPUBindGroupLayout *layout = nullptr;
448
+ label = GPULabel(isolate, labelVal);
393
449
 
450
+ const CanvasGPUBindGroupLayout *layout = nullptr;
394
451
 
395
452
  v8::Local<v8::Value> layoutVal;
396
453
  options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(&layoutVal);
@@ -407,107 +464,10 @@ void GPUDeviceImpl::CreateBindGroup(const v8::FunctionCallbackInfo<v8::Value> &a
407
464
  v8::Local<v8::Value> entriesVal;
408
465
  options->Get(context, ConvertToV8String(isolate, "entries")).ToLocal(&entriesVal);
409
466
 
410
- if (!entriesVal.IsEmpty() && entriesVal->IsArray()) {
411
- auto entriesArray = entriesVal.As<v8::Array>();
412
- auto len = entriesArray->Length();
413
- for (int i = 0; i < len; i++) {
414
- v8::Local<v8::Value> entryVal;
415
- entriesArray->Get(context, i).ToLocal(&entryVal);
416
- if (!entryVal.IsEmpty() && entryVal->IsObject()) {
417
- auto entryObj = entryVal.As<v8::Object>();
418
- auto binding = entryObj->Get(context, ConvertToV8String(isolate,
419
- "binding")).ToLocalChecked()->Uint32Value(
420
- context).FromJust();
421
- v8::Local<v8::Value> resourceVal;
422
- entryObj->Get(context, ConvertToV8String(isolate, "resource")).ToLocal(
423
- &resourceVal);
424
-
425
- auto resourceType = GetNativeType(resourceVal);
426
- switch (resourceType) {
427
- case NativeType::GPUSampler: {
428
- auto sampler = GPUSamplerImpl::GetPointer(resourceVal.As<v8::Object>());
429
- if (sampler != nullptr) {
430
- auto resource = CanvasBindGroupEntryResource{
431
- CanvasBindGroupEntryResourceSampler,
432
- };
433
- resource.sampler = sampler->GetSampler();
434
- CanvasBindGroupEntry entry{binding, resource};
435
- entries.push_back(entry);
436
- }
437
-
438
- }
439
- break;
440
- case NativeType::GPUTextureView: {
441
- auto textureView = GPUTextureViewImpl::GetPointer(
442
- resourceVal.As<v8::Object>());
443
- if (textureView != nullptr) {
444
- auto resource = CanvasBindGroupEntryResource{
445
- CanvasBindGroupEntryResourceTextureView,
446
- };
447
- resource.texture_view = textureView->GetTextureView();
448
- CanvasBindGroupEntry entry{binding, resource};
449
- entries.push_back(entry);
450
- }
451
- }
452
- break;
453
- default: {
454
- if (!resourceVal.IsEmpty() && resourceVal->IsObject()) {
455
- auto resourceObj = resourceVal.As<v8::Object>();
456
- v8::Local<v8::Value> bufferVal;
457
- resourceObj->Get(context,
458
- ConvertToV8String(isolate, "buffer")).ToLocal(
459
- &bufferVal);
460
- if (GetNativeType(bufferVal) == NativeType::GPUBuffer) {
461
- auto bufferObj = bufferVal.As<v8::Object>();
462
- auto buffer = GPUBufferImpl::GetPointer(bufferObj);
463
- if (buffer != nullptr) {
464
- auto resource = CanvasBindGroupEntryResource{
465
- CanvasBindGroupEntryResourceBuffer,
466
- };
467
- int64_t offset = -1;
468
-
469
- v8::Local<v8::Value> offsetVal;
470
-
471
- resourceObj->Get(context,
472
- ConvertToV8String(isolate,
473
- "offset")).ToLocal(
474
- &offsetVal);
475
- if (!offsetVal.IsEmpty() && offsetVal->IsNumber()) {
476
- offset = (int64_t) offsetVal->NumberValue(
477
- context).ToChecked();
478
- }
479
-
480
- int64_t size = -1;
481
-
482
- v8::Local<v8::Value> sizeVal;
483
- resourceObj->Get(context,
484
- ConvertToV8String(isolate, "size")).ToLocal(
485
- &sizeVal);
486
- if (!sizeVal.IsEmpty() && sizeVal->IsNumber()) {
487
- size = (int64_t) sizeVal->NumberValue(
488
- context).ToChecked();
489
- }
490
-
491
- resource.buffer = CanvasBufferBinding{
492
- buffer->GetGPUBuffer(), offset, size
493
- };
494
-
495
- CanvasBindGroupEntry entry{binding, resource};
496
- entries.push_back(entry);
497
- }
498
- }
499
- }
500
-
501
- }
502
- break;
503
- }
504
-
505
- }
506
- }
507
- }
508
-
467
+ entries = ParseBindGroupEntries(isolate, entriesVal);
509
468
 
510
- auto bind_group = canvas_native_webgpu_device_create_bind_group(ptr->GetGPUDevice(), label,
469
+ auto bind_group = canvas_native_webgpu_device_create_bind_group(ptr->GetGPUDevice(),
470
+ *label,
511
471
  layout, entries.data(),
512
472
  entries.size());
513
473
 
@@ -528,7 +488,7 @@ void GPUDeviceImpl::CreateBindGroupLayout(const v8::FunctionCallbackInfo<v8::Val
528
488
  }
529
489
  auto isolate = args.GetIsolate();
530
490
  auto context = isolate->GetCurrentContext();
531
- char *label = nullptr;
491
+ GPULabel label;
532
492
 
533
493
  auto optionsVal = args[0];
534
494
 
@@ -537,381 +497,16 @@ void GPUDeviceImpl::CreateBindGroupLayout(const v8::FunctionCallbackInfo<v8::Val
537
497
  v8::Local<v8::Value> labelVal;
538
498
  options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
539
499
 
540
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
541
- label = *v8::String::Utf8Value(isolate, labelVal);
542
- }
543
-
544
-
545
- std::vector<CanvasBindGroupLayoutEntry> entries;
500
+ label = GPULabel(isolate, labelVal);
546
501
 
547
502
  v8::Local<v8::Value> entriesVal;
548
503
  options->Get(context, ConvertToV8String(isolate, "entries")).ToLocal(&entriesVal);
549
504
 
550
- if (!entriesVal.IsEmpty() && entriesVal->IsArray()) {
551
- auto entriesArray = entriesVal.As<v8::Array>();
552
- auto len = entriesArray->Length();
553
- for (int i = 0; i < len; i++) {
554
- v8::Local<v8::Value> entryVal;
555
- entriesArray->Get(context, i).ToLocal(&entryVal);
556
- if (!entryVal.IsEmpty() && entryVal->IsObject()) {
557
- auto entryObj = entryVal.As<v8::Object>();
558
- auto binding = entryObj->Get(context, ConvertToV8String(isolate,
559
- "binding")).ToLocalChecked()->Uint32Value(
560
- context).FromJust();
561
- v8::Local<v8::Value> resourceVal;
562
- entryObj->Get(context, ConvertToV8String(isolate, "resource")).ToLocal(
563
- &resourceVal);
564
-
565
-
566
- auto visibility = entryObj->Get(context, ConvertToV8String(isolate,
567
- "visibility")).ToLocalChecked()->Uint32Value(
568
- context).FromJust();
569
-
570
-
571
- v8::Local<v8::Value> bufferVal;
572
-
573
- entryObj->Get(context, ConvertToV8String(isolate, "buffer")).ToLocal(
574
- &bufferVal);
575
-
576
-
577
- if (!bufferVal.IsEmpty() && bufferVal->IsObject()) {
578
- auto bufferObj = bufferVal.As<v8::Object>();
579
- v8::Local<v8::Value> bufferType;
580
- bufferObj->Get(context, ConvertToV8String(isolate, "type")).ToLocal(
581
- &bufferType);
582
-
583
- CanvasBufferBindingType type = CanvasBufferBindingTypeUniform;
584
-
585
- if (!bufferType.IsEmpty() && bufferType->IsString()) {
586
- auto typeStr = ConvertFromV8String(isolate, bufferType);
587
- if (typeStr == "read-only-storage") {
588
- type = CanvasBufferBindingTypeReadOnlyStorage;
589
- } else if (typeStr == "storage") {
590
- type = CanvasBufferBindingTypeStorage;
591
- } else if (typeStr == "uniform") {
592
- type = CanvasBufferBindingTypeUniform;
593
- }
594
- }
595
-
596
- bool has_dynamic_offset = false;
597
-
598
- v8::Local<v8::Value> hasDynamicOffsetVal;
599
- bufferObj->Get(context,
600
- ConvertToV8String(isolate, "hasDynamicOffset")).ToLocal(
601
- &hasDynamicOffsetVal);
602
-
603
-
604
- if (!hasDynamicOffsetVal.IsEmpty() && hasDynamicOffsetVal->IsBoolean()) {
605
- has_dynamic_offset = hasDynamicOffsetVal->BooleanValue(isolate);
606
- }
607
-
608
- int64_t min_binding_size = -1;
609
-
610
- v8::Local<v8::Value> minBindingSizeVal;
611
- bufferObj->Get(context,
612
- ConvertToV8String(isolate, "minBindingSize")).ToLocal(
613
- &minBindingSizeVal);
614
-
615
-
616
- if (!minBindingSizeVal.IsEmpty() && minBindingSizeVal->IsNumber()) {
617
- min_binding_size = (int64_t) minBindingSizeVal->NumberValue(
618
- context).ToChecked();
619
- }
620
-
621
- CanvasBindingType buffer{
622
- CanvasBindingTypeBuffer
623
- };
624
-
625
- buffer.buffer = CanvasBufferBindingLayout{
626
- type, has_dynamic_offset, min_binding_size
627
- };
628
-
629
-
630
- CanvasBindGroupLayoutEntry entry{
631
- binding,
632
- visibility,
633
- buffer
634
- };
635
-
636
- entries.push_back(entry);
637
-
638
- continue;
639
- }
640
-
641
-
642
- v8::Local<v8::Value> externalTextureVal;
643
-
644
- entryObj->Get(context, ConvertToV8String(isolate, "externalTexture")).ToLocal(
645
- &externalTextureVal);
646
-
647
- if (!externalTextureVal.IsEmpty() && externalTextureVal->IsObject()) {
648
- // todo
649
- // CanvasBindingType buffer{
650
- // CanvasBindingTypeTexture
651
- // };
652
- //
653
- // buffer.buffer = CanvasBufferBindingLayout{
654
- // type, has_dynamic_offset, min_binding_size
655
- // };
656
- //
657
- //
658
- // CanvasBindGroupLayoutEntry entry{
659
- // binding,
660
- // visibility,
661
- // buffer
662
- // };
663
-
664
- continue;
665
- }
666
-
667
-
668
- v8::Local<v8::Value> samplerVal;
669
-
670
- entryObj->Get(context, ConvertToV8String(isolate, "sampler")).ToLocal(
671
- &samplerVal);
672
-
673
- if (!samplerVal.IsEmpty() && samplerVal->IsObject()) {
674
- auto samplerObj = samplerVal.As<v8::Object>();
675
- v8::Local<v8::Value> samplerType;
676
- samplerObj->Get(context, ConvertToV8String(isolate, "type")).ToLocal(
677
- &samplerType);
678
-
679
- CanvasSamplerBindingType type = CanvasSamplerBindingTypeFiltering;
680
-
681
- if (!samplerType.IsEmpty() && samplerType->IsString()) {
682
- auto typeStr = ConvertFromV8String(isolate, samplerType);
683
- if (typeStr == "comparison") {
684
- type = CanvasSamplerBindingTypeComparison;
685
- } else if (typeStr == "non-filtering") {
686
- type = CanvasSamplerBindingTypeNonFiltering;
687
- } else if (typeStr == "filtering") {
688
- type = CanvasSamplerBindingTypeFiltering;
689
- }
690
- }
691
-
692
-
693
- CanvasBindingType sampler{
694
- CanvasBindingTypeSampler
695
- };
696
-
697
- sampler.sampler = CanvasSamplerBindingLayout{
698
- type
699
- };
700
-
701
-
702
- CanvasBindGroupLayoutEntry entry{
703
- binding,
704
- visibility,
705
- sampler
706
- };
707
-
708
- entries.push_back(entry);
709
-
710
- continue;
711
-
712
- }
713
-
714
-
715
- v8::Local<v8::Value> storageTextureVal;
716
-
717
- entryObj->Get(context, ConvertToV8String(isolate, "storageTexture")).ToLocal(
718
- &storageTextureVal);
719
-
720
- if (!storageTextureVal.IsEmpty() && storageTextureVal->IsObject()) {
721
- auto storageTextureObj = storageTextureVal.As<v8::Object>();
722
-
723
- CanvasBindingType storage{
724
- CanvasBindingTypeStorageTexture
725
- };
726
-
727
- CanvasStorageTextureAccess access = CanvasStorageTextureAccessWriteOnly;
728
-
729
- v8::Local<v8::Value> accessVal;
730
-
731
- storageTextureObj->Get(context,
732
- ConvertToV8String(isolate, "access")).ToLocal(
733
- &accessVal);
734
-
735
-
736
- if (!accessVal.IsEmpty() && accessVal->IsString()) {
737
- auto accessStr = ConvertFromV8String(isolate, accessVal);
738
-
739
- if (accessStr == "write-only") {
740
- access = CanvasStorageTextureAccessWriteOnly;
741
- } else if (accessStr == "read-only") {
742
- access = CanvasStorageTextureAccessReadOnly;
743
- } else if (accessStr == "read-write") {
744
- access = CanvasStorageTextureAccessReadWrite;
745
- }
746
- }
747
-
748
-
749
- CanvasTextureViewDimension view_dimension = CanvasTextureViewDimensionD2;
750
-
751
-
752
- v8::Local<v8::Value> viewDimensionVal;
753
-
754
- storageTextureObj->Get(context,
755
- ConvertToV8String(isolate, "viewDimension")).ToLocal(
756
- &viewDimensionVal);
757
-
758
-
759
- if (!viewDimensionVal.IsEmpty() && viewDimensionVal->IsString()) {
760
- auto viewDimensionStr = ConvertFromV8String(isolate, viewDimensionVal);
761
- if (viewDimensionStr == "1d") {
762
- view_dimension = CanvasTextureViewDimensionD1;
763
- } else if (viewDimensionStr == "2d") {
764
- view_dimension = CanvasTextureViewDimensionD2;
765
- } else if (viewDimensionStr == "2d-array") {
766
- view_dimension = CanvasTextureViewDimensionD2Array;
767
- } else if (viewDimensionStr == "cube") {
768
- view_dimension = CanvasTextureViewDimensionCube;
769
- } else if (viewDimensionStr == "cube-array") {
770
- view_dimension = CanvasTextureViewDimensionCubeArray;
771
- } else if (viewDimensionStr == "3d") {
772
- view_dimension = CanvasTextureViewDimensionD3;
773
- }
774
- }
775
-
776
-
777
- v8::Local<v8::Value> formatVal;
778
-
779
- storageTextureObj->Get(context,
780
- ConvertToV8String(isolate, "format")).ToLocal(
781
- &formatVal);
782
-
783
-
784
- if (!formatVal.IsEmpty() && formatVal->IsString()) {
785
- auto formatStr = ConvertFromV8String(isolate, formatVal);
786
- auto textureFormat = canvas_native_webgpu_enum_string_to_gpu_texture(
787
- formatStr.c_str());
788
- if (textureFormat.tag == CanvasOptionalGPUTextureFormatSome) {
789
- storage.storage_texture = CanvasStorageTextureBindingLayout{
790
- access,
791
- textureFormat.some,
792
- view_dimension
793
- };
794
-
795
- CanvasBindGroupLayoutEntry entry{
796
- binding,
797
- visibility,
798
- storage
799
- };
800
-
801
- entries.push_back(entry);
802
-
803
- continue;
804
-
805
- } else {
806
- // todo throw ??
807
- continue;
808
- }
809
- }
810
-
811
-
812
- }
813
-
814
-
815
- v8::Local<v8::Value> textureVal;
816
-
817
- entryObj->Get(context, ConvertToV8String(isolate, "texture")).ToLocal(
818
- &textureVal);
819
-
820
- if (!textureVal.IsEmpty() && textureVal->IsObject()) {
821
- auto textureObj = textureVal.As<v8::Object>();
822
- bool multisampled = false;
823
-
824
- v8::Local<v8::Value> multisampledVal;
825
-
826
- textureObj->Get(context,
827
- ConvertToV8String(isolate, "multisampled")).ToLocal(
828
- &multisampledVal);
829
-
830
- if (!multisampledVal.IsEmpty() && multisampledVal->IsBoolean()) {
831
- multisampled = multisampledVal->BooleanValue(isolate);
832
- }
833
-
834
-
835
- v8::Local<v8::Value> sampleTypeVal;
836
- textureObj->Get(context, ConvertToV8String(isolate, "sampleType")).ToLocal(
837
- &sampleTypeVal);
838
-
839
- CanvasTextureSampleType type = CanvasTextureSampleTypeFloat;
840
-
841
- if (!sampleTypeVal.IsEmpty() && sampleTypeVal->IsString()) {
842
- auto typeStr = ConvertFromV8String(isolate, sampleTypeVal);
843
- if (typeStr == "depth") {
844
- type = CanvasTextureSampleTypeDepth;
845
- } else if (typeStr == "float") {
846
- type = CanvasTextureSampleTypeFloat;
847
- } else if (typeStr == "sint") {
848
- type = CanvasTextureSampleTypeSint;
849
- } else if (typeStr == "uint") {
850
- type = CanvasTextureSampleTypeUint;
851
- } else if (typeStr == "unfilterable-float") {
852
- type = CanvasTextureSampleTypeUnfilterableFloat;
853
- }
854
- }
855
-
856
-
857
- CanvasTextureViewDimension view_dimension = CanvasTextureViewDimensionD2;
858
-
859
-
860
- v8::Local<v8::Value> viewDimensionVal;
861
-
862
- textureObj->Get(context,
863
- ConvertToV8String(isolate, "viewDimension")).ToLocal(
864
- &viewDimensionVal);
865
-
866
-
867
- if (!viewDimensionVal.IsEmpty() && viewDimensionVal->IsString()) {
868
- auto viewDimensionStr = ConvertFromV8String(isolate, viewDimensionVal);
869
- if (viewDimensionStr == "1d") {
870
- view_dimension = CanvasTextureViewDimensionD1;
871
- } else if (viewDimensionStr == "2d") {
872
- view_dimension = CanvasTextureViewDimensionD2;
873
- } else if (viewDimensionStr == "2d-array") {
874
- view_dimension = CanvasTextureViewDimensionD2Array;
875
- } else if (viewDimensionStr == "cube") {
876
- view_dimension = CanvasTextureViewDimensionCube;
877
- } else if (viewDimensionStr == "cube-array") {
878
- view_dimension = CanvasTextureViewDimensionCubeArray;
879
- } else if (viewDimensionStr == "3d") {
880
- view_dimension = CanvasTextureViewDimensionD3;
881
- }
882
- }
883
-
884
-
885
- CanvasBindingType texture{
886
- CanvasBindingTypeTexture
887
- };
888
-
889
- texture.texture = CanvasTextureBindingLayout{
890
- type,
891
- view_dimension,
892
- multisampled
893
- };
894
-
895
-
896
- CanvasBindGroupLayoutEntry entry{
897
- binding,
898
- visibility,
899
- texture
900
- };
901
-
902
- entries.push_back(entry);
903
-
904
- continue;
905
-
906
- }
907
-
908
- }
909
- }
910
- }
911
-
505
+ std::vector<CanvasBindGroupLayoutEntry> entries = ParseBindGroupLayoutEntries(isolate,
506
+ entriesVal);
912
507
 
913
508
  auto bind_group = canvas_native_webgpu_device_create_bind_group_layout(ptr->GetGPUDevice(),
914
- label,
509
+ *label,
915
510
  entries.data(),
916
511
  entries.size());
917
512
 
@@ -933,7 +528,7 @@ void GPUDeviceImpl::CreateBuffer(const v8::FunctionCallbackInfo<v8::Value> &args
933
528
  }
934
529
  auto isolate = args.GetIsolate();
935
530
  auto context = isolate->GetCurrentContext();
936
- char *label = nullptr;
531
+ GPULabel label;
937
532
  bool mappedAtCreation = false;
938
533
  uint64_t size = 0;
939
534
  uint32_t usage = 0;
@@ -945,10 +540,7 @@ void GPUDeviceImpl::CreateBuffer(const v8::FunctionCallbackInfo<v8::Value> &args
945
540
  v8::Local<v8::Value> labelVal;
946
541
  options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
947
542
 
948
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
949
- label = *v8::String::Utf8Value(isolate, labelVal);
950
- }
951
-
543
+ label = GPULabel(isolate, labelVal);
952
544
  v8::Local<v8::Value> mappedAtCreationVal;
953
545
 
954
546
  options->Get(context, ConvertToV8String(isolate, "mappedAtCreation")).ToLocal(
@@ -974,7 +566,8 @@ void GPUDeviceImpl::CreateBuffer(const v8::FunctionCallbackInfo<v8::Value> &args
974
566
  }
975
567
  }
976
568
 
977
- auto buffer = canvas_native_webgpu_device_create_buffer(ptr->GetGPUDevice(), label, size, usage,
569
+ auto buffer = canvas_native_webgpu_device_create_buffer(ptr->GetGPUDevice(), *label,
570
+ size, usage,
978
571
  mappedAtCreation);
979
572
 
980
573
  if (buffer != nullptr) {
@@ -995,15 +588,10 @@ void GPUDeviceImpl::CreateCommandEncoder(const v8::FunctionCallbackInfo<v8::Valu
995
588
  }
996
589
  auto isolate = args.GetIsolate();
997
590
 
998
- char *label = nullptr;
591
+ auto label = GPULabel(isolate, args[0]);
999
592
 
1000
- auto labelVal = args[0];
1001
-
1002
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
1003
- label = *v8::String::Utf8Value(isolate, labelVal);
1004
- }
1005
-
1006
- auto encoder = canvas_native_webgpu_device_create_command_encoder(ptr->GetGPUDevice(), label);
593
+ auto encoder = canvas_native_webgpu_device_create_command_encoder(ptr->GetGPUDevice(),
594
+ *label);
1007
595
 
1008
596
  if (encoder != nullptr) {
1009
597
  auto instance = new GPUCommandEncoderImpl(encoder);
@@ -1035,11 +623,7 @@ void GPUDeviceImpl::CreateComputePipeline(const v8::FunctionCallbackInfo<v8::Val
1035
623
  v8::Local<v8::Value> labelVal;
1036
624
  options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1037
625
 
1038
- char *label = nullptr;
1039
-
1040
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
1041
- label = *v8::String::Utf8Value(isolate, labelVal);
1042
- }
626
+ GPULabel label(isolate, labelVal);
1043
627
 
1044
628
  CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout{
1045
629
  CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
@@ -1125,7 +709,8 @@ void GPUDeviceImpl::CreateComputePipeline(const v8::FunctionCallbackInfo<v8::Val
1125
709
  };
1126
710
 
1127
711
  auto pipeline = canvas_native_webgpu_device_create_compute_pipeline(ptr->GetGPUDevice(),
1128
- label, layout, &stage);
712
+ *label, layout,
713
+ &stage);
1129
714
 
1130
715
  if (entry_point != nullptr) {
1131
716
  free(entry_point);
@@ -1148,7 +733,34 @@ void GPUDeviceImpl::CreateComputePipeline(const v8::FunctionCallbackInfo<v8::Val
1148
733
  args.GetReturnValue().SetUndefined();
1149
734
  }
1150
735
 
1151
- void GPUDeviceImpl::CreatePipelineLayout(const v8::FunctionCallbackInfo<v8::Value> &args) {
736
+ struct ComputePipeLineAsyncData {
737
+ char *label;
738
+ CanvasConstants *constants;
739
+ enum CanvasGPUErrorType type;
740
+ char *errorMessage;
741
+ const CanvasGPUComputePipeline *pipeline;
742
+
743
+ ~ComputePipeLineAsyncData() {
744
+ if (label != nullptr) {
745
+ free(label);
746
+ label = nullptr;
747
+ canvas_native_webgpu_constants_destroy(constants);
748
+ constants = nullptr;
749
+ }
750
+
751
+ if (constants != nullptr) {
752
+ canvas_native_webgpu_constants_destroy(constants);
753
+ constants = nullptr;
754
+ }
755
+
756
+ if (errorMessage != nullptr) {
757
+ canvas_native_string_destroy(errorMessage);
758
+ errorMessage = nullptr;
759
+ }
760
+ }
761
+ };
762
+
763
+ void GPUDeviceImpl::CreateComputePipelineAsync(const v8::FunctionCallbackInfo<v8::Value> &args) {
1152
764
  GPUDeviceImpl *ptr = GetPointer(args.This());
1153
765
  if (ptr == nullptr) {
1154
766
  return;
@@ -1157,6 +769,7 @@ void GPUDeviceImpl::CreatePipelineLayout(const v8::FunctionCallbackInfo<v8::Valu
1157
769
  auto context = isolate->GetCurrentContext();
1158
770
 
1159
771
  auto optionsVal = args[0];
772
+ auto callback = args[1];
1160
773
 
1161
774
  if (!optionsVal->IsObject()) {
1162
775
  // should error at this point
@@ -1167,33 +780,282 @@ void GPUDeviceImpl::CreatePipelineLayout(const v8::FunctionCallbackInfo<v8::Valu
1167
780
  v8::Local<v8::Value> labelVal;
1168
781
  options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1169
782
 
1170
- char *label = nullptr;
783
+ auto label = GPULabel(isolate, labelVal);
784
+
785
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout{
786
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
787
+ };
788
+
789
+ v8::Local<v8::Value> layoutVal;
1171
790
 
1172
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
1173
- label = *v8::String::Utf8Value(isolate, labelVal);
791
+ if (options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(&layoutVal) &&
792
+ layoutVal->IsObject()) {
793
+ auto layoutImpl = GPUPipelineLayoutImpl::GetPointer(layoutVal.As<v8::Object>());
794
+ if (layoutImpl != nullptr) {
795
+ layout.tag = CanvasGPUPipelineLayoutOrGPUAutoLayoutModeLayout;
796
+ layout.layout = layoutImpl->GetPipeline();
797
+ }
1174
798
  }
1175
799
 
1176
800
 
1177
- std::vector<const CanvasGPUBindGroupLayout *> group_layouts;
801
+ v8::Local<v8::Value> computeVal;
802
+ options->Get(context, ConvertToV8String(isolate, "compute")).ToLocal(&computeVal);
1178
803
 
1179
- v8::Local<v8::Value> groupLayoutsVal;
1180
- options->Get(context, ConvertToV8String(isolate, "bindGroupLayouts")).ToLocal(&groupLayoutsVal);
804
+ if (!computeVal.IsEmpty() && computeVal->IsObject()) {
1181
805
 
1182
- if (!groupLayoutsVal.IsEmpty() && groupLayoutsVal->IsArray()) {
1183
- auto groupLayoutsArray = groupLayoutsVal.As<v8::Array>();
1184
- auto len = groupLayoutsArray->Length();
1185
- for (int i = 0; i < len; i++) {
1186
- v8::Local<v8::Value> groupVal;
1187
- groupLayoutsArray->Get(context, i).ToLocal(&groupVal);
1188
- if (GetNativeType(groupVal) == NativeType::GPUBindGroupLayout) {
1189
- auto layout = GPUBindGroupLayoutImpl::GetPointer(groupVal.As<v8::Object>());
1190
- if (layout != nullptr) {
806
+ auto computeObj = computeVal.As<v8::Object>();
807
+
808
+ v8::Local<v8::Value> constantsVal;
809
+ computeObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(
810
+ &constantsVal);
811
+
812
+ CanvasConstants *store = nullptr;
813
+
814
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
815
+ auto constants = constantsVal.As<v8::Map>();
816
+ auto keyValues = constants->AsArray();
817
+ auto length = keyValues->Length();
818
+ if (length > 0) {
819
+ store = canvas_native_webgpu_constants_create();
820
+ for (int i = 0; i < length; i += 2) {
821
+ auto k = i;
822
+ auto v = k + 1;
823
+
824
+ v8::Local<v8::Value> keyVal;
825
+ keyValues->Get(context, k).ToLocal(&keyVal);
826
+ v8::Local<v8::Value> valueVal;
827
+ keyValues->Get(context, v).ToLocal(&valueVal);
828
+
829
+
830
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
831
+ valueVal->IsNumber()) {
832
+ auto val = ConvertFromV8String(isolate, keyVal);
833
+ canvas_native_webgpu_constants_insert(
834
+ store,
835
+ val.c_str(),
836
+ valueVal.As<v8::Number>()->Value()
837
+ );
838
+ }
839
+
840
+ }
841
+ }
842
+ }
843
+
844
+
845
+ v8::Local<v8::Value> entryPoint;
846
+ computeObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(
847
+ &entryPoint);
848
+
849
+ char *entry_point = nullptr;
850
+
851
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
852
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
853
+ entry_point = (char *) malloc(ep.length());
854
+ std::strcpy(entry_point, *ep);
855
+ }
856
+
857
+ v8::Local<v8::Value> moduleVal;
858
+ computeObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
859
+
860
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
861
+
862
+ CanvasProgrammableStage stage{
863
+ module->GetShaderModule(),
864
+ entry_point,
865
+ store
866
+ };
867
+
868
+
869
+ auto async_callback = new AsyncCallback(isolate, callback.As<v8::Function>(),
870
+ [](bool success, void *data) {
871
+ if (data != nullptr) {
872
+
873
+ auto async_data = static_cast<AsyncCallback *>(data);
874
+ auto func = async_data->inner_.get();
875
+ if (func != nullptr &&
876
+ func->isolate_ != nullptr) {
877
+ v8::Isolate *isolate = func->isolate_;
878
+ v8::Locker locker(isolate);
879
+ v8::Isolate::Scope isolate_scope(
880
+ isolate);
881
+ v8::HandleScope handle_scope(isolate);
882
+ v8::Local<v8::Function> callback = func->callback_.Get(
883
+ isolate);
884
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
885
+ v8::Context::Scope context_scope(
886
+ context);
887
+
888
+ ComputePipeLineAsyncData *pipelineData = nullptr;
889
+ if (func->data != nullptr) {
890
+ pipelineData = static_cast<ComputePipeLineAsyncData *>(func->data);
891
+ }
892
+
893
+ if (pipelineData == nullptr) {
894
+ // Should never happen
895
+
896
+ auto error = v8::Object::New(
897
+ isolate);
898
+ error->Set(context,
899
+ ConvertToV8String(
900
+ isolate,
901
+ "error"),
902
+ v8::Exception::Error(
903
+ ConvertToV8String(
904
+ isolate,
905
+ "Internal Error")));
906
+ error->Set(context,
907
+ ConvertToV8String(
908
+ isolate,
909
+ "type"),
910
+ v8::Uint32::NewFromUnsigned(
911
+ isolate,
912
+ (uint32_t) CanvasGPUErrorType::CanvasGPUErrorTypeInternal));
913
+
914
+
915
+ v8::Local<v8::Value> args[1] = {
916
+ error};
917
+
918
+ callback->Call(context,
919
+ context->Global(),
920
+ 1,
921
+ args); // ignore JS return value
922
+ delete static_cast<AsyncCallback *>(data);
923
+
924
+ return;
925
+ }
926
+
927
+ if (pipelineData->type !=
928
+ CanvasGPUErrorType::CanvasGPUErrorTypeNone) {
929
+
930
+ auto error = v8::Object::New(
931
+ isolate);
932
+ error->Set(context,
933
+ ConvertToV8String(
934
+ isolate,
935
+ "error"),
936
+ v8::Exception::Error(
937
+ ConvertToV8String(
938
+ isolate,
939
+ pipelineData->errorMessage)));
940
+
941
+ error->Set(context,
942
+ ConvertToV8String(
943
+ isolate,
944
+ "type"),
945
+ v8::Uint32::NewFromUnsigned(
946
+ isolate,
947
+ (uint32_t) pipelineData->type));
948
+
949
+ v8::Local<v8::Value> args[1] = {
950
+ error};
951
+
952
+ callback->Call(context,
953
+ context->Global(),
954
+ 1,
955
+ args); // ignore JS return value
956
+ } else {
957
+
958
+ auto ret = GPUComputePipelineImpl::NewInstance(
959
+ isolate,
960
+ new GPUComputePipelineImpl(
961
+ pipelineData->pipeline));
962
+
963
+ v8::Local<v8::Value> args[2] = {
964
+ v8::Null(isolate), ret};
965
+
966
+
967
+ callback->Call(context,
968
+ context->Global(),
969
+ 2,
970
+ args); // ignore JS return value
971
+ }
972
+
973
+ if (pipelineData != nullptr) {
974
+ delete pipelineData;
975
+ pipelineData = nullptr;
976
+ }
977
+
978
+ delete static_cast<AsyncCallback *>(data);
979
+ }
980
+ }
981
+ });
982
+ async_callback->inner_->data = new ComputePipeLineAsyncData{
983
+ entry_point,
984
+ store,
985
+ CanvasGPUErrorType::CanvasGPUErrorTypeNone,
986
+ nullptr,
987
+ nullptr
988
+ };
989
+ async_callback->prepare();
990
+ canvas_native_webgpu_device_create_compute_pipeline_async(ptr->GetGPUDevice(),
991
+ *label, layout, &stage,
992
+ [](const struct CanvasGPUComputePipeline *pipeline,
993
+ enum CanvasGPUErrorType type,
994
+ char *message,
995
+ void *data) {
996
+ if (data != nullptr) {
997
+ auto async_data = static_cast<AsyncCallback *>(data);
998
+ auto inner = async_data->inner_.get();
999
+ if (inner != nullptr) {
1000
+ auto pipeline_data = static_cast<ComputePipeLineAsyncData *>(inner->data);
1001
+ pipeline_data->errorMessage = message;
1002
+ pipeline_data->type = type;
1003
+ pipeline_data->pipeline = pipeline;
1004
+ async_data->execute(
1005
+ true);
1006
+ }
1007
+ }
1008
+ }, async_callback);
1009
+
1010
+
1011
+ }
1012
+
1013
+ args.GetReturnValue().SetUndefined();
1014
+ }
1015
+
1016
+ void GPUDeviceImpl::CreatePipelineLayout(const v8::FunctionCallbackInfo<v8::Value> &args) {
1017
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1018
+ if (ptr == nullptr) {
1019
+ return;
1020
+ }
1021
+ auto isolate = args.GetIsolate();
1022
+ auto context = isolate->GetCurrentContext();
1023
+
1024
+ auto optionsVal = args[0];
1025
+
1026
+ if (!optionsVal->IsObject()) {
1027
+ // should error at this point
1028
+ return;
1029
+ }
1030
+ auto options = optionsVal.As<v8::Object>();
1031
+
1032
+ v8::Local<v8::Value> labelVal;
1033
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1034
+
1035
+ auto label = GPULabel(isolate, labelVal);
1036
+
1037
+
1038
+ std::vector<const CanvasGPUBindGroupLayout *> group_layouts;
1039
+
1040
+ v8::Local<v8::Value> groupLayoutsVal;
1041
+ options->Get(context, ConvertToV8String(isolate, "bindGroupLayouts")).ToLocal(&groupLayoutsVal);
1042
+
1043
+ if (!groupLayoutsVal.IsEmpty() && groupLayoutsVal->IsArray()) {
1044
+ auto groupLayoutsArray = groupLayoutsVal.As<v8::Array>();
1045
+ auto len = groupLayoutsArray->Length();
1046
+ for (int i = 0; i < len; i++) {
1047
+ v8::Local<v8::Value> groupVal;
1048
+ groupLayoutsArray->Get(context, i).ToLocal(&groupVal);
1049
+ if (GetNativeType(groupVal) == NativeType::GPUBindGroupLayout) {
1050
+ auto layout = GPUBindGroupLayoutImpl::GetPointer(groupVal.As<v8::Object>());
1051
+ if (layout != nullptr) {
1191
1052
  group_layouts.push_back(layout->GetBindGroupLayout());
1192
1053
  }
1193
1054
  }
1194
1055
  }
1195
1056
 
1196
- auto layout = canvas_native_webgpu_device_create_pipeline_layout(ptr->GetGPUDevice(), label,
1057
+ auto layout = canvas_native_webgpu_device_create_pipeline_layout(ptr->GetGPUDevice(),
1058
+ *label,
1197
1059
  group_layouts.data(),
1198
1060
  group_layouts.size());
1199
1061
 
@@ -1203,158 +1065,1126 @@ void GPUDeviceImpl::CreatePipelineLayout(const v8::FunctionCallbackInfo<v8::Valu
1203
1065
  args.GetReturnValue().Set(ret);
1204
1066
  return;
1205
1067
  }
1206
- }
1068
+ }
1069
+
1070
+
1071
+ args.GetReturnValue().SetUndefined();
1072
+ }
1073
+
1074
+ void GPUDeviceImpl::CreateQuerySet(const v8::FunctionCallbackInfo<v8::Value> &args) {
1075
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1076
+ if (ptr == nullptr) {
1077
+ return;
1078
+ }
1079
+ auto isolate = args.GetIsolate();
1080
+ auto context = isolate->GetCurrentContext();
1081
+
1082
+ auto optionsVal = args[0];
1083
+
1084
+ if (!optionsVal->IsObject()) {
1085
+ // should error at this point
1086
+ return;
1087
+ }
1088
+ auto options = optionsVal.As<v8::Object>();
1089
+
1090
+ v8::Local<v8::Value> labelVal;
1091
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1092
+
1093
+ auto label = GPULabel(isolate, labelVal);
1094
+ v8::Local<v8::Value> typeVal;
1095
+ options->Get(context, ConvertToV8String(isolate, "type")).ToLocal(&typeVal);
1096
+
1097
+
1098
+ v8::Local<v8::Value> countVal;
1099
+ options->Get(context, ConvertToV8String(isolate, "count")).ToLocal(&countVal);
1100
+
1101
+ auto typeStr = ConvertFromV8String(isolate, typeVal);
1102
+
1103
+ const CanvasGPUQuerySet *query_set = nullptr;
1104
+ if (typeStr == "occlusion") {
1105
+ query_set = canvas_native_webgpu_device_create_query_set(ptr->GetGPUDevice(), *label,
1106
+ CanvasQueryTypeOcclusion,
1107
+ countVal->Uint32Value(
1108
+ context).FromJust());
1109
+ } else if (typeStr == "timestamp") {
1110
+ query_set = canvas_native_webgpu_device_create_query_set(ptr->GetGPUDevice(), *label,
1111
+ CanvasQueryTypeTimestamp,
1112
+ countVal->Uint32Value(
1113
+ context).FromJust());
1114
+ } else {
1115
+ // todo throw
1116
+ }
1117
+
1118
+
1119
+ if (query_set != nullptr) {
1120
+ auto ret = GPUQuerySetImpl::NewInstance(isolate, new GPUQuerySetImpl(query_set));
1121
+ args.GetReturnValue().Set(ret);
1122
+ return;
1123
+ }
1124
+
1125
+ args.GetReturnValue().SetUndefined();
1126
+
1127
+ }
1128
+
1129
+ void GPUDeviceImpl::CreateRenderBundleEncoder(const v8::FunctionCallbackInfo<v8::Value> &args) {
1130
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1131
+ if (ptr == nullptr) {
1132
+ return;
1133
+ }
1134
+ auto isolate = args.GetIsolate();
1135
+ auto context = isolate->GetCurrentContext();
1136
+
1137
+ auto optionsVal = args[0];
1138
+
1139
+ if (!optionsVal->IsObject()) {
1140
+ // should error at this point
1141
+ return;
1142
+ }
1143
+ auto options = optionsVal.As<v8::Object>();
1144
+
1145
+ v8::Local<v8::Value> labelVal;
1146
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1147
+
1148
+ auto label = GPULabel(isolate, labelVal);
1149
+
1150
+ std::vector<CanvasGPUTextureFormat> colorFormats;
1151
+
1152
+ v8::Local<v8::Value> colorFormatsVal;
1153
+ options->Get(context, ConvertToV8String(isolate, "colorFormats")).ToLocal(&colorFormatsVal);
1154
+
1155
+ if (!colorFormatsVal.IsEmpty() && colorFormatsVal->IsArray()) {
1156
+ auto colorFormatsArray = colorFormatsVal.As<v8::Array>();
1157
+ auto len = colorFormatsArray->Length();
1158
+ for (int i = 0; i < len; i++) {
1159
+ v8::Local<v8::Value> formatVal;
1160
+ colorFormatsArray->Get(context, i).ToLocal(&formatVal);
1161
+ if (!formatVal.IsEmpty() && formatVal->IsString()) {
1162
+ auto formatStr = ConvertFromV8String(isolate, formatVal);
1163
+ auto format = canvas_native_webgpu_enum_string_to_gpu_texture(formatStr.c_str());
1164
+ if (format.tag == CanvasOptionalGPUTextureFormatSome) {
1165
+ colorFormats.push_back(format.some);
1166
+ }
1167
+ }
1168
+
1169
+ }
1170
+ }
1171
+
1172
+
1173
+ auto depthStencilFormat = CanvasOptionalGPUTextureFormat{
1174
+ CanvasOptionalGPUTextureFormatNone
1175
+ };
1176
+
1177
+ v8::Local<v8::Value> depthStencilFormatVal;
1178
+ options->Get(context, ConvertToV8String(isolate, "depthStencilFormat")).ToLocal(
1179
+ &depthStencilFormatVal);
1180
+
1181
+ if (!depthStencilFormatVal.IsEmpty() && depthStencilFormatVal->IsString()) {
1182
+ auto depthStencilFormatStr = ConvertFromV8String(isolate, depthStencilFormatVal);
1183
+ depthStencilFormat = canvas_native_webgpu_enum_string_to_gpu_texture(
1184
+ depthStencilFormatStr.c_str());
1185
+ }
1186
+
1187
+ uint32_t sampleCount = 1;
1188
+
1189
+ bool depthReadOnly = false;
1190
+
1191
+ bool stencilReadOnly = false;
1192
+
1193
+ CanvasCreateRenderBundleEncoderDescriptor descriptor{
1194
+ *label,
1195
+ colorFormats.data(),
1196
+ colorFormats.size(),
1197
+ depthStencilFormat,
1198
+ sampleCount,
1199
+ depthReadOnly,
1200
+ stencilReadOnly
1201
+ };
1202
+
1203
+
1204
+ auto encoder = canvas_native_webgpu_device_create_render_bundle_encoder(ptr->GetGPUDevice(),
1205
+ &descriptor);
1206
+
1207
+ if (encoder != nullptr) {
1208
+ auto ret = GPURenderBundleEncoderImpl::NewInstance(isolate,
1209
+ new GPURenderBundleEncoderImpl(encoder));
1210
+ args.GetReturnValue().Set(ret);
1211
+ return;
1212
+ }
1213
+
1214
+ args.GetReturnValue().SetUndefined();
1215
+ }
1216
+
1217
+ struct RenderPipeLineAsyncData {
1218
+ char *label;
1219
+ char *vertex_entry_point;
1220
+ char *fragment_entry_point;
1221
+ CanvasConstants *constants;
1222
+ enum CanvasGPUErrorType type;
1223
+ char *errorMessage;
1224
+ const CanvasGPURenderPipeline *pipeline;
1225
+ CanvasPrimitiveState *primitive;
1226
+ CanvasMultisampleState *multisample;
1227
+ CanvasDepthStencilState *depth_stencil;
1228
+ CanvasConstants *vertex_constants;
1229
+
1230
+ ~RenderPipeLineAsyncData() {
1231
+ if (label != nullptr) {
1232
+ free(label);
1233
+ label = nullptr;
1234
+ }
1235
+
1236
+ if (constants != nullptr) {
1237
+ canvas_native_webgpu_constants_destroy(constants);
1238
+ constants = nullptr;
1239
+ }
1240
+
1241
+ if (errorMessage != nullptr) {
1242
+ canvas_native_string_destroy(errorMessage);
1243
+ errorMessage = nullptr;
1244
+ }
1245
+
1246
+ if (primitive != nullptr) {
1247
+ delete primitive;
1248
+ primitive = nullptr;
1249
+ }
1250
+
1251
+ if (multisample != nullptr) {
1252
+ delete multisample;
1253
+ multisample = nullptr;
1254
+ }
1255
+
1256
+ if (vertex_entry_point != nullptr) {
1257
+ free(vertex_entry_point);
1258
+ vertex_entry_point = nullptr;
1259
+ }
1260
+
1261
+ if (fragment_entry_point != nullptr) {
1262
+ free(fragment_entry_point);
1263
+ fragment_entry_point = nullptr;
1264
+ }
1265
+
1266
+ if (depth_stencil != nullptr) {
1267
+ delete depth_stencil;
1268
+ depth_stencil = nullptr;
1269
+ }
1270
+
1271
+ if (vertex_constants != nullptr) {
1272
+ canvas_native_webgpu_constants_destroy(vertex_constants);
1273
+ vertex_constants = nullptr;
1274
+ }
1275
+ }
1276
+ };
1277
+
1278
+ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Value> &args) {
1279
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1280
+ if (ptr == nullptr) {
1281
+ return;
1282
+ }
1283
+ auto isolate = args.GetIsolate();
1284
+ auto context = isolate->GetCurrentContext();
1285
+
1286
+ CanvasCreateRenderPipelineDescriptor descriptor{};
1287
+ descriptor.label = nullptr;
1288
+
1289
+ auto optionsVal = args[0];
1290
+
1291
+ if (!optionsVal->IsObject()) {
1292
+ // should error at this point
1293
+ return;
1294
+ }
1295
+ auto options = optionsVal.As<v8::Object>();
1296
+
1297
+ v8::Local<v8::Value> stencilValue;
1298
+ options->Get(context, ConvertToV8String(isolate, "depthStencil")).ToLocal(
1299
+ &stencilValue);
1300
+
1301
+ CanvasDepthStencilState *stencil = nullptr;
1302
+
1303
+ if (!stencilValue.IsEmpty() && stencilValue->IsObject()) {
1304
+ auto stencilObj = stencilValue.As<v8::Object>();
1305
+ stencil = new CanvasDepthStencilState{};
1306
+ stencil->depth_bias = 0;
1307
+ stencil->depth_bias_clamp = 0;
1308
+ stencil->depth_bias_slope_scale = 0;
1309
+ stencil->stencil_read_mask = 0xFFFFFFFF;
1310
+ stencil->stencil_write_mask = 0xFFFFFFFF;
1311
+ stencil->stencil_front = CanvasStencilFaceState{
1312
+ CanvasCompareFunctionAlways,
1313
+ CanvasStencilOperationKeep,
1314
+ CanvasStencilOperationKeep,
1315
+ CanvasStencilOperationKeep
1316
+ };
1317
+
1318
+ stencil->stencil_back = CanvasStencilFaceState{
1319
+ CanvasCompareFunctionAlways,
1320
+ CanvasStencilOperationKeep,
1321
+ CanvasStencilOperationKeep,
1322
+ CanvasStencilOperationKeep
1323
+ };
1324
+ // todo throw if failed
1325
+ v8::Local<v8::Value> formatValue;
1326
+
1327
+ stencilObj->Get(context, ConvertToV8String(isolate, "format")).ToLocal(&formatValue);
1328
+ if (!formatValue.IsEmpty() && formatValue->IsString()) {
1329
+ auto val = ConvertFromV8String(isolate, formatValue);
1330
+ auto format = canvas_native_webgpu_enum_string_to_gpu_texture(
1331
+ val.c_str());
1332
+ if (format.tag ==
1333
+ CanvasOptionalGPUTextureFormat_Tag::CanvasOptionalGPUTextureFormatSome) {
1334
+ stencil->format = format.some;
1335
+ }
1336
+ } else {
1337
+ // todo throw
1338
+ }
1339
+
1340
+ v8::Local<v8::Value> depthBiasVal;
1341
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBias")).ToLocal(&depthBiasVal);
1342
+
1343
+ if (!depthBiasVal.IsEmpty() && depthBiasVal->IsInt32()) {
1344
+ stencil->depth_bias = depthBiasVal->Int32Value(context).FromJust();
1345
+ }
1346
+
1347
+ v8::Local<v8::Value> depthBiasClampVal;
1348
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBiasClamp")).ToLocal(
1349
+ &depthBiasClampVal);
1350
+
1351
+ if (!depthBiasClampVal.IsEmpty() && depthBiasClampVal->IsNumber()) {
1352
+ stencil->depth_bias_clamp = (float) depthBiasClampVal->NumberValue(context).FromJust();
1353
+ }
1354
+
1355
+
1356
+ v8::Local<v8::Value> depthBiasSlopeScaleVal;
1357
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBiasSlopeScale")).ToLocal(
1358
+ &depthBiasSlopeScaleVal);
1359
+
1360
+ if (!depthBiasSlopeScaleVal.IsEmpty() && depthBiasSlopeScaleVal->IsNumber()) {
1361
+ stencil->depth_bias_slope_scale = (float) depthBiasSlopeScaleVal->NumberValue(
1362
+ context).FromJust();
1363
+ }
1364
+
1365
+ v8::Local<v8::Value> depthCompareVal;
1366
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthCompare")).ToLocal(
1367
+ &depthCompareVal);
1368
+
1369
+ auto depthCompareStr = ConvertFromV8String(isolate, depthCompareVal);
1370
+
1371
+ if (depthCompareStr == "never") {
1372
+ stencil->depth_compare = CanvasCompareFunctionNever;
1373
+ } else if (depthCompareStr == "less") {
1374
+ stencil->depth_compare = CanvasCompareFunctionLess;
1375
+ } else if (depthCompareStr == "equal") {
1376
+ stencil->depth_compare = CanvasCompareFunctionEqual;
1377
+ } else if (depthCompareStr == "less-equal") {
1378
+ stencil->depth_compare = CanvasCompareFunctionLessEqual;
1379
+ } else if (depthCompareStr == "greater") {
1380
+ stencil->depth_compare = CanvasCompareFunctionGreater;
1381
+ } else if (depthCompareStr == "not-equal") {
1382
+ stencil->depth_compare = CanvasCompareFunctionNotEqual;
1383
+ } else if (depthCompareStr == "greater-equal") {
1384
+ stencil->depth_compare = CanvasCompareFunctionGreaterEqual;
1385
+ } else if (depthCompareStr == "always") {
1386
+ stencil->depth_compare = CanvasCompareFunctionAlways;
1387
+ }
1388
+
1389
+ stencil->depth_write_enabled = stencilObj->Get(context, ConvertToV8String(isolate,
1390
+ "depthWriteEnabled")).ToLocalChecked()->BooleanValue(
1391
+ isolate);
1392
+
1393
+
1394
+ v8::Local<v8::Value> stencilBackVal;
1395
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilBack")).ToLocal(
1396
+ &stencilBackVal);
1397
+
1398
+ if (!stencilBackVal.IsEmpty() && stencilBackVal->IsObject()) {
1399
+ auto stencilBackObj = stencilBackVal.As<v8::Object>();
1400
+
1401
+ v8::Local<v8::Value> compareVal;
1402
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(
1403
+ &compareVal);
1404
+
1405
+ stencil->stencil_back.compare = ParseCompareFunction(isolate, compareVal,
1406
+ stencil->stencil_back.compare);
1407
+
1408
+ v8::Local<v8::Value> depthFailOpVal;
1409
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "depthFailOp")).ToLocal(
1410
+ &depthFailOpVal);
1411
+
1412
+ stencil->stencil_back.depth_fail_op = ParseStencilOperation(isolate, depthFailOpVal,
1413
+ stencil->stencil_back.depth_fail_op);
1414
+
1415
+
1416
+ v8::Local<v8::Value> failOpVal;
1417
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "failOp")).ToLocal(
1418
+ &failOpVal);
1419
+
1420
+ stencil->stencil_back.fail_op = ParseStencilOperation(isolate, failOpVal,
1421
+ stencil->stencil_back.fail_op);
1422
+
1423
+ v8::Local<v8::Value> passOpVal;
1424
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "passOp")).ToLocal(
1425
+ &passOpVal);
1426
+
1427
+ stencil->stencil_back.pass_op = ParseStencilOperation(isolate, passOpVal,
1428
+ stencil->stencil_back.pass_op);
1429
+
1430
+ }
1431
+
1432
+
1433
+ v8::Local<v8::Value> stencilFrontVal;
1434
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilFront")).ToLocal(
1435
+ &stencilFrontVal);
1436
+
1437
+ if (!stencilFrontVal.IsEmpty() && stencilFrontVal->IsObject()) {
1438
+ auto stencilFrontObj = stencilFrontVal.As<v8::Object>();
1439
+
1440
+ v8::Local<v8::Value> compareVal;
1441
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(
1442
+ &compareVal);
1443
+
1444
+ stencil->stencil_front.compare = ParseCompareFunction(isolate, compareVal,
1445
+ stencil->stencil_front.compare);
1446
+
1447
+ v8::Local<v8::Value> depthFailOpVal;
1448
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "depthFailOp")).ToLocal(
1449
+ &depthFailOpVal);
1450
+
1451
+ stencil->stencil_front.depth_fail_op = ParseStencilOperation(isolate, depthFailOpVal,
1452
+ stencil->stencil_front.depth_fail_op);
1453
+
1454
+
1455
+ v8::Local<v8::Value> failOpVal;
1456
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "failOp")).ToLocal(
1457
+ &failOpVal);
1458
+
1459
+ stencil->stencil_front.fail_op = ParseStencilOperation(isolate, failOpVal,
1460
+ stencil->stencil_front.fail_op);
1461
+
1462
+ v8::Local<v8::Value> passOpVal;
1463
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "passOp")).ToLocal(
1464
+ &passOpVal);
1465
+
1466
+ stencil->stencil_front.pass_op = ParseStencilOperation(isolate, passOpVal,
1467
+ stencil->stencil_front.pass_op);
1468
+
1469
+ }
1470
+
1471
+ v8::Local<v8::Value> stencilReadMaskVal;
1472
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilReadMask")).ToLocal(
1473
+ &stencilReadMaskVal);
1474
+
1475
+ if (!stencilReadMaskVal.IsEmpty() && stencilReadMaskVal->IsUint32()) {
1476
+ stencil->stencil_read_mask = stencilReadMaskVal->Uint32Value(context).FromJust();
1477
+ }
1478
+
1479
+
1480
+ v8::Local<v8::Value> stencilWriteMaskVal;
1481
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilWriteMask")).ToLocal(
1482
+ &stencilWriteMaskVal);
1483
+
1484
+ if (!stencilWriteMaskVal.IsEmpty() && stencilWriteMaskVal->IsUint32()) {
1485
+ stencil->stencil_write_mask = stencilWriteMaskVal->Uint32Value(context).FromJust();
1486
+ }
1487
+
1488
+ descriptor.depth_stencil = stencil;
1489
+
1490
+ }
1491
+
1492
+
1493
+ v8::Local<v8::Value> fragmentValue;
1494
+ options->Get(context, ConvertToV8String(isolate, "fragment")).ToLocal(
1495
+ &fragmentValue);
1496
+
1497
+ CanvasFragmentState *fragment = nullptr;
1498
+
1499
+ std::vector<CanvasColorTargetState> targets;
1500
+
1501
+ if (!fragmentValue.IsEmpty() && fragmentValue->IsObject()) {
1502
+ auto fragmentValueObj = fragmentValue.As<v8::Object>();
1503
+ fragment = new CanvasFragmentState{};
1504
+
1505
+ v8::Local<v8::Value> targetsVal;
1506
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "targets")).ToLocal(&targetsVal);
1507
+
1508
+
1509
+ auto targetsArray = targetsVal.As<v8::Array>();
1510
+ auto len = targetsArray->Length();
1511
+
1512
+ for (int i = 0; i < len; i++) {
1513
+ auto state = targetsArray->Get(context, i).ToLocalChecked().As<v8::Object>();
1514
+
1515
+ auto formatVal = state->Get(context,
1516
+ ConvertToV8String(isolate, "format")).ToLocalChecked();
1517
+ auto formatStr = ConvertFromV8String(isolate, formatVal);
1518
+ auto formatResult = canvas_native_webgpu_enum_string_to_gpu_texture(formatStr.c_str());
1519
+
1520
+
1521
+ if (formatResult.tag == CanvasOptionalGPUTextureFormatNone) {
1522
+ // todo throw
1523
+ args.GetReturnValue().SetUndefined();
1524
+ return;
1525
+ } else {}
1526
+
1527
+ auto format = CanvasGPUTextureFormat{
1528
+ formatResult.some.tag
1529
+ };
1530
+
1531
+ uint32_t writeMask = 0xF;
1532
+
1533
+ v8::Local<v8::Value> writeMaskVal;
1534
+
1535
+ state->Get(context, ConvertToV8String(isolate, "writeMask")).ToLocal(&writeMaskVal);
1536
+
1537
+ if (!writeMaskVal.IsEmpty() && writeMaskVal->IsUint32()) {
1538
+ writeMask = writeMaskVal->Uint32Value(context).FromJust();
1539
+ }
1540
+
1541
+ CanvasOptionalBlendState blend{
1542
+ CanvasOptionalBlendStateNone
1543
+ };
1544
+
1545
+ v8::Local<v8::Value> blendVal;
1546
+
1547
+ state->Get(context, ConvertToV8String(isolate, "blend")).ToLocal(&blendVal);
1548
+
1549
+ if (!blendVal.IsEmpty() && blendVal->IsObject()) {
1550
+ auto blendObj = blendVal.As<v8::Object>();
1551
+ auto alpha = blendObj->Get(context, ConvertToV8String(isolate,
1552
+ "alpha")).ToLocalChecked().As<v8::Object>();
1553
+
1554
+ v8::Local<v8::Value> alphaSrcFactorVal;
1555
+
1556
+ alpha->Get(context,
1557
+ ConvertToV8String(isolate,
1558
+ "srcFactor")).ToLocal(&alphaSrcFactorVal);
1559
+
1560
+ auto alphaSrcFactor = ParseBlendFactor(isolate, alphaSrcFactorVal,
1561
+ CanvasBlendFactorZero);
1562
+
1563
+ v8::Local<v8::Value> alphaDstFactorVal;
1564
+ alpha->Get(context,
1565
+ ConvertToV8String(isolate,
1566
+ "dstFactor")).ToLocal(&alphaDstFactorVal);
1567
+
1568
+ auto alphaDstFactor = ParseBlendFactor(isolate, alphaDstFactorVal,
1569
+ CanvasBlendFactorZero);
1570
+
1571
+ v8::Local<v8::Value> alphaOperationVal;
1572
+
1573
+ alpha->Get(context,
1574
+ ConvertToV8String(isolate,
1575
+ "operation")).ToLocal(&alphaOperationVal);
1576
+
1577
+ auto alphaOperation = ParseBlendOperation(isolate, alphaOperationVal,
1578
+ CanvasBlendOperationAdd);
1579
+
1580
+ auto alpha_val = CanvasBlendComponent{alphaSrcFactor, alphaDstFactor,
1581
+ alphaOperation};
1582
+
1583
+ auto color = blendObj->Get(context, ConvertToV8String(isolate,
1584
+ "color")).ToLocalChecked().As<v8::Object>();
1585
+
1586
+
1587
+ v8::Local<v8::Value> colorSrcFactorVal;
1588
+
1589
+ color->Get(context,
1590
+ ConvertToV8String(isolate,
1591
+ "srcFactor")).ToLocal(&colorSrcFactorVal);
1592
+
1593
+ auto colorSrcFactor = ParseBlendFactor(isolate, colorSrcFactorVal,
1594
+ CanvasBlendFactorZero);
1595
+
1596
+ v8::Local<v8::Value> colorDstFactorVal;
1597
+ color->Get(context,
1598
+ ConvertToV8String(isolate,
1599
+ "dstFactor")).ToLocal(&colorDstFactorVal);
1600
+
1601
+ auto colorDstFactor = ParseBlendFactor(isolate, colorDstFactorVal,
1602
+ CanvasBlendFactorZero);
1603
+
1604
+ v8::Local<v8::Value> colorOperationVal;
1605
+
1606
+ color->Get(context,
1607
+ ConvertToV8String(isolate,
1608
+ "operation")).ToLocal(&colorOperationVal);
1609
+
1610
+ auto colorOperation = ParseBlendOperation(isolate, colorOperationVal,
1611
+ CanvasBlendOperationAdd);
1612
+
1613
+
1614
+ auto color_val = CanvasBlendComponent{colorSrcFactor, colorDstFactor,
1615
+ colorOperation};
1616
+
1617
+
1618
+ blend = CanvasOptionalBlendState{
1619
+ CanvasOptionalBlendStateSome,
1620
+ CanvasBlendState{
1621
+ color_val, alpha_val
1622
+ }
1623
+ };
1624
+ }
1625
+
1626
+ auto targetState = CanvasColorTargetState{
1627
+ format,
1628
+ blend,
1629
+ writeMask
1630
+ };
1631
+
1632
+ targets.push_back(targetState);
1633
+ }
1634
+
1635
+ if (!targets.empty()) {
1636
+ fragment->targets = targets.data();
1637
+ fragment->targets_size = targets.size();
1638
+ }
1639
+
1640
+ v8::Local<v8::Value> constantsVal;
1641
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(
1642
+ &constantsVal);
1643
+
1644
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
1645
+ auto constants = constantsVal.As<v8::Map>();
1646
+ auto keyValues = constants->AsArray();
1647
+ auto length = keyValues->Length();
1648
+ CanvasConstants *store = nullptr;
1649
+
1650
+ if (length > 0) {
1651
+ store = canvas_native_webgpu_constants_create();
1652
+ for (int i = 0; i < length; i += 2) {
1653
+ auto k = i;
1654
+ auto v = k + 1;
1655
+
1656
+ v8::Local<v8::Value> keyVal;
1657
+ keyValues->Get(context, k).ToLocal(&keyVal);
1658
+ v8::Local<v8::Value> valueVal;
1659
+ keyValues->Get(context, v).ToLocal(&valueVal);
1660
+
1661
+
1662
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
1663
+ valueVal->IsNumber()) {
1664
+ canvas_native_webgpu_constants_insert(
1665
+ store,
1666
+ *v8::String::Utf8Value(isolate, keyVal),
1667
+ valueVal.As<v8::Number>()->Value()
1668
+ );
1669
+ }
1670
+
1671
+ }
1672
+ }
1673
+ fragment->constants = store;
1674
+ }
1675
+
1676
+
1677
+ v8::Local<v8::Value> entryPoint;
1678
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(
1679
+ &entryPoint);
1680
+
1681
+
1682
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
1683
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
1684
+ char *entry_point = (char *) malloc(ep.length());
1685
+ std::strcpy(entry_point, *ep);
1686
+
1687
+ fragment->entry_point = entry_point;
1688
+ }
1689
+
1690
+
1691
+ v8::Local<v8::Value> moduleVal;
1692
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
1693
+
1694
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
1695
+
1696
+ fragment->module = module->GetShaderModule();
1697
+
1698
+ descriptor.fragment = fragment;
1699
+
1700
+ }
1701
+
1702
+
1703
+ v8::Local<v8::Value> labelVal;
1704
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(
1705
+ &labelVal);
1706
+
1707
+
1708
+ auto label = GPULabel(isolate, labelVal);
1709
+
1710
+
1711
+ descriptor.label = *label;
1712
+
1713
+
1714
+ v8::Local<v8::Value> layoutVal;
1715
+ options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(
1716
+ &layoutVal);
1717
+
1718
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout;
1719
+
1720
+ if (layoutVal->IsString()) {
1721
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1722
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
1723
+ };
1724
+ } else if (!layoutVal->IsNullOrUndefined() && layoutVal->IsObject()) {
1725
+ auto pipeline = GPUPipelineLayoutImpl::GetPointer(layoutVal.As<v8::Object>());
1726
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1727
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeLayout,
1728
+ layout.layout = pipeline->GetPipeline()
1729
+ };
1730
+ } else {
1731
+ // todo throw ?
1732
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1733
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
1734
+ };
1735
+ }
1736
+
1737
+ descriptor.layout = layout;
1738
+
1739
+
1740
+ v8::Local<v8::Value> multisampleValue;
1741
+ options->Get(context, ConvertToV8String(isolate, "multisample")).ToLocal(
1742
+ &multisampleValue);
1743
+
1744
+
1745
+ CanvasMultisampleState *multisample = nullptr;
1746
+
1747
+ if (!multisampleValue.IsEmpty() && multisampleValue->IsObject()) {
1748
+ auto multisampleObj = multisampleValue.As<v8::Object>();
1749
+ multisample = new CanvasMultisampleState{};
1750
+ multisample->alpha_to_coverage_enabled = false;
1751
+ multisample->count = 1;
1752
+ multisample->mask = 0xFFFFFFFF;
1753
+
1754
+ v8::Local<v8::Value> alphaToCoverageEnabled;
1755
+ v8::Local<v8::Value> count;
1756
+ v8::Local<v8::Value> mask;
1757
+
1758
+ multisampleObj->Get(context, ConvertToV8String(isolate, "alphaToCoverageEnabled")).
1759
+ ToLocal(&alphaToCoverageEnabled);
1760
+
1761
+ if (!alphaToCoverageEnabled.IsEmpty() && alphaToCoverageEnabled->IsBoolean()) {
1762
+ multisample->alpha_to_coverage_enabled = alphaToCoverageEnabled->BooleanValue(
1763
+ isolate);
1764
+ }
1765
+
1766
+ multisampleObj->Get(context, ConvertToV8String(isolate, "count")).
1767
+ ToLocal(&count);
1768
+
1769
+ if (!count.IsEmpty() && count->IsUint32()) {
1770
+ multisample->count = count.As<v8::Uint32>()->Value();
1771
+ }
1772
+
1773
+ multisampleObj->Get(context, ConvertToV8String(isolate, "mask")).
1774
+ ToLocal(&mask);
1775
+
1776
+ if (!mask.IsEmpty() && mask->IsNumber()) {
1777
+ // todo verify mask
1778
+ auto maskValue = mask.As<v8::Number>()->Value();
1779
+ multisample->mask = (uint64_t) maskValue;
1780
+ }
1781
+
1782
+
1783
+ descriptor.multisample = multisample;
1784
+
1785
+ }
1786
+
1787
+
1788
+ v8::Local<v8::Value> primitiveValue;
1789
+ options->Get(context, ConvertToV8String(isolate, "primitive")).ToLocal(
1790
+ &primitiveValue);
1791
+
1792
+
1793
+ CanvasPrimitiveState *primitive = nullptr;
1794
+
1795
+ if (!primitiveValue.IsEmpty() && primitiveValue->IsObject()) {
1796
+ auto primitiveObj = primitiveValue.As<v8::Object>();
1797
+ primitive = new CanvasPrimitiveState{};
1798
+
1799
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1800
+ primitive->front_face = CanvasFrontFaceCcw;
1801
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1802
+ CanvasOptionalIndexFormatNone
1803
+ };
1804
+
1805
+ primitive->topology = CanvasPrimitiveTopologyTriangleList;
1806
+
1807
+ primitive->unclipped_depth = false;
1808
+
1809
+
1810
+ v8::Local<v8::Value> cullModeValue;
1811
+
1812
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "cullMode")).ToLocal(
1813
+ &cullModeValue)) {
1814
+ if (cullModeValue->IsUint32()) {
1815
+ auto cullMode = cullModeValue.As<v8::Uint32>()->Value();
1816
+
1817
+ switch (cullMode) {
1818
+ case 0:
1819
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1820
+ break;
1821
+ case 1:
1822
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeFront;
1823
+ break;
1824
+ case 2:
1825
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeBack;
1826
+ break;
1827
+ default:
1828
+ break;
1829
+ }
1830
+ } else if (cullModeValue->IsString()) {
1831
+
1832
+ auto cullMode = ConvertFromV8String(isolate, cullModeValue);
1833
+
1834
+ if (cullMode == "none") {
1835
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1836
+ } else if (cullMode == "front") {
1837
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeFront;
1838
+ } else if (cullMode == "back") {
1839
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeBack;
1840
+ }
1841
+ }
1842
+
1843
+ }
1844
+
1845
+ v8::Local<v8::Value> frontFaceValue;
1846
+
1847
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "frontFace")).ToLocal(
1848
+ &frontFaceValue)) {
1849
+ if (frontFaceValue->IsUint32()) {
1850
+ auto frontFace = frontFaceValue.As<v8::Uint32>()->Value();
1851
+ switch (frontFace) {
1852
+ case 0:
1853
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCcw;
1854
+ break;
1855
+ case 1:
1856
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCw;
1857
+ break;
1858
+ default:
1859
+ break;
1860
+ }
1861
+ } else if (frontFaceValue->IsString()) {
1862
+ auto frontFace = ConvertFromV8String(isolate, frontFaceValue);
1863
+ if (frontFace == "ccw") {
1864
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCcw;
1865
+ } else if (frontFace == "cw") {
1866
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCw;
1867
+ }
1868
+ }
1869
+ }
1870
+
1871
+
1872
+ v8::Local<v8::Value> stripIndexFormatValue;
1873
+
1874
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "stripIndexFormat")).ToLocal(
1875
+ &stripIndexFormatValue)) {
1876
+ if (stripIndexFormatValue->IsUint32()) {
1877
+ auto stripIndexFormat = stripIndexFormatValue.As<v8::Uint32>()->Value();
1878
+ switch (stripIndexFormat) {
1879
+ case 0:
1880
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1881
+ CanvasOptionalIndexFormatSome,
1882
+ CanvasIndexFormat::CanvasIndexFormatUint16
1883
+ };
1884
+ break;
1885
+ case 1:
1886
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1887
+ CanvasOptionalIndexFormatSome,
1888
+ CanvasIndexFormat::CanvasIndexFormatUint32
1889
+ };
1890
+ break;
1891
+ default:
1892
+ break;
1893
+ }
1894
+ } else if (stripIndexFormatValue->IsString()) {
1895
+ auto stripIndexFormat = ConvertFromV8String(isolate, stripIndexFormatValue);
1896
+
1897
+
1898
+ if (stripIndexFormat == "uint16") {
1899
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1900
+ CanvasOptionalIndexFormatSome,
1901
+ CanvasIndexFormat::CanvasIndexFormatUint16
1902
+ };
1903
+ } else if (stripIndexFormat == "uint32") {
1904
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1905
+ CanvasOptionalIndexFormatSome,
1906
+ CanvasIndexFormat::CanvasIndexFormatUint32
1907
+ };
1908
+ }
1909
+ }
1910
+ }
1911
+
1912
+
1913
+ v8::Local<v8::Value> topologyValue;
1914
+
1915
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "topology")).ToLocal(
1916
+ &topologyValue)) {
1917
+
1918
+ if (topologyValue->IsUint32()) {
1919
+ auto topology = topologyValue.As<v8::Uint32>()->Value();
1920
+ switch (topology) {
1921
+ case 0:
1922
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyPointList;
1923
+ break;
1924
+ case 1:
1925
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineList;
1926
+ break;
1927
+ case 2:
1928
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineStrip;
1929
+ break;
1930
+ case 3:
1931
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleList;
1932
+ break;
1933
+ case 4:
1934
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleStrip;
1935
+ break;
1936
+ default:
1937
+ break;
1938
+ }
1939
+ } else if (topologyValue->IsString()) {
1940
+ auto topology = ConvertFromV8String(isolate, topologyValue);
1941
+ if (topology == "line-list") {
1942
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineList;
1943
+ } else if (topology == "line-strip") {
1944
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineStrip;
1945
+ } else if (topology == "point-list") {
1946
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyPointList;
1947
+ } else if (topology == "triangle-list") {
1948
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleList;
1949
+ } else if (topology == "triangle-strip") {
1950
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleStrip;
1951
+ }
1952
+ }
1953
+
1954
+ }
1955
+
1956
+
1957
+ v8::Local<v8::Value> unclippedDepthValue;
1958
+ primitiveObj->Get(context, ConvertToV8String(isolate, "unclippedDepth")).ToLocal(
1959
+ &unclippedDepthValue);
1960
+
1961
+ if (!unclippedDepthValue.IsEmpty() && unclippedDepthValue->IsBoolean()) {
1962
+ primitive->unclipped_depth = unclippedDepthValue->BooleanValue(isolate);
1963
+ }
1964
+
1965
+ descriptor.primitive = primitive;
1966
+
1967
+ }
1968
+
1969
+
1970
+ v8::Local<v8::Value> vertexValue;
1971
+ options->Get(context, ConvertToV8String(isolate, "vertex")).ToLocal(
1972
+ &vertexValue);
1973
+
1974
+
1975
+ CanvasVertexState *vertex = nullptr;
1976
+
1977
+ std::vector<CanvasVertexBufferLayout> bufferLayout;
1978
+
1979
+ std::vector<std::vector<CanvasVertexAttribute>> attributes;
1980
+
1981
+ if (!vertexValue.IsEmpty() && vertexValue->IsObject()) {
1982
+ auto vertexObj = vertexValue.As<v8::Object>();
1983
+ vertex = new CanvasVertexState{};
1984
+
1985
+ v8::Local<v8::Value> moduleVal;
1986
+ vertexObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
1987
+
1988
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
1989
+
1990
+ vertex->module = module->GetShaderModule();
1991
+
1992
+ v8::Local<v8::Value> constantsVal;
1993
+ vertexObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(&constantsVal);
1994
+
1995
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
1996
+ auto constants = constantsVal.As<v8::Map>();
1997
+ auto keyValues = constants->AsArray();
1998
+ auto len = keyValues->Length();
1999
+ CanvasConstants *store = nullptr;
2000
+
2001
+ if (len > 0) {
2002
+ store = canvas_native_webgpu_constants_create();
2003
+ for (int i = 0; i < len; i += 2) {
2004
+ auto k = i;
2005
+ auto v = k + 1;
2006
+
2007
+ v8::Local<v8::Value> keyVal;
2008
+ keyValues->Get(context, k).ToLocal(&keyVal);
2009
+ v8::Local<v8::Value> valueVal;
2010
+ keyValues->Get(context, v).ToLocal(&valueVal);
2011
+
2012
+
2013
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
2014
+ valueVal->IsNumber()) {
2015
+ canvas_native_webgpu_constants_insert(
2016
+ store,
2017
+ *v8::String::Utf8Value(isolate, keyVal),
2018
+ valueVal.As<v8::Number>()->Value()
2019
+ );
2020
+ }
2021
+
2022
+ }
2023
+ }
2024
+
2025
+ vertex->constants = store;
2026
+
2027
+ }
1207
2028
 
2029
+ v8::Local<v8::Value> buffersVal;
2030
+ vertexObj->Get(context, ConvertToV8String(isolate, "buffers")).ToLocal(&buffersVal);
1208
2031
 
1209
- args.GetReturnValue().SetUndefined();
1210
- }
2032
+ uint64_t stride = 0;
2033
+ if (!buffersVal.IsEmpty() && buffersVal->IsArray()) {
2034
+ auto buffers = buffersVal.As<v8::Array>();
2035
+ auto len = buffers->Length();
1211
2036
 
1212
- void GPUDeviceImpl::CreateQuerySet(const v8::FunctionCallbackInfo<v8::Value> &args) {
1213
- GPUDeviceImpl *ptr = GetPointer(args.This());
1214
- if (ptr == nullptr) {
1215
- return;
1216
- }
1217
- auto isolate = args.GetIsolate();
1218
- auto context = isolate->GetCurrentContext();
2037
+ for (int i = 0; i < len; i++) {
2038
+ auto buffer = buffers->Get(context, i).ToLocalChecked().As<v8::Object>();
1219
2039
 
1220
- auto optionsVal = args[0];
2040
+ v8::Local<v8::Value> arrayStride;
1221
2041
 
1222
- if (!optionsVal->IsObject()) {
1223
- // should error at this point
1224
- return;
1225
- }
1226
- auto options = optionsVal.As<v8::Object>();
2042
+ buffer->Get(context, ConvertToV8String(isolate, "arrayStride")).ToLocal(
2043
+ &arrayStride);
1227
2044
 
1228
- v8::Local<v8::Value> labelVal;
1229
- options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
2045
+ if (!arrayStride.IsEmpty() && arrayStride->IsNumber()) {
2046
+ stride = (uint64_t) arrayStride.As<v8::Number>()->Value();
2047
+ }
1230
2048
 
1231
- char *label = nullptr;
2049
+ std::vector<CanvasVertexAttribute> attributes_;
1232
2050
 
1233
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
1234
- label = *v8::String::Utf8Value(isolate, labelVal);
1235
- }
2051
+ v8::Local<v8::Value> attributesValue;
1236
2052
 
1237
- v8::Local<v8::Value> typeVal;
1238
- options->Get(context, ConvertToV8String(isolate, "type")).ToLocal(&labelVal);
2053
+ buffer->Get(context, ConvertToV8String(isolate, "attributes")).ToLocal(
2054
+ &attributesValue);
1239
2055
 
2056
+ if (!attributesValue.IsEmpty() && attributesValue->IsArray()) {
2057
+ auto attributes_array = attributesValue.As<v8::Array>();
2058
+ auto attributes_len = attributes_array->Length();
1240
2059
 
1241
- v8::Local<v8::Value> countVal;
1242
- options->Get(context, ConvertToV8String(isolate, "count")).ToLocal(&labelVal);
2060
+ for (int j = 0; j < attributes_len; j++) {
2061
+ auto attr = attributes_array->Get(context,
2062
+ j).ToLocalChecked().As<v8::Object>();
2063
+ auto format = attr->Get(context, ConvertToV8String(isolate,
2064
+ "format")).ToLocalChecked()->Uint32Value(
2065
+ context).ToChecked();
1243
2066
 
1244
- auto typeStr = ConvertFromV8String(isolate, typeVal);
2067
+ auto offset = (uint64_t) attr->Get(context, ConvertToV8String(isolate,
2068
+ "offset")).ToLocalChecked()->NumberValue(
2069
+ context).ToChecked();
2070
+ auto shaderLocation = attr->Get(context, ConvertToV8String(isolate,
2071
+ "shaderLocation")).ToLocalChecked()->Uint32Value(
2072
+ context).ToChecked();
1245
2073
 
1246
- const CanvasGPUQuerySet *query_set = nullptr;
1247
- if (typeStr == "occlusion") {
1248
- query_set = canvas_native_webgpu_device_create_query_set(ptr->GetGPUDevice(), label,
1249
- CanvasQueryTypeOcclusion,
1250
- countVal->Uint32Value(
1251
- context).FromJust());
1252
- } else if (typeStr == "timestamp") {
1253
- query_set = canvas_native_webgpu_device_create_query_set(ptr->GetGPUDevice(), label,
1254
- CanvasQueryTypeTimestamp,
1255
- countVal->Uint32Value(
1256
- context).FromJust());
1257
- } else {
1258
- // todo throw
1259
- }
2074
+ auto attribute = CanvasVertexAttribute{
2075
+ (CanvasVertexFormat) format,
2076
+ offset,
2077
+ shaderLocation
2078
+ };
1260
2079
 
2080
+ attributes_.push_back(attribute);
2081
+ }
1261
2082
 
1262
- if (query_set != nullptr) {
1263
- auto ret = GPUQuerySetImpl::NewInstance(isolate, new GPUQuerySetImpl(query_set));
1264
- args.GetReturnValue().Set(ret);
1265
- return;
1266
- }
2083
+ attributes.push_back(attributes_);
2084
+ }
1267
2085
 
1268
- args.GetReturnValue().SetUndefined();
1269
2086
 
1270
- }
2087
+ CanvasVertexStepMode stepMode = CanvasVertexStepModeVertex;
1271
2088
 
1272
- void GPUDeviceImpl::CreateRenderBundleEncoder(const v8::FunctionCallbackInfo<v8::Value> &args) {
1273
- GPUDeviceImpl *ptr = GetPointer(args.This());
1274
- if (ptr == nullptr) {
1275
- return;
1276
- }
1277
- auto isolate = args.GetIsolate();
1278
- auto context = isolate->GetCurrentContext();
2089
+ v8::Local<v8::Value> stepModeVal;
1279
2090
 
1280
- auto optionsVal = args[0];
2091
+ buffer->Get(context, ConvertToV8String(isolate, "stepMode")).ToLocal(
2092
+ &stepModeVal);
1281
2093
 
1282
- if (!optionsVal->IsObject()) {
1283
- // should error at this point
1284
- return;
1285
- }
1286
- auto options = optionsVal.As<v8::Object>();
1287
2094
 
1288
- v8::Local<v8::Value> labelVal;
1289
- options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
2095
+ if (!stepModeVal.IsEmpty()) {
2096
+ if (stepModeVal->IsUint32()) {
2097
+ switch (stepModeVal.As<v8::Uint32>()->Value()) {
2098
+ case 0:
2099
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeVertex;
2100
+ break;
2101
+ case 1:
2102
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeInstance;
2103
+ break;
2104
+ }
2105
+ } else if (stepModeVal->IsString()) {
2106
+ auto stepModeStr = ConvertFromV8String(isolate, stepModeVal);
2107
+ if (stepModeStr == "vertex") {
2108
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeVertex;
2109
+ } else if (stepModeStr == "instance") {
2110
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeInstance;
2111
+ }
2112
+ }
2113
+ }
2114
+
2115
+ auto vertexBufferLayout = CanvasVertexBufferLayout{
2116
+ stride,
2117
+ stepMode,
2118
+ attributes[i].data(),
2119
+ attributes[i].size()
2120
+ };
1290
2121
 
1291
- char *label = nullptr;
2122
+ bufferLayout.push_back(vertexBufferLayout);
2123
+ }
1292
2124
 
1293
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
1294
- label = *v8::String::Utf8Value(isolate, labelVal);
1295
- }
2125
+ vertex->buffers = bufferLayout.data();
2126
+ vertex->buffers_size = bufferLayout.size();
1296
2127
 
2128
+ }
1297
2129
 
1298
- std::vector<CanvasGPUTextureFormat> colorFormats;
1299
2130
 
1300
- v8::Local<v8::Value> colorFormatsVal;
1301
- options->Get(context, ConvertToV8String(isolate, "colorFormats")).ToLocal(&colorFormatsVal);
2131
+ v8::Local<v8::Value> entryPoint;
2132
+ vertexObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(&entryPoint);
1302
2133
 
1303
- if (!colorFormatsVal.IsEmpty() && colorFormatsVal->IsArray()) {
1304
- auto colorFormatsArray = colorFormatsVal.As<v8::Array>();
1305
- auto len = colorFormatsArray->Length();
1306
- for (int i = 0; i < len; i++) {
1307
- v8::Local<v8::Value> formatVal;
1308
- colorFormatsArray->Get(context, i).ToLocal(&formatVal);
1309
- if (!formatVal.IsEmpty() && formatVal->IsString()) {
1310
- auto formatStr = ConvertFromV8String(isolate, formatVal);
1311
- auto format = canvas_native_webgpu_enum_string_to_gpu_texture(formatStr.c_str());
1312
- if (format.tag == CanvasOptionalGPUTextureFormatSome) {
1313
- colorFormats.push_back(format.some);
1314
- }
1315
- }
1316
2134
 
2135
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
2136
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
2137
+ char *entry_point = (char *) malloc(ep.length());
2138
+ std::strcpy(entry_point, *ep);
2139
+ vertex->entry_point = entry_point;
1317
2140
  }
2141
+
2142
+ descriptor.vertex = vertex;
2143
+
1318
2144
  }
1319
2145
 
1320
2146
 
1321
- auto depthStencilFormat = CanvasOptionalGPUTextureFormat{
1322
- CanvasOptionalGPUTextureFormatNone
1323
- };
2147
+ auto pipeline = canvas_native_webgpu_device_create_render_pipeline(ptr->GetGPUDevice(),
2148
+ &descriptor);
1324
2149
 
1325
- v8::Local<v8::Value> depthStencilFormatVal;
1326
- options->Get(context, ConvertToV8String(isolate, "depthStencilFormat")).ToLocal(
1327
- &depthStencilFormatVal);
1328
2150
 
1329
- if (!depthStencilFormatVal.IsEmpty() && depthStencilFormatVal->IsString()) {
1330
- auto depthStencilFormatStr = ConvertFromV8String(isolate, depthStencilFormatVal);
1331
- depthStencilFormat = canvas_native_webgpu_enum_string_to_gpu_texture(
1332
- depthStencilFormatStr.c_str());
2151
+ if (descriptor.fragment != nullptr) {
2152
+ if (descriptor.fragment->entry_point != nullptr) {
2153
+ free((void *) descriptor.fragment->entry_point);
2154
+ }
1333
2155
  }
1334
2156
 
1335
- uint32_t sampleCount = 1;
2157
+ if (descriptor.primitive != nullptr) {
2158
+ delete descriptor.primitive;
2159
+ descriptor.primitive = nullptr;
2160
+ }
1336
2161
 
1337
- bool depthReadOnly = false;
2162
+ if (descriptor.multisample != nullptr) {
2163
+ delete descriptor.multisample;
2164
+ descriptor.multisample = nullptr;
2165
+ }
1338
2166
 
1339
- bool stencilReadOnly = false;
1340
2167
 
1341
- CanvasCreateRenderBundleEncoderDescriptor descriptor{
1342
- label,
1343
- colorFormats.data(),
1344
- colorFormats.size(),
1345
- depthStencilFormat,
1346
- sampleCount,
1347
- depthReadOnly,
1348
- stencilReadOnly
1349
- };
2168
+ if (descriptor.vertex != nullptr) {
2169
+ if (descriptor.vertex->constants != nullptr) {
2170
+ canvas_native_webgpu_constants_destroy(
2171
+ (CanvasConstants *) descriptor.vertex->constants);
2172
+ }
1350
2173
 
2174
+ if (descriptor.vertex->entry_point != nullptr) {
2175
+ free((void *) descriptor.vertex->entry_point);
2176
+ }
1351
2177
 
1352
- auto encoder = canvas_native_webgpu_device_create_render_bundle_encoder(ptr->GetGPUDevice(),
1353
- &descriptor);
2178
+ }
1354
2179
 
1355
- if (encoder != nullptr) {
1356
- auto ret = GPURenderBundleEncoderImpl::NewInstance(isolate,
1357
- new GPURenderBundleEncoderImpl(encoder));
2180
+ if (descriptor.depth_stencil != nullptr) {
2181
+ delete descriptor.depth_stencil;
2182
+ descriptor.depth_stencil = nullptr;
2183
+ }
2184
+
2185
+
2186
+ if (pipeline != nullptr) {
2187
+ auto ret = GPURenderPipelineImpl::NewInstance(isolate, new GPURenderPipelineImpl(pipeline));
1358
2188
  args.GetReturnValue().Set(ret);
1359
2189
  return;
1360
2190
  }
@@ -1362,7 +2192,7 @@ void GPUDeviceImpl::CreateRenderBundleEncoder(const v8::FunctionCallbackInfo<v8:
1362
2192
  args.GetReturnValue().SetUndefined();
1363
2193
  }
1364
2194
 
1365
- void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Value> &args) {
2195
+ void GPUDeviceImpl::CreateRenderPipelineAsync(const v8::FunctionCallbackInfo<v8::Value> &args) {
1366
2196
  GPUDeviceImpl *ptr = GetPointer(args.This());
1367
2197
  if (ptr == nullptr) {
1368
2198
  return;
@@ -1374,13 +2204,14 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
1374
2204
  descriptor.label = nullptr;
1375
2205
 
1376
2206
  auto optionsVal = args[0];
2207
+ auto callback = args[1];
1377
2208
 
1378
2209
  if (!optionsVal->IsObject()) {
1379
2210
  // should error at this point
1380
2211
  return;
1381
2212
  }
1382
2213
  auto options = optionsVal.As<v8::Object>();
1383
-
2214
+ GPULabel label;
1384
2215
 
1385
2216
  v8::Local<v8::Value> stencilValue;
1386
2217
  options->Get(context, ConvertToV8String(isolate, "depthStencil")).ToLocal(
@@ -1437,7 +2268,7 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
1437
2268
  &depthBiasClampVal);
1438
2269
 
1439
2270
  if (!depthBiasClampVal.IsEmpty() && depthBiasClampVal->IsNumber()) {
1440
- stencil->depth_bias_clamp = (float)depthBiasClampVal->NumberValue(context).FromJust();
2271
+ stencil->depth_bias_clamp = (float) depthBiasClampVal->NumberValue(context).FromJust();
1441
2272
  }
1442
2273
 
1443
2274
 
@@ -1446,7 +2277,7 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
1446
2277
  &depthBiasSlopeScaleVal);
1447
2278
 
1448
2279
  if (!depthBiasSlopeScaleVal.IsEmpty() && depthBiasSlopeScaleVal->IsNumber()) {
1449
- stencil->depth_bias_slope_scale = (float)depthBiasSlopeScaleVal->NumberValue(
2280
+ stencil->depth_bias_slope_scale = (float) depthBiasSlopeScaleVal->NumberValue(
1450
2281
  context).FromJust();
1451
2282
  }
1452
2283
 
@@ -1792,10 +2623,10 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
1792
2623
  options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(
1793
2624
  &labelVal);
1794
2625
 
2626
+ label = GPULabel(isolate, labelVal);
2627
+
2628
+ descriptor.label = *label;
1795
2629
 
1796
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
1797
- descriptor.label = *v8::String::Utf8Value(isolate, labelVal);
1798
- }
1799
2630
 
1800
2631
 
1801
2632
  v8::Local<v8::Value> layoutVal;
@@ -1897,7 +2728,7 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
1897
2728
  v8::Local<v8::Value> cullModeValue;
1898
2729
 
1899
2730
  if (primitiveObj->Get(context, ConvertToV8String(isolate, "cullMode")).ToLocal(
1900
- &cullModeValue)) {
2731
+ &cullModeValue)) {
1901
2732
  if (cullModeValue->IsUint32()) {
1902
2733
  auto cullMode = cullModeValue.As<v8::Uint32>()->Value();
1903
2734
 
@@ -1932,7 +2763,7 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
1932
2763
  v8::Local<v8::Value> frontFaceValue;
1933
2764
 
1934
2765
  if (primitiveObj->Get(context, ConvertToV8String(isolate, "frontFace")).ToLocal(
1935
- &frontFaceValue)) {
2766
+ &frontFaceValue)) {
1936
2767
  if (frontFaceValue->IsUint32()) {
1937
2768
  auto frontFace = frontFaceValue.As<v8::Uint32>()->Value();
1938
2769
  switch (frontFace) {
@@ -1959,7 +2790,7 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
1959
2790
  v8::Local<v8::Value> stripIndexFormatValue;
1960
2791
 
1961
2792
  if (primitiveObj->Get(context, ConvertToV8String(isolate, "stripIndexFormat")).ToLocal(
1962
- &stripIndexFormatValue)) {
2793
+ &stripIndexFormatValue)) {
1963
2794
  if (stripIndexFormatValue->IsUint32()) {
1964
2795
  auto stripIndexFormat = stripIndexFormatValue.As<v8::Uint32>()->Value();
1965
2796
  switch (stripIndexFormat) {
@@ -2000,7 +2831,7 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
2000
2831
  v8::Local<v8::Value> topologyValue;
2001
2832
 
2002
2833
  if (primitiveObj->Get(context, ConvertToV8String(isolate, "topology")).ToLocal(
2003
- &topologyValue)) {
2834
+ &topologyValue)) {
2004
2835
 
2005
2836
  if (topologyValue->IsUint32()) {
2006
2837
  auto topology = topologyValue.As<v8::Uint32>()->Value();
@@ -2230,50 +3061,176 @@ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Valu
2230
3061
 
2231
3062
  }
2232
3063
 
3064
+ auto async_callback = new AsyncCallback(isolate, callback.As<v8::Function>(),
3065
+ [](bool success, void *data) {
3066
+ if (data != nullptr) {
3067
+ auto async_data = static_cast<AsyncCallback *>(data);
3068
+ auto func = async_data->inner_.get();
3069
+ if (func != nullptr &&
3070
+ func->isolate_ != nullptr) {
3071
+ v8::Isolate *isolate = func->isolate_;
3072
+ v8::Locker locker(isolate);
3073
+ v8::Isolate::Scope isolate_scope(
3074
+ isolate);
3075
+ v8::HandleScope handle_scope(isolate);
3076
+ v8::Local<v8::Function> callback = func->callback_.Get(
3077
+ isolate);
3078
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
3079
+ v8::Context::Scope context_scope(
3080
+ context);
3081
+
3082
+ RenderPipeLineAsyncData *pipelineData = nullptr;
3083
+ if (func->data != nullptr) {
3084
+ pipelineData = static_cast<RenderPipeLineAsyncData *>(func->data);
3085
+ }
3086
+
3087
+ if (pipelineData == nullptr) {
3088
+ // Should never happen
3089
+ auto error = v8::Object::New(isolate);
3090
+ error->Set(context,
3091
+ ConvertToV8String(isolate,
3092
+ "error"),
3093
+ v8::Exception::Error(
3094
+ ConvertToV8String(
3095
+ isolate,
3096
+ "Internal Error")));
3097
+ error->Set(context, ConvertToV8String(
3098
+ isolate,
3099
+ "type"),
3100
+ v8::Uint32::NewFromUnsigned(
3101
+ isolate,
3102
+ (uint32_t) CanvasGPUErrorType::CanvasGPUErrorTypeInternal));
3103
+
3104
+ v8::Local<v8::Value> args[1] = {error};
3105
+
3106
+ callback->Call(context,
3107
+ context->Global(),
3108
+ 1,
3109
+ args); // ignore JS return value
3110
+ delete static_cast<AsyncCallback *>(data);
3111
+
3112
+ return;
3113
+ }
3114
+
3115
+ if (pipelineData->type !=
3116
+ CanvasGPUErrorType::CanvasGPUErrorTypeNone) {
3117
+
3118
+
3119
+ auto error = v8::Object::New(isolate);
3120
+ error->Set(context,
3121
+ ConvertToV8String(isolate,
3122
+ "error"),
3123
+ v8::Exception::Error(
3124
+ ConvertToV8String(
3125
+ isolate,
3126
+ pipelineData->errorMessage)));
3127
+ error->Set(context, ConvertToV8String(
3128
+ isolate,
3129
+ "type"),
3130
+ v8::Uint32::NewFromUnsigned(
3131
+ isolate,
3132
+ (uint32_t) pipelineData->type));
3133
+
3134
+ v8::Local<v8::Value> args[1] = {error};
3135
+
3136
+ callback->Call(context,
3137
+ context->Global(),
3138
+ 1,
3139
+ args); // ignore JS return value
3140
+ } else {
3141
+
3142
+ auto ret = GPURenderPipelineImpl::NewInstance(
3143
+ isolate,
3144
+ new GPURenderPipelineImpl(
3145
+ pipelineData->pipeline));
3146
+
3147
+ v8::Local<v8::Value> args[2] = {
3148
+ v8::Null(isolate), ret};
3149
+
3150
+
3151
+ callback->Call(context,
3152
+ context->Global(),
3153
+ 2,
3154
+ args); // ignore JS return value
3155
+ }
3156
+
3157
+ if (pipelineData != nullptr) {
3158
+ delete pipelineData;
3159
+ pipelineData = nullptr;
3160
+ }
3161
+
3162
+ delete static_cast<AsyncCallback *>(data);
3163
+ }
3164
+ }
3165
+ });
3166
+
3167
+ auto data = new RenderPipeLineAsyncData{
3168
+ nullptr,
3169
+ nullptr,
3170
+ nullptr,
3171
+ nullptr,
3172
+ CanvasGPUErrorType::CanvasGPUErrorTypeNone,
3173
+ nullptr,
3174
+ nullptr,
3175
+ nullptr,
3176
+ nullptr,
3177
+ nullptr,
3178
+ nullptr
3179
+ };
2233
3180
 
2234
- auto pipeline = canvas_native_webgpu_device_create_render_pipeline(ptr->GetGPUDevice(),
2235
- &descriptor);
2236
-
2237
-
2238
- if (descriptor.fragment != nullptr) {
2239
- if (descriptor.fragment->entry_point != nullptr) {
2240
- free((void *) descriptor.fragment->entry_point);
3181
+ if (fragment != nullptr) {
3182
+ if (fragment->entry_point != nullptr) {
3183
+ data->fragment_entry_point = (char *) fragment->entry_point;
2241
3184
  }
2242
3185
  }
2243
3186
 
2244
- if (descriptor.primitive != nullptr) {
2245
- delete descriptor.primitive;
3187
+ if (primitive != nullptr) {
3188
+ data->primitive = primitive;
2246
3189
  }
2247
3190
 
2248
- if (descriptor.multisample != nullptr) {
2249
- delete descriptor.multisample;
3191
+ if (multisample != nullptr) {
3192
+ data->multisample = multisample;
2250
3193
  }
2251
3194
 
2252
-
2253
- if (descriptor.vertex != nullptr) {
2254
- if (descriptor.vertex->constants != nullptr) {
2255
- canvas_native_webgpu_constants_destroy(
2256
- (CanvasConstants *) descriptor.vertex->constants);
3195
+ if (vertex != nullptr) {
3196
+ if (vertex->constants != nullptr) {
3197
+ data->vertex_constants = (CanvasConstants *) vertex->constants;
2257
3198
  }
2258
3199
 
2259
- if (descriptor.vertex->entry_point != nullptr) {
2260
- free((void *) descriptor.vertex->entry_point);
3200
+ if (vertex->entry_point != nullptr) {
3201
+ data->vertex_entry_point = (char *) descriptor.vertex->entry_point;
2261
3202
  }
2262
3203
 
2263
3204
  }
2264
3205
 
2265
- if(descriptor.depth_stencil != nullptr){
3206
+ if (stencil != nullptr) {
2266
3207
  delete descriptor.depth_stencil;
3208
+ data->depth_stencil = stencil;
2267
3209
  }
2268
3210
 
2269
-
2270
- if (pipeline != nullptr) {
2271
- auto ret = GPURenderPipelineImpl::NewInstance(isolate, new GPURenderPipelineImpl(pipeline));
2272
- args.GetReturnValue().Set(ret);
2273
- return;
2274
- }
2275
-
2276
- args.GetReturnValue().SetUndefined();
3211
+ async_callback->inner_->data = data;
3212
+
3213
+ async_callback->prepare();
3214
+
3215
+ canvas_native_webgpu_device_create_render_pipeline_async(ptr->GetGPUDevice(),
3216
+ &descriptor, [](
3217
+ const struct CanvasGPURenderPipeline *pipeline,
3218
+ enum CanvasGPUErrorType type,
3219
+ char *message,
3220
+ void *data) {
3221
+ if (data != nullptr) {
3222
+ auto async_data = static_cast<AsyncCallback *>(data);
3223
+ auto inner = async_data->inner_.get();
3224
+ if (inner != nullptr) {
3225
+ auto pipeline_data = static_cast<RenderPipeLineAsyncData *>(inner->data);
3226
+ pipeline_data->errorMessage = message;
3227
+ pipeline_data->type = type;
3228
+ pipeline_data->pipeline = pipeline;
3229
+ async_data->execute(
3230
+ true);
3231
+ }
3232
+ }
3233
+ }, async_callback);
2277
3234
  }
2278
3235
 
2279
3236
  void GPUDeviceImpl::CreateSampler(const v8::FunctionCallbackInfo<v8::Value> &args) {
@@ -2293,11 +3250,7 @@ void GPUDeviceImpl::CreateSampler(const v8::FunctionCallbackInfo<v8::Value> &arg
2293
3250
  v8::Local<v8::Value> labelVal;
2294
3251
  options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
2295
3252
 
2296
- char *label = nullptr;
2297
-
2298
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
2299
- label = *v8::String::Utf8Value(isolate, labelVal);
2300
- }
3253
+ GPULabel label(isolate, labelVal);
2301
3254
 
2302
3255
  auto addressModeU = CanvasAddressModeClampToEdge;
2303
3256
 
@@ -2427,12 +3380,12 @@ void GPUDeviceImpl::CreateSampler(const v8::FunctionCallbackInfo<v8::Value> &arg
2427
3380
  &maxAnisotropyVal);
2428
3381
 
2429
3382
  if (!maxAnisotropyVal.IsEmpty() && maxAnisotropyVal->IsNumber()) {
2430
- maxAnisotropy = (u_short) maxAnisotropyVal->NumberValue(context).FromJust();
3383
+ maxAnisotropy = (uint16_t) maxAnisotropyVal->NumberValue(context).FromJust();
2431
3384
  }
2432
3385
 
2433
3386
 
2434
3387
  CanvasCreateSamplerDescriptor descriptor{
2435
- label,
3388
+ *label,
2436
3389
  addressModeU,
2437
3390
  addressModeV,
2438
3391
  addressModeW,
@@ -2483,20 +3436,18 @@ void GPUDeviceImpl::CreateShaderModule(const v8::FunctionCallbackInfo<v8::Value>
2483
3436
  v8::Local<v8::Value> labelVal;
2484
3437
  desc->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
2485
3438
 
2486
- char *label = nullptr;
2487
-
2488
- if (!labelVal.IsEmpty() && labelVal->IsString()) {
2489
- label = *v8::String::Utf8Value(isolate, labelVal);
2490
- }
3439
+ GPULabel label(isolate, labelVal);
2491
3440
 
2492
3441
  v8::Local<v8::Value> codeVal;
2493
3442
 
2494
3443
  std::string code;
2495
- if (desc->Get(context, ConvertToV8String(isolate, "code")).ToLocal(&codeVal) && codeVal->IsString()) {
3444
+ if (desc->Get(context, ConvertToV8String(isolate, "code")).ToLocal(&codeVal) &&
3445
+ codeVal->IsString()) {
2496
3446
  code = ConvertFromV8String(isolate, codeVal);
2497
3447
  }
2498
3448
 
2499
- auto module = canvas_native_webgpu_device_create_shader_module(ptr->GetGPUDevice(), label,
3449
+ auto module = canvas_native_webgpu_device_create_shader_module(ptr->GetGPUDevice(),
3450
+ *label,
2500
3451
  code.c_str());
2501
3452
 
2502
3453
  if (module != nullptr) {
@@ -2541,15 +3492,15 @@ void GPUDeviceImpl::CreateTexture(const v8::FunctionCallbackInfo<v8::Value> &arg
2541
3492
  v8::Local<v8::Value> depthOrArrayLayersVal;
2542
3493
 
2543
3494
  if (options->Get(context, ConvertToV8String(isolate, "depthOrArrayLayers")).ToLocal(
2544
- &depthOrArrayLayersVal) && depthOrArrayLayersVal->IsUint32()) {
3495
+ &depthOrArrayLayersVal) && depthOrArrayLayersVal->IsUint32()) {
2545
3496
  descriptor.depthOrArrayLayers = depthOrArrayLayersVal.As<v8::Uint32>()->Value();
2546
3497
  }
2547
3498
 
2548
3499
 
2549
3500
  v8::Local<v8::Value> widthVal;
2550
3501
 
2551
- if ( options->Get(context, ConvertToV8String(isolate, "width")).ToLocal(
2552
- &widthVal) &&widthVal->IsUint32()) {
3502
+ if (options->Get(context, ConvertToV8String(isolate, "width")).ToLocal(
3503
+ &widthVal) && widthVal->IsUint32()) {
2553
3504
  descriptor.width = widthVal.As<v8::Uint32>()->Value();
2554
3505
  }
2555
3506
 
@@ -2557,7 +3508,7 @@ void GPUDeviceImpl::CreateTexture(const v8::FunctionCallbackInfo<v8::Value> &arg
2557
3508
  v8::Local<v8::Value> heightVal;
2558
3509
 
2559
3510
  if (options->Get(context, ConvertToV8String(isolate, "height")).ToLocal(
2560
- &heightVal) && heightVal->IsUint32()) {
3511
+ &heightVal) && heightVal->IsUint32()) {
2561
3512
  descriptor.height = heightVal.As<v8::Uint32>()->Value();
2562
3513
  }
2563
3514
 
@@ -2565,7 +3516,7 @@ void GPUDeviceImpl::CreateTexture(const v8::FunctionCallbackInfo<v8::Value> &arg
2565
3516
  v8::Local<v8::Value> usageVal;
2566
3517
 
2567
3518
  if (options->Get(context, ConvertToV8String(isolate, "usage")).ToLocal(
2568
- &usageVal) && usageVal->IsUint32()) {
3519
+ &usageVal) && usageVal->IsUint32()) {
2569
3520
  descriptor.usage = usageVal.As<v8::Uint32>()->Value();
2570
3521
  }
2571
3522
 
@@ -2594,7 +3545,6 @@ void GPUDeviceImpl::CreateTexture(const v8::FunctionCallbackInfo<v8::Value> &arg
2594
3545
 
2595
3546
  if (dimensionVal->IsString()) {
2596
3547
  auto dimension = ConvertFromV8String(isolate, dimensionVal);
2597
-
2598
3548
  // todo use enum
2599
3549
  if (dimension == "1d") {
2600
3550
  descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD1;
@@ -2610,7 +3560,7 @@ void GPUDeviceImpl::CreateTexture(const v8::FunctionCallbackInfo<v8::Value> &arg
2610
3560
  v8::Local<v8::Value> formatVal;
2611
3561
 
2612
3562
  if (options->Get(context, ConvertToV8String(isolate, "format")).ToLocal(
2613
- &formatVal) && formatVal->IsString()) {
3563
+ &formatVal) && formatVal->IsString()) {
2614
3564
  auto format = ConvertFromV8String(isolate, formatVal);
2615
3565
 
2616
3566
  // todo use enum