@nativescript/canvas 2.0.0-webgpu.0 → 2.0.0-webgpu.10

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