@nativescript/canvas 2.0.0-beta.9 → 2.0.0-webgpu.1

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 (288) hide show
  1. package/Canvas/common.d.ts +24 -17
  2. package/Canvas/common.js +133 -66
  3. package/Canvas/common.js.map +1 -1
  4. package/Canvas/index.android.d.ts +5 -7
  5. package/Canvas/index.android.js +62 -133
  6. package/Canvas/index.android.js.map +1 -1
  7. package/Canvas/index.d.ts +4 -1
  8. package/Canvas/index.ios.d.ts +4 -5
  9. package/Canvas/index.ios.js +73 -82
  10. package/Canvas/index.ios.js.map +1 -1
  11. package/Canvas2D/CanvasRenderingContext2D/index.d.ts +1 -1
  12. package/Canvas2D/CanvasRenderingContext2D/index.js +8 -11
  13. package/Canvas2D/CanvasRenderingContext2D/index.js.map +1 -1
  14. package/Canvas2D/DOMMatrix/index.d.ts +14 -0
  15. package/Canvas2D/DOMMatrix/index.js +62 -0
  16. package/Canvas2D/DOMMatrix/index.js.map +1 -1
  17. package/Canvas2D/ImageData/index.js +4 -6
  18. package/Canvas2D/ImageData/index.js.map +1 -1
  19. package/ImageAsset/index.d.ts +1 -0
  20. package/ImageAsset/index.js +49 -0
  21. package/ImageAsset/index.js.map +1 -1
  22. package/WebGL/WebGLRenderingContext/index.d.ts +1 -0
  23. package/WebGL/WebGLRenderingContext/index.js +86 -32
  24. package/WebGL/WebGLRenderingContext/index.js.map +1 -1
  25. package/WebGL2/WebGL2RenderingContext/index.d.ts +1 -0
  26. package/WebGL2/WebGL2RenderingContext/index.js +2 -3
  27. package/WebGL2/WebGL2RenderingContext/index.js.map +1 -1
  28. package/WebGPU/Constants.d.ts +36 -0
  29. package/WebGPU/Constants.js +42 -0
  30. package/WebGPU/Constants.js.map +1 -0
  31. package/WebGPU/Errors.d.ts +18 -0
  32. package/WebGPU/Errors.js +21 -0
  33. package/WebGPU/Errors.js.map +1 -0
  34. package/WebGPU/GPU.d.ts +13 -0
  35. package/WebGPU/GPU.js +35 -0
  36. package/WebGPU/GPU.js.map +1 -0
  37. package/WebGPU/GPUAdapter.d.ts +23 -0
  38. package/WebGPU/GPUAdapter.js +62 -0
  39. package/WebGPU/GPUAdapter.js.map +1 -0
  40. package/WebGPU/GPUAdapterInfo.d.ts +9 -0
  41. package/WebGPU/GPUAdapterInfo.js +24 -0
  42. package/WebGPU/GPUAdapterInfo.js.map +1 -0
  43. package/WebGPU/GPUBindGroup.d.ts +5 -0
  44. package/WebGPU/GPUBindGroup.js +12 -0
  45. package/WebGPU/GPUBindGroup.js.map +1 -0
  46. package/WebGPU/GPUBindGroupLayout.d.ts +5 -0
  47. package/WebGPU/GPUBindGroupLayout.js +12 -0
  48. package/WebGPU/GPUBindGroupLayout.js.map +1 -0
  49. package/WebGPU/GPUBuffer.d.ts +15 -0
  50. package/WebGPU/GPUBuffer.js +54 -0
  51. package/WebGPU/GPUBuffer.js.map +1 -0
  52. package/WebGPU/GPUCanvasContext.d.ts +35 -0
  53. package/WebGPU/GPUCanvasContext.js +76 -0
  54. package/WebGPU/GPUCanvasContext.js.map +1 -0
  55. package/WebGPU/GPUCommandBuffer.d.ts +5 -0
  56. package/WebGPU/GPUCommandBuffer.js +12 -0
  57. package/WebGPU/GPUCommandBuffer.js.map +1 -0
  58. package/WebGPU/GPUCommandEncoder.d.ts +41 -0
  59. package/WebGPU/GPUCommandEncoder.js +110 -0
  60. package/WebGPU/GPUCommandEncoder.js.map +1 -0
  61. package/WebGPU/GPUComputePassEncoder.d.ts +16 -0
  62. package/WebGPU/GPUComputePassEncoder.js +50 -0
  63. package/WebGPU/GPUComputePassEncoder.js.map +1 -0
  64. package/WebGPU/GPUComputePipeline.d.ts +7 -0
  65. package/WebGPU/GPUComputePipeline.js +16 -0
  66. package/WebGPU/GPUComputePipeline.js.map +1 -0
  67. package/WebGPU/GPUDevice.d.ts +173 -0
  68. package/WebGPU/GPUDevice.js +356 -0
  69. package/WebGPU/GPUDevice.js.map +1 -0
  70. package/WebGPU/GPUDeviceLostInfo.d.ts +1 -0
  71. package/WebGPU/GPUDeviceLostInfo.js +10 -0
  72. package/WebGPU/GPUDeviceLostInfo.js.map +1 -0
  73. package/WebGPU/GPUExternalTexture.d.ts +5 -0
  74. package/WebGPU/GPUExternalTexture.js +12 -0
  75. package/WebGPU/GPUExternalTexture.js.map +1 -0
  76. package/WebGPU/GPUPipelineLayout.d.ts +5 -0
  77. package/WebGPU/GPUPipelineLayout.js +12 -0
  78. package/WebGPU/GPUPipelineLayout.js.map +1 -0
  79. package/WebGPU/GPUQuerySet.d.ts +5 -0
  80. package/WebGPU/GPUQuerySet.js +12 -0
  81. package/WebGPU/GPUQuerySet.js.map +1 -0
  82. package/WebGPU/GPUQueue.d.ts +14 -0
  83. package/WebGPU/GPUQueue.js +77 -0
  84. package/WebGPU/GPUQueue.js.map +1 -0
  85. package/WebGPU/GPURenderBundle.d.ts +5 -0
  86. package/WebGPU/GPURenderBundle.js +12 -0
  87. package/WebGPU/GPURenderBundle.js.map +1 -0
  88. package/WebGPU/GPURenderBundleEncoder.d.ts +20 -0
  89. package/WebGPU/GPURenderBundleEncoder.js +61 -0
  90. package/WebGPU/GPURenderBundleEncoder.js.map +1 -0
  91. package/WebGPU/GPURenderPassEncoder.d.ts +29 -0
  92. package/WebGPU/GPURenderPassEncoder.js +94 -0
  93. package/WebGPU/GPURenderPassEncoder.js.map +1 -0
  94. package/WebGPU/GPURenderPipeline.d.ts +7 -0
  95. package/WebGPU/GPURenderPipeline.js +16 -0
  96. package/WebGPU/GPURenderPipeline.js.map +1 -0
  97. package/WebGPU/GPUSampler.d.ts +5 -0
  98. package/WebGPU/GPUSampler.js +12 -0
  99. package/WebGPU/GPUSampler.js.map +1 -0
  100. package/WebGPU/GPUShaderModule.d.ts +6 -0
  101. package/WebGPU/GPUShaderModule.js +15 -0
  102. package/WebGPU/GPUShaderModule.js.map +1 -0
  103. package/WebGPU/GPUTexture.d.ts +17 -0
  104. package/WebGPU/GPUTexture.js +44 -0
  105. package/WebGPU/GPUTexture.js.map +1 -0
  106. package/WebGPU/GPUTextureView.d.ts +5 -0
  107. package/WebGPU/GPUTextureView.js +12 -0
  108. package/WebGPU/GPUTextureView.js.map +1 -0
  109. package/WebGPU/Interfaces.d.ts +155 -0
  110. package/WebGPU/Interfaces.js +2 -0
  111. package/WebGPU/Interfaces.js.map +1 -0
  112. package/WebGPU/Types.d.ts +39 -0
  113. package/WebGPU/Types.js +2 -0
  114. package/WebGPU/Types.js.map +1 -0
  115. package/WebGPU/Utils.d.ts +1 -0
  116. package/WebGPU/Utils.js +75 -0
  117. package/WebGPU/Utils.js.map +1 -0
  118. package/WebGPU/index.d.ts +28 -0
  119. package/WebGPU/index.js +29 -0
  120. package/WebGPU/index.js.map +1 -0
  121. package/common.d.ts +0 -3
  122. package/common.js +1 -5
  123. package/common.js.map +1 -1
  124. package/index.d.ts +1 -1
  125. package/index.js +22 -1
  126. package/index.js.map +1 -1
  127. package/package.json +1 -4
  128. package/platforms/android/canvas-release.aar +0 -0
  129. package/platforms/ios/CanvasNative.xcframework/Info.plist +5 -5
  130. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/CanvasNative +0 -0
  131. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/CanvasNative-Swift.h +23 -23
  132. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/canvas_ios.h +41 -8
  133. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/canvas_native.h +2318 -103
  134. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Info.plist +0 -0
  135. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
  136. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.abi.json +1563 -3729
  137. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.private.swiftinterface +27 -34
  138. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  139. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.swiftinterface +27 -34
  140. package/platforms/ios/CanvasNative.xcframework/ios-arm64/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/DWARF/CanvasNative +0 -0
  141. package/platforms/ios/CanvasNative.xcframework/ios-arm64/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/aarch64/CanvasNative.yml +602 -663
  142. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/CanvasNative +0 -0
  143. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/CanvasNative-Swift.h +46 -46
  144. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/canvas_ios.h +41 -8
  145. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/canvas_native.h +2318 -103
  146. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Info.plist +0 -0
  147. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
  148. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo +0 -0
  149. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.abi.json +1563 -3729
  150. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +27 -34
  151. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  152. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.swiftinterface +27 -34
  153. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.abi.json +1563 -3729
  154. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +27 -34
  155. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  156. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +27 -34
  157. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/_CodeSignature/CodeResources +31 -31
  158. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/DWARF/CanvasNative +0 -0
  159. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/aarch64/CanvasNative.yml +604 -662
  160. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/x86_64/CanvasNative.yml +638 -641
  161. package/platforms/ios/build.xcconfig +3 -1
  162. package/platforms/ios/src/cpp/Caches.h +69 -1
  163. package/platforms/ios/src/cpp/CanvasJSIModule.cpp +320 -395
  164. package/platforms/ios/src/cpp/CanvasJSIModule.h +7 -1
  165. package/platforms/ios/src/cpp/Helpers.h +43 -8
  166. package/platforms/ios/src/cpp/ImageAssetImpl.cpp +35 -37
  167. package/platforms/ios/src/cpp/ImageAssetImpl.h +14 -10
  168. package/platforms/ios/src/cpp/ImageBitmapImpl.cpp +2 -2
  169. package/platforms/ios/src/cpp/ImageBitmapImpl.h +1 -1
  170. package/platforms/ios/src/cpp/canvas2d/CanvasPattern.cpp +0 -10
  171. package/platforms/ios/src/cpp/canvas2d/CanvasRenderingContext2DImpl.cpp +41 -4
  172. package/platforms/ios/src/cpp/canvas2d/MatrixImpl.cpp +409 -3
  173. package/platforms/ios/src/cpp/canvas2d/MatrixImpl.h +27 -0
  174. package/platforms/ios/src/cpp/webgl/WebGLRenderingContext.cpp +131 -149
  175. package/platforms/ios/src/cpp/webgl2/WebGL2RenderingContext.cpp +1766 -1659
  176. package/platforms/ios/src/cpp/webgpu/GPUAdapterImpl.cpp +302 -0
  177. package/platforms/ios/src/cpp/webgpu/GPUAdapterImpl.h +63 -0
  178. package/platforms/ios/src/cpp/webgpu/GPUAdapterInfoImpl.cpp +174 -0
  179. package/platforms/ios/src/cpp/webgpu/GPUAdapterInfoImpl.h +58 -0
  180. package/platforms/ios/src/cpp/webgpu/GPUBindGroupImpl.cpp +53 -0
  181. package/platforms/ios/src/cpp/webgpu/GPUBindGroupImpl.h +45 -0
  182. package/platforms/ios/src/cpp/webgpu/GPUBindGroupLayoutImpl.cpp +53 -0
  183. package/platforms/ios/src/cpp/webgpu/GPUBindGroupLayoutImpl.h +45 -0
  184. package/platforms/ios/src/cpp/webgpu/GPUBufferImpl.cpp +229 -0
  185. package/platforms/ios/src/cpp/webgpu/GPUBufferImpl.h +59 -0
  186. package/platforms/ios/src/cpp/webgpu/GPUCanvasContextImpl.cpp +317 -0
  187. package/platforms/ios/src/cpp/webgpu/GPUCanvasContextImpl.h +55 -0
  188. package/platforms/ios/src/cpp/webgpu/GPUCommandBufferImpl.cpp +54 -0
  189. package/platforms/ios/src/cpp/webgpu/GPUCommandBufferImpl.h +45 -0
  190. package/platforms/ios/src/cpp/webgpu/GPUCommandEncoderImpl.cpp +1222 -0
  191. package/platforms/ios/src/cpp/webgpu/GPUCommandEncoderImpl.h +69 -0
  192. package/platforms/ios/src/cpp/webgpu/GPUComputePassEncoderImpl.cpp +260 -0
  193. package/platforms/ios/src/cpp/webgpu/GPUComputePassEncoderImpl.h +62 -0
  194. package/platforms/ios/src/cpp/webgpu/GPUComputePipelineImpl.cpp +84 -0
  195. package/platforms/ios/src/cpp/webgpu/GPUComputePipelineImpl.h +49 -0
  196. package/platforms/ios/src/cpp/webgpu/GPUDeviceImpl.cpp +2750 -0
  197. package/platforms/ios/src/cpp/webgpu/GPUDeviceImpl.h +95 -0
  198. package/platforms/ios/src/cpp/webgpu/GPUImpl.cpp +186 -0
  199. package/platforms/ios/src/cpp/webgpu/GPUImpl.h +55 -0
  200. package/platforms/ios/src/cpp/webgpu/GPUPipelineLayoutImpl.cpp +54 -0
  201. package/platforms/ios/src/cpp/webgpu/GPUPipelineLayoutImpl.h +46 -0
  202. package/platforms/ios/src/cpp/webgpu/GPUQuerySetImpl.cpp +137 -0
  203. package/platforms/ios/src/cpp/webgpu/GPUQuerySetImpl.h +55 -0
  204. package/platforms/ios/src/cpp/webgpu/GPUQueueImpl.cpp +521 -0
  205. package/platforms/ios/src/cpp/webgpu/GPUQueueImpl.h +56 -0
  206. package/platforms/ios/src/cpp/webgpu/GPURenderBundleEncoderImpl.cpp +469 -0
  207. package/platforms/ios/src/cpp/webgpu/GPURenderBundleEncoderImpl.h +71 -0
  208. package/platforms/ios/src/cpp/webgpu/GPURenderBundleImpl.cpp +53 -0
  209. package/platforms/ios/src/cpp/webgpu/GPURenderBundleImpl.h +45 -0
  210. package/platforms/ios/src/cpp/webgpu/GPURenderPassEncoderImpl.cpp +623 -0
  211. package/platforms/ios/src/cpp/webgpu/GPURenderPassEncoderImpl.h +85 -0
  212. package/platforms/ios/src/cpp/webgpu/GPURenderPipelineImpl.cpp +84 -0
  213. package/platforms/ios/src/cpp/webgpu/GPURenderPipelineImpl.h +49 -0
  214. package/platforms/ios/src/cpp/webgpu/GPUSamplerImpl.cpp +53 -0
  215. package/platforms/ios/src/cpp/webgpu/GPUSamplerImpl.h +45 -0
  216. package/platforms/ios/src/cpp/webgpu/GPUShaderModuleImpl.cpp +56 -0
  217. package/platforms/ios/src/cpp/webgpu/GPUShaderModuleImpl.h +45 -0
  218. package/platforms/ios/src/cpp/webgpu/GPUSupportedLimitsImpl.cpp +1304 -0
  219. package/platforms/ios/src/cpp/webgpu/GPUSupportedLimitsImpl.h +288 -0
  220. package/platforms/ios/src/cpp/webgpu/GPUTextureImpl.cpp +360 -0
  221. package/platforms/ios/src/cpp/webgpu/GPUTextureImpl.h +75 -0
  222. package/platforms/ios/src/cpp/webgpu/GPUTextureViewImpl.cpp +53 -0
  223. package/platforms/ios/src/cpp/webgpu/GPUTextureViewImpl.h +45 -0
  224. package/platforms/ios/src/cpp/webgpu/GPUUtils.h +245 -0
  225. package/SVG/Circle.d.ts +0 -11
  226. package/SVG/Circle.js +0 -21
  227. package/SVG/Circle.js.map +0 -1
  228. package/SVG/ClipPath.d.ts +0 -4
  229. package/SVG/ClipPath.js +0 -9
  230. package/SVG/ClipPath.js.map +0 -1
  231. package/SVG/Defs.d.ts +0 -4
  232. package/SVG/Defs.js +0 -9
  233. package/SVG/Defs.js.map +0 -1
  234. package/SVG/Ellipse.d.ts +0 -13
  235. package/SVG/Ellipse.js +0 -26
  236. package/SVG/Ellipse.js.map +0 -1
  237. package/SVG/G.d.ts +0 -7
  238. package/SVG/G.js +0 -9
  239. package/SVG/G.js.map +0 -1
  240. package/SVG/Image.d.ts +0 -11
  241. package/SVG/Image.js +0 -40
  242. package/SVG/Image.js.map +0 -1
  243. package/SVG/Line.d.ts +0 -13
  244. package/SVG/Line.js +0 -26
  245. package/SVG/Line.js.map +0 -1
  246. package/SVG/LinearGradient.d.ts +0 -10
  247. package/SVG/LinearGradient.js +0 -13
  248. package/SVG/LinearGradient.js.map +0 -1
  249. package/SVG/Path.d.ts +0 -7
  250. package/SVG/Path.js +0 -14
  251. package/SVG/Path.js.map +0 -1
  252. package/SVG/Pattern.d.ts +0 -4
  253. package/SVG/Pattern.js +0 -9
  254. package/SVG/Pattern.js.map +0 -1
  255. package/SVG/Polygon.d.ts +0 -7
  256. package/SVG/Polygon.js +0 -14
  257. package/SVG/Polygon.js.map +0 -1
  258. package/SVG/Polyline.d.ts +0 -7
  259. package/SVG/Polyline.js +0 -14
  260. package/SVG/Polyline.js.map +0 -1
  261. package/SVG/Rect.d.ts +0 -8
  262. package/SVG/Rect.js +0 -13
  263. package/SVG/Rect.js.map +0 -1
  264. package/SVG/SVG.d.ts +0 -32
  265. package/SVG/SVG.js +0 -204
  266. package/SVG/SVG.js.map +0 -1
  267. package/SVG/SVGItem.d.ts +0 -5
  268. package/SVG/SVGItem.js +0 -8
  269. package/SVG/SVGItem.js.map +0 -1
  270. package/SVG/Stop.d.ts +0 -5
  271. package/SVG/Stop.js +0 -9
  272. package/SVG/Stop.js.map +0 -1
  273. package/SVG/Symbol.d.ts +0 -4
  274. package/SVG/Symbol.js +0 -9
  275. package/SVG/Symbol.js.map +0 -1
  276. package/SVG/Text.d.ts +0 -14
  277. package/SVG/Text.js +0 -26
  278. package/SVG/Text.js.map +0 -1
  279. package/SVG/Use.d.ts +0 -4
  280. package/SVG/Use.js +0 -9
  281. package/SVG/Use.js.map +0 -1
  282. package/SVG/index.d.ts +0 -18
  283. package/SVG/index.js +0 -19
  284. package/SVG/index.js.map +0 -1
  285. package/platforms/ios/src/cpp/PerIsolateData.cpp +0 -49
  286. package/platforms/ios/src/cpp/PerIsolateData.h +0 -54
  287. package/platforms/ios/src/cpp/URLImpl.cpp +0 -464
  288. package/platforms/ios/src/cpp/URLImpl.h +0 -121
@@ -0,0 +1,2750 @@
1
+ //
2
+ // Created by Osei Fortune on 18/06/2024.
3
+ //
4
+
5
+ #include "GPUDeviceImpl.h"
6
+ #include "Caches.h"
7
+ #include "GPUAdapterImpl.h"
8
+ #include "GPUQueueImpl.h"
9
+ #include "GPUCommandEncoderImpl.h"
10
+ #include "GPUShaderModuleImpl.h"
11
+ #include "GPUPipelineLayoutImpl.h"
12
+ #include "GPURenderPipelineImpl.h"
13
+ #include "JSICallback.h"
14
+ #include "GPUBindGroupImpl.h"
15
+ #include "GPUBindGroupLayoutImpl.h"
16
+ #include "GPUSamplerImpl.h"
17
+ #include "GPUTextureViewImpl.h"
18
+ #include "GPUBufferImpl.h"
19
+ #include "GPUTextureImpl.h"
20
+ #include "GPUComputePipelineImpl.h"
21
+ #include "GPUQuerySetImpl.h"
22
+ #include "GPURenderBundleEncoderImpl.h"
23
+ #include "GPUUtils.h"
24
+
25
+ GPUDeviceImpl::GPUDeviceImpl(const CanvasGPUDevice *device) : device_(device) {}
26
+
27
+ const CanvasGPUDevice *GPUDeviceImpl::GetGPUDevice() {
28
+ return this->device_;
29
+ }
30
+
31
+
32
+ void GPUDeviceImpl::Init(v8::Local<v8::Object> canvasModule, v8::Isolate *isolate) {
33
+ v8::Locker locker(isolate);
34
+ v8::Isolate::Scope isolate_scope(isolate);
35
+ v8::HandleScope handle_scope(isolate);
36
+
37
+ auto ctor = GetCtor(isolate);
38
+ auto context = isolate->GetCurrentContext();
39
+ auto func = ctor->GetFunction(context).ToLocalChecked();
40
+
41
+ canvasModule->Set(context, ConvertToV8String(isolate, "GPUDevice"), func).FromJust();;
42
+ }
43
+
44
+ GPUDeviceImpl *GPUDeviceImpl::GetPointer(const v8::Local<v8::Object> &object) {
45
+ auto ptr = object->GetAlignedPointerFromInternalField(0);
46
+ if (ptr == nullptr) {
47
+ return nullptr;
48
+ }
49
+ return static_cast<GPUDeviceImpl *>(ptr);
50
+ }
51
+
52
+ v8::Local<v8::FunctionTemplate> GPUDeviceImpl::GetCtor(v8::Isolate *isolate) {
53
+ auto cache = Caches::Get(isolate);
54
+ auto ctor = cache->GPUDeviceTmpl.get();
55
+ if (ctor != nullptr) {
56
+ return ctor->Get(isolate);
57
+ }
58
+
59
+ v8::Local<v8::FunctionTemplate> ctorTmpl = v8::FunctionTemplate::New(isolate);
60
+ ctorTmpl->InstanceTemplate()->SetInternalFieldCount(2);
61
+ ctorTmpl->SetClassName(ConvertToV8String(isolate, "GPUDevice"));
62
+
63
+ auto tmpl = ctorTmpl->InstanceTemplate();
64
+ tmpl->SetInternalFieldCount(2);
65
+
66
+ tmpl->SetLazyDataProperty(
67
+ ConvertToV8String(isolate, "features"),
68
+ GetFeatures
69
+ );
70
+
71
+ tmpl->SetLazyDataProperty(
72
+ ConvertToV8String(isolate, "queue"),
73
+ GetQueue
74
+ );
75
+
76
+ tmpl->SetLazyDataProperty(
77
+ ConvertToV8String(isolate, "limits"),
78
+ GetLimits
79
+ );
80
+
81
+ tmpl->SetLazyDataProperty(
82
+ ConvertToV8String(isolate, "lost"),
83
+ GetLost
84
+ );
85
+
86
+ tmpl->Set(
87
+ ConvertToV8String(isolate, "createBindGroup"),
88
+ v8::FunctionTemplate::New(isolate, &CreateBindGroup));
89
+
90
+ tmpl->Set(
91
+ ConvertToV8String(isolate, "createBindGroupLayout"),
92
+ v8::FunctionTemplate::New(isolate, &CreateBindGroupLayout));
93
+
94
+ tmpl->Set(
95
+ ConvertToV8String(isolate, "createBuffer"),
96
+ v8::FunctionTemplate::New(isolate, &CreateBuffer));
97
+
98
+ tmpl->Set(
99
+ ConvertToV8String(isolate, "createCommandEncoder"),
100
+ v8::FunctionTemplate::New(isolate, &CreateCommandEncoder));
101
+
102
+ tmpl->Set(
103
+ ConvertToV8String(isolate, "createComputePipeline"),
104
+ v8::FunctionTemplate::New(isolate, &CreateComputePipeline));
105
+
106
+ tmpl->Set(
107
+ ConvertToV8String(isolate, "createPipelineLayout"),
108
+ v8::FunctionTemplate::New(isolate, &CreatePipelineLayout));
109
+
110
+ tmpl->Set(
111
+ ConvertToV8String(isolate, "createQuerySet"),
112
+ v8::FunctionTemplate::New(isolate, &CreateQuerySet));
113
+
114
+ tmpl->Set(
115
+ ConvertToV8String(isolate, "createRenderBundleEncoder"),
116
+ v8::FunctionTemplate::New(isolate, &CreateRenderBundleEncoder));
117
+
118
+ tmpl->Set(
119
+ ConvertToV8String(isolate, "createRenderPipeline"),
120
+ v8::FunctionTemplate::New(isolate, &CreateRenderPipeline));
121
+
122
+ tmpl->Set(
123
+ ConvertToV8String(isolate, "createSampler"),
124
+ v8::FunctionTemplate::New(isolate, &CreateSampler));
125
+
126
+ tmpl->Set(
127
+ ConvertToV8String(isolate, "createShaderModule"),
128
+ v8::FunctionTemplate::New(isolate, &CreateShaderModule));
129
+
130
+ tmpl->Set(
131
+ ConvertToV8String(isolate, "createTexture"),
132
+ v8::FunctionTemplate::New(isolate, &CreateTexture));
133
+
134
+ tmpl->Set(
135
+ ConvertToV8String(isolate, "destroy"),
136
+ v8::FunctionTemplate::New(isolate, &Destroy));
137
+
138
+ tmpl->Set(
139
+ ConvertToV8String(isolate, "popErrorScope"),
140
+ v8::FunctionTemplate::New(isolate, &PopErrorScope));
141
+
142
+ tmpl->Set(
143
+ ConvertToV8String(isolate, "pushErrorScope"),
144
+ v8::FunctionTemplate::New(isolate, &PushErrorScope));
145
+
146
+
147
+ tmpl->Set(
148
+ ConvertToV8String(isolate, "setuncapturederror"),
149
+ v8::FunctionTemplate::New(isolate, &SetUncapturedError));
150
+
151
+
152
+ cache->GPUDeviceTmpl =
153
+ std::make_unique<v8::Persistent<v8::FunctionTemplate>>(isolate, ctorTmpl);
154
+ return ctorTmpl;
155
+ }
156
+
157
+ void
158
+ GPUDeviceImpl::SetUncapturedError(const v8::FunctionCallbackInfo<v8::Value> &args) {
159
+ auto *ptr = GetPointer(args.This());
160
+ if (ptr == nullptr) {
161
+ return;
162
+ }
163
+ auto isolate = args.GetIsolate();
164
+ auto cb = args[0];
165
+ auto callback = new JSICallback(isolate, cb.As<v8::Function>());
166
+
167
+ canvas_native_webgpu_device_set_uncaptured_error_callback(ptr->GetGPUDevice(),
168
+ [](CanvasGPUErrorType type, char *msg,
169
+ void *data) {
170
+
171
+ auto cb = static_cast<JSICallback *>(data);
172
+
173
+ v8::Isolate *isolate = cb->isolate_;
174
+ v8::Locker locker(isolate);
175
+ v8::Isolate::Scope isolate_scope(
176
+ isolate);
177
+ v8::HandleScope handle_scope(
178
+ isolate);
179
+ v8::Local<v8::Function> callback = cb->callback_->Get(
180
+ isolate);
181
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
182
+ v8::Context::Scope context_scope(
183
+ context);
184
+ v8::Local<v8::Value> typ;
185
+ v8::Local<v8::Value> message;
186
+ switch (type) {
187
+ case CanvasGPUErrorType::CanvasGPUErrorTypeNone:
188
+ typ = v8::Number::New(
189
+ isolate, 0);
190
+ message = v8::Null(
191
+ isolate);
192
+ break;
193
+ case CanvasGPUErrorType::CanvasGPUErrorTypeLost:
194
+ typ = v8::Number::New(
195
+ isolate, 1);
196
+ message = v8::Null(
197
+ isolate);
198
+ break;
199
+ case CanvasGPUErrorType::CanvasGPUErrorTypeOutOfMemory:
200
+ typ = v8::Number::New(
201
+ isolate, 2);
202
+ message = v8::Null(
203
+ isolate);
204
+ break;
205
+ case CanvasGPUErrorType::CanvasGPUErrorTypeValidation:
206
+ typ = v8::Number::New(
207
+ isolate, 3);
208
+ message = ConvertToV8String(
209
+ isolate, msg);
210
+ break;
211
+ case CanvasGPUErrorType::CanvasGPUErrorTypeInternal:
212
+ typ = v8::Number::New(
213
+ isolate, 4);
214
+ message = v8::Null(
215
+ isolate);
216
+ break;
217
+ }
218
+ v8::Local<v8::Value> args[2] = {
219
+ typ, message
220
+ };
221
+
222
+ callback->Call(context,
223
+ context->Global(),
224
+ 2, args);
225
+
226
+ // todo clean up
227
+ // delete static_cast<JSICallback *>(data);
228
+
229
+ }, callback);
230
+
231
+
232
+ }
233
+
234
+
235
+ void
236
+ GPUDeviceImpl::GetFeatures(v8::Local<v8::Name> name,
237
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
238
+ auto ptr = GetPointer(info.This());
239
+ auto isolate = info.GetIsolate();
240
+ if (ptr != nullptr) {
241
+ auto context = isolate->GetCurrentContext();
242
+
243
+ auto features = canvas_native_webgpu_device_get_features(ptr->GetGPUDevice());
244
+
245
+ auto len = canvas_native_string_buffer_get_length(features);
246
+
247
+ auto map = v8::Map::New(isolate);
248
+ for (int i = 0; i < len; ++i) {
249
+ auto item = canvas_native_string_buffer_get_value_at(features, i);
250
+ if (item != nullptr) {
251
+ auto keyValue = ConvertToV8OneByteString(isolate, (char *) item);
252
+ map->Set(context, keyValue, keyValue);
253
+ canvas_native_string_destroy(item);
254
+ }
255
+
256
+ }
257
+ canvas_native_string_buffer_destroy(features);
258
+
259
+ info.GetReturnValue().Set(map);
260
+
261
+ return;
262
+ }
263
+
264
+ info.GetReturnValue().Set(v8::Map::New(info.GetIsolate()));
265
+ }
266
+
267
+
268
+ void
269
+ GPUDeviceImpl::GetLimits(v8::Local<v8::Name> name,
270
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
271
+ auto ptr = GetPointer(info.This());
272
+ if (ptr != nullptr) {
273
+ auto limits = canvas_native_webgpu_device_get_limits(ptr->GetGPUDevice());
274
+
275
+ auto ret = GPUSupportedLimitsImpl::NewInstance(info.GetIsolate(),
276
+ new GPUSupportedLimitsImpl(limits));
277
+ info.GetReturnValue().Set(ret);
278
+ return;
279
+ }
280
+ info.GetReturnValue().SetUndefined();
281
+ }
282
+
283
+
284
+ void
285
+ GPUDeviceImpl::GetQueue(v8::Local<v8::Name> name,
286
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
287
+ auto ptr = GetPointer(info.This());
288
+ if (ptr != nullptr) {
289
+ auto queue = canvas_native_webgpu_device_get_queue(ptr->GetGPUDevice());
290
+ auto ret = GPUQueueImpl::NewInstance(info.GetIsolate(),
291
+ new GPUQueueImpl(queue));
292
+ info.GetReturnValue().Set(ret);
293
+ return;
294
+ }
295
+ info.GetReturnValue().SetUndefined();
296
+ }
297
+
298
+
299
+ void
300
+ GPUDeviceImpl::GetLost(v8::Local<v8::Name> name,
301
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
302
+ auto ptr = GetPointer(info.This());
303
+ auto isolate = info.GetIsolate();
304
+ auto resolver = v8::Promise::Resolver::New(isolate->GetCurrentContext()).ToLocalChecked();
305
+ info.GetReturnValue().Set(resolver->GetPromise());
306
+ if (ptr != nullptr) {
307
+ v8::Global<v8::Promise::Resolver> promise(isolate, resolver);
308
+ auto callback = new PromiseCallback{
309
+ isolate,
310
+ std::move(promise)
311
+ };
312
+
313
+ canvas_native_webgpu_device_set_lost_callback(ptr->GetGPUDevice(),
314
+ [](int32_t reason, char *message,
315
+ void *data) {
316
+ 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);
362
+ }
363
+ }
364
+
365
+ }, callback);
366
+ }
367
+ }
368
+
369
+
370
+ void GPUDeviceImpl::CreateBindGroup(const v8::FunctionCallbackInfo<v8::Value> &args) {
371
+ GPUDeviceImpl *ptr = GetPointer(args.This());
372
+ if (ptr == nullptr) {
373
+ return;
374
+ }
375
+ auto isolate = args.GetIsolate();
376
+ auto context = isolate->GetCurrentContext();
377
+ char *label = nullptr;
378
+
379
+ auto optionsVal = args[0];
380
+
381
+ std::vector<CanvasBindGroupEntry> entries;
382
+
383
+ if (optionsVal->IsObject()) {
384
+ auto options = optionsVal.As<v8::Object>();
385
+ v8::Local<v8::Value> labelVal;
386
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
387
+
388
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
389
+ label = *v8::String::Utf8Value(isolate, labelVal);
390
+ }
391
+
392
+ const CanvasGPUBindGroupLayout *layout = nullptr;
393
+
394
+
395
+ v8::Local<v8::Value> layoutVal;
396
+ options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(&layoutVal);
397
+
398
+ if (!layoutVal.IsEmpty() && layoutVal->IsObject()) {
399
+ auto layoutObj = layoutVal.As<v8::Object>();
400
+ auto layoutImpl = GPUBindGroupLayoutImpl::GetPointer(layoutObj);
401
+ if (layoutImpl != nullptr) {
402
+ layout = layoutImpl->GetBindGroupLayout();
403
+ }
404
+ }
405
+
406
+
407
+ v8::Local<v8::Value> entriesVal;
408
+ options->Get(context, ConvertToV8String(isolate, "entries")).ToLocal(&entriesVal);
409
+
410
+ if (!entriesVal.IsEmpty() && entriesVal->IsArray()) {
411
+ auto entriesArray = entriesVal.As<v8::Array>();
412
+ auto len = entriesArray->Length();
413
+ for (int i = 0; i < len; i++) {
414
+ v8::Local<v8::Value> entryVal;
415
+ entriesArray->Get(context, i).ToLocal(&entryVal);
416
+ if (!entryVal.IsEmpty() && entryVal->IsObject()) {
417
+ auto entryObj = entryVal.As<v8::Object>();
418
+ auto binding = entryObj->Get(context, ConvertToV8String(isolate,
419
+ "binding")).ToLocalChecked()->Uint32Value(
420
+ context).FromJust();
421
+ v8::Local<v8::Value> resourceVal;
422
+ entryObj->Get(context, ConvertToV8String(isolate, "resource")).ToLocal(
423
+ &resourceVal);
424
+
425
+ auto resourceType = GetNativeType(resourceVal);
426
+ switch (resourceType) {
427
+ case NativeType::GPUSampler: {
428
+ auto sampler = GPUSamplerImpl::GetPointer(resourceVal.As<v8::Object>());
429
+ if (sampler != nullptr) {
430
+ auto resource = CanvasBindGroupEntryResource{
431
+ CanvasBindGroupEntryResourceSampler,
432
+ };
433
+ resource.sampler = sampler->GetSampler();
434
+ CanvasBindGroupEntry entry{binding, resource};
435
+ entries.push_back(entry);
436
+ }
437
+
438
+ }
439
+ break;
440
+ case NativeType::GPUTextureView: {
441
+ auto textureView = GPUTextureViewImpl::GetPointer(
442
+ resourceVal.As<v8::Object>());
443
+ if (textureView != nullptr) {
444
+ auto resource = CanvasBindGroupEntryResource{
445
+ CanvasBindGroupEntryResourceTextureView,
446
+ };
447
+ resource.texture_view = textureView->GetTextureView();
448
+ CanvasBindGroupEntry entry{binding, resource};
449
+ entries.push_back(entry);
450
+ }
451
+ }
452
+ break;
453
+ default: {
454
+ if (!resourceVal.IsEmpty() && resourceVal->IsObject()) {
455
+ auto resourceObj = resourceVal.As<v8::Object>();
456
+ v8::Local<v8::Value> bufferVal;
457
+ resourceObj->Get(context,
458
+ ConvertToV8String(isolate, "buffer")).ToLocal(
459
+ &bufferVal);
460
+ if (GetNativeType(bufferVal) == NativeType::GPUBuffer) {
461
+ auto bufferObj = bufferVal.As<v8::Object>();
462
+ auto buffer = GPUBufferImpl::GetPointer(bufferObj);
463
+ if (buffer != nullptr) {
464
+ auto resource = CanvasBindGroupEntryResource{
465
+ CanvasBindGroupEntryResourceBuffer,
466
+ };
467
+ int64_t offset = -1;
468
+
469
+ v8::Local<v8::Value> offsetVal;
470
+
471
+ resourceObj->Get(context,
472
+ ConvertToV8String(isolate,
473
+ "offset")).ToLocal(
474
+ &offsetVal);
475
+ if (!offsetVal.IsEmpty() && offsetVal->IsNumber()) {
476
+ offset = (int64_t) offsetVal->NumberValue(
477
+ context).ToChecked();
478
+ }
479
+
480
+ int64_t size = -1;
481
+
482
+ v8::Local<v8::Value> sizeVal;
483
+ resourceObj->Get(context,
484
+ ConvertToV8String(isolate, "size")).ToLocal(
485
+ &sizeVal);
486
+ if (!sizeVal.IsEmpty() && sizeVal->IsNumber()) {
487
+ size = (int64_t) sizeVal->NumberValue(
488
+ context).ToChecked();
489
+ }
490
+
491
+ resource.buffer = CanvasBufferBinding{
492
+ buffer->GetGPUBuffer(), offset, size
493
+ };
494
+
495
+ CanvasBindGroupEntry entry{binding, resource};
496
+ entries.push_back(entry);
497
+ }
498
+ }
499
+ }
500
+
501
+ }
502
+ break;
503
+ }
504
+
505
+ }
506
+ }
507
+ }
508
+
509
+
510
+ auto bind_group = canvas_native_webgpu_device_create_bind_group(ptr->GetGPUDevice(), label,
511
+ layout, entries.data(),
512
+ entries.size());
513
+
514
+ if (bind_group != nullptr) {
515
+ auto ret = GPUBindGroupImpl::NewInstance(isolate, new GPUBindGroupImpl(bind_group));
516
+ args.GetReturnValue().Set(ret);
517
+ return;
518
+ }
519
+ }
520
+
521
+ args.GetReturnValue().SetUndefined();
522
+ }
523
+
524
+ void GPUDeviceImpl::CreateBindGroupLayout(const v8::FunctionCallbackInfo<v8::Value> &args) {
525
+ GPUDeviceImpl *ptr = GetPointer(args.This());
526
+ if (ptr == nullptr) {
527
+ return;
528
+ }
529
+ auto isolate = args.GetIsolate();
530
+ auto context = isolate->GetCurrentContext();
531
+ char *label = nullptr;
532
+
533
+ auto optionsVal = args[0];
534
+
535
+ if (optionsVal->IsObject()) {
536
+ auto options = optionsVal.As<v8::Object>();
537
+ v8::Local<v8::Value> labelVal;
538
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
539
+
540
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
541
+ label = *v8::String::Utf8Value(isolate, labelVal);
542
+ }
543
+
544
+
545
+ std::vector<CanvasBindGroupLayoutEntry> entries;
546
+
547
+ v8::Local<v8::Value> entriesVal;
548
+ options->Get(context, ConvertToV8String(isolate, "entries")).ToLocal(&entriesVal);
549
+
550
+ if (!entriesVal.IsEmpty() && entriesVal->IsArray()) {
551
+ auto entriesArray = entriesVal.As<v8::Array>();
552
+ auto len = entriesArray->Length();
553
+ for (int i = 0; i < len; i++) {
554
+ v8::Local<v8::Value> entryVal;
555
+ entriesArray->Get(context, i).ToLocal(&entryVal);
556
+ if (!entryVal.IsEmpty() && entryVal->IsObject()) {
557
+ auto entryObj = entryVal.As<v8::Object>();
558
+ auto binding = entryObj->Get(context, ConvertToV8String(isolate,
559
+ "binding")).ToLocalChecked()->Uint32Value(
560
+ context).FromJust();
561
+ v8::Local<v8::Value> resourceVal;
562
+ entryObj->Get(context, ConvertToV8String(isolate, "resource")).ToLocal(
563
+ &resourceVal);
564
+
565
+
566
+ auto visibility = entryObj->Get(context, ConvertToV8String(isolate,
567
+ "visibility")).ToLocalChecked()->Uint32Value(
568
+ context).FromJust();
569
+
570
+
571
+ v8::Local<v8::Value> bufferVal;
572
+
573
+ entryObj->Get(context, ConvertToV8String(isolate, "buffer")).ToLocal(
574
+ &bufferVal);
575
+
576
+
577
+ if (!bufferVal.IsEmpty() && bufferVal->IsObject()) {
578
+ auto bufferObj = bufferVal.As<v8::Object>();
579
+ v8::Local<v8::Value> bufferType;
580
+ bufferObj->Get(context, ConvertToV8String(isolate, "type")).ToLocal(
581
+ &bufferType);
582
+
583
+ CanvasBufferBindingType type = CanvasBufferBindingTypeUniform;
584
+
585
+ if (!bufferType.IsEmpty() && bufferType->IsString()) {
586
+ auto typeStr = ConvertFromV8String(isolate, bufferType);
587
+ if (typeStr == "read-only-storage") {
588
+ type = CanvasBufferBindingTypeReadOnlyStorage;
589
+ } else if (typeStr == "storage") {
590
+ type = CanvasBufferBindingTypeStorage;
591
+ } else if (typeStr == "uniform") {
592
+ type = CanvasBufferBindingTypeUniform;
593
+ }
594
+ }
595
+
596
+ bool has_dynamic_offset = false;
597
+
598
+ v8::Local<v8::Value> hasDynamicOffsetVal;
599
+ bufferObj->Get(context,
600
+ ConvertToV8String(isolate, "hasDynamicOffset")).ToLocal(
601
+ &hasDynamicOffsetVal);
602
+
603
+
604
+ if (!hasDynamicOffsetVal.IsEmpty() && hasDynamicOffsetVal->IsBoolean()) {
605
+ has_dynamic_offset = hasDynamicOffsetVal->BooleanValue(isolate);
606
+ }
607
+
608
+ int64_t min_binding_size = -1;
609
+
610
+ v8::Local<v8::Value> minBindingSizeVal;
611
+ bufferObj->Get(context,
612
+ ConvertToV8String(isolate, "minBindingSize")).ToLocal(
613
+ &minBindingSizeVal);
614
+
615
+
616
+ if (!minBindingSizeVal.IsEmpty() && minBindingSizeVal->IsNumber()) {
617
+ min_binding_size = (int64_t) minBindingSizeVal->NumberValue(
618
+ context).ToChecked();
619
+ }
620
+
621
+ CanvasBindingType buffer{
622
+ CanvasBindingTypeBuffer
623
+ };
624
+
625
+ buffer.buffer = CanvasBufferBindingLayout{
626
+ type, has_dynamic_offset, min_binding_size
627
+ };
628
+
629
+
630
+ CanvasBindGroupLayoutEntry entry{
631
+ binding,
632
+ visibility,
633
+ buffer
634
+ };
635
+
636
+ entries.push_back(entry);
637
+
638
+ continue;
639
+ }
640
+
641
+
642
+ v8::Local<v8::Value> externalTextureVal;
643
+
644
+ entryObj->Get(context, ConvertToV8String(isolate, "externalTexture")).ToLocal(
645
+ &externalTextureVal);
646
+
647
+ if (!externalTextureVal.IsEmpty() && externalTextureVal->IsObject()) {
648
+ // todo
649
+ // CanvasBindingType buffer{
650
+ // CanvasBindingTypeTexture
651
+ // };
652
+ //
653
+ // buffer.buffer = CanvasBufferBindingLayout{
654
+ // type, has_dynamic_offset, min_binding_size
655
+ // };
656
+ //
657
+ //
658
+ // CanvasBindGroupLayoutEntry entry{
659
+ // binding,
660
+ // visibility,
661
+ // buffer
662
+ // };
663
+
664
+ continue;
665
+ }
666
+
667
+
668
+ v8::Local<v8::Value> samplerVal;
669
+
670
+ entryObj->Get(context, ConvertToV8String(isolate, "sampler")).ToLocal(
671
+ &samplerVal);
672
+
673
+ if (!samplerVal.IsEmpty() && samplerVal->IsObject()) {
674
+ auto samplerObj = samplerVal.As<v8::Object>();
675
+ v8::Local<v8::Value> samplerType;
676
+ samplerObj->Get(context, ConvertToV8String(isolate, "type")).ToLocal(
677
+ &samplerType);
678
+
679
+ CanvasSamplerBindingType type = CanvasSamplerBindingTypeFiltering;
680
+
681
+ if (!samplerType.IsEmpty() && samplerType->IsString()) {
682
+ auto typeStr = ConvertFromV8String(isolate, samplerType);
683
+ if (typeStr == "comparison") {
684
+ type = CanvasSamplerBindingTypeComparison;
685
+ } else if (typeStr == "non-filtering") {
686
+ type = CanvasSamplerBindingTypeNonFiltering;
687
+ } else if (typeStr == "filtering") {
688
+ type = CanvasSamplerBindingTypeFiltering;
689
+ }
690
+ }
691
+
692
+
693
+ CanvasBindingType sampler{
694
+ CanvasBindingTypeSampler
695
+ };
696
+
697
+ sampler.sampler = CanvasSamplerBindingLayout{
698
+ type
699
+ };
700
+
701
+
702
+ CanvasBindGroupLayoutEntry entry{
703
+ binding,
704
+ visibility,
705
+ sampler
706
+ };
707
+
708
+ entries.push_back(entry);
709
+
710
+ continue;
711
+
712
+ }
713
+
714
+
715
+ v8::Local<v8::Value> storageTextureVal;
716
+
717
+ entryObj->Get(context, ConvertToV8String(isolate, "storageTexture")).ToLocal(
718
+ &storageTextureVal);
719
+
720
+ if (!storageTextureVal.IsEmpty() && storageTextureVal->IsObject()) {
721
+ auto storageTextureObj = storageTextureVal.As<v8::Object>();
722
+
723
+ CanvasBindingType storage{
724
+ CanvasBindingTypeStorageTexture
725
+ };
726
+
727
+ CanvasStorageTextureAccess access = CanvasStorageTextureAccessWriteOnly;
728
+
729
+ v8::Local<v8::Value> accessVal;
730
+
731
+ storageTextureObj->Get(context,
732
+ ConvertToV8String(isolate, "access")).ToLocal(
733
+ &accessVal);
734
+
735
+
736
+ if (!accessVal.IsEmpty() && accessVal->IsString()) {
737
+ auto accessStr = ConvertFromV8String(isolate, accessVal);
738
+
739
+ if (accessStr == "write-only") {
740
+ access = CanvasStorageTextureAccessWriteOnly;
741
+ } else if (accessStr == "read-only") {
742
+ access = CanvasStorageTextureAccessReadOnly;
743
+ } else if (accessStr == "read-write") {
744
+ access = CanvasStorageTextureAccessReadWrite;
745
+ }
746
+ }
747
+
748
+
749
+ CanvasTextureViewDimension view_dimension = CanvasTextureViewDimensionD2;
750
+
751
+
752
+ v8::Local<v8::Value> viewDimensionVal;
753
+
754
+ storageTextureObj->Get(context,
755
+ ConvertToV8String(isolate, "viewDimension")).ToLocal(
756
+ &viewDimensionVal);
757
+
758
+
759
+ if (!viewDimensionVal.IsEmpty() && viewDimensionVal->IsString()) {
760
+ auto viewDimensionStr = ConvertFromV8String(isolate, viewDimensionVal);
761
+ if (viewDimensionStr == "1d") {
762
+ view_dimension = CanvasTextureViewDimensionD1;
763
+ } else if (viewDimensionStr == "2d") {
764
+ view_dimension = CanvasTextureViewDimensionD2;
765
+ } else if (viewDimensionStr == "2d-array") {
766
+ view_dimension = CanvasTextureViewDimensionD2Array;
767
+ } else if (viewDimensionStr == "cube") {
768
+ view_dimension = CanvasTextureViewDimensionCube;
769
+ } else if (viewDimensionStr == "cube-array") {
770
+ view_dimension = CanvasTextureViewDimensionCubeArray;
771
+ } else if (viewDimensionStr == "3d") {
772
+ view_dimension = CanvasTextureViewDimensionD3;
773
+ }
774
+ }
775
+
776
+
777
+ v8::Local<v8::Value> formatVal;
778
+
779
+ storageTextureObj->Get(context,
780
+ ConvertToV8String(isolate, "format")).ToLocal(
781
+ &formatVal);
782
+
783
+
784
+ if (!formatVal.IsEmpty() && formatVal->IsString()) {
785
+ auto formatStr = ConvertFromV8String(isolate, formatVal);
786
+ auto textureFormat = canvas_native_webgpu_enum_string_to_gpu_texture(
787
+ formatStr.c_str());
788
+ if (textureFormat.tag == CanvasOptionalGPUTextureFormatSome) {
789
+ storage.storage_texture = CanvasStorageTextureBindingLayout{
790
+ access,
791
+ textureFormat.some,
792
+ view_dimension
793
+ };
794
+
795
+ CanvasBindGroupLayoutEntry entry{
796
+ binding,
797
+ visibility,
798
+ storage
799
+ };
800
+
801
+ entries.push_back(entry);
802
+
803
+ continue;
804
+
805
+ } else {
806
+ // todo throw ??
807
+ continue;
808
+ }
809
+ }
810
+
811
+
812
+ }
813
+
814
+
815
+ v8::Local<v8::Value> textureVal;
816
+
817
+ entryObj->Get(context, ConvertToV8String(isolate, "texture")).ToLocal(
818
+ &textureVal);
819
+
820
+ if (!textureVal.IsEmpty() && textureVal->IsObject()) {
821
+ auto textureObj = textureVal.As<v8::Object>();
822
+ bool multisampled = false;
823
+
824
+ v8::Local<v8::Value> multisampledVal;
825
+
826
+ textureObj->Get(context,
827
+ ConvertToV8String(isolate, "multisampled")).ToLocal(
828
+ &multisampledVal);
829
+
830
+ if (!multisampledVal.IsEmpty() && multisampledVal->IsBoolean()) {
831
+ multisampled = multisampledVal->BooleanValue(isolate);
832
+ }
833
+
834
+
835
+ v8::Local<v8::Value> sampleTypeVal;
836
+ textureObj->Get(context, ConvertToV8String(isolate, "sampleType")).ToLocal(
837
+ &sampleTypeVal);
838
+
839
+ CanvasTextureSampleType type = CanvasTextureSampleTypeFloat;
840
+
841
+ if (!sampleTypeVal.IsEmpty() && sampleTypeVal->IsString()) {
842
+ auto typeStr = ConvertFromV8String(isolate, sampleTypeVal);
843
+ if (typeStr == "depth") {
844
+ type = CanvasTextureSampleTypeDepth;
845
+ } else if (typeStr == "float") {
846
+ type = CanvasTextureSampleTypeFloat;
847
+ } else if (typeStr == "sint") {
848
+ type = CanvasTextureSampleTypeSint;
849
+ } else if (typeStr == "uint") {
850
+ type = CanvasTextureSampleTypeUint;
851
+ } else if (typeStr == "unfilterable-float") {
852
+ type = CanvasTextureSampleTypeUnfilterableFloat;
853
+ }
854
+ }
855
+
856
+
857
+ CanvasTextureViewDimension view_dimension = CanvasTextureViewDimensionD2;
858
+
859
+
860
+ v8::Local<v8::Value> viewDimensionVal;
861
+
862
+ textureObj->Get(context,
863
+ ConvertToV8String(isolate, "viewDimension")).ToLocal(
864
+ &viewDimensionVal);
865
+
866
+
867
+ if (!viewDimensionVal.IsEmpty() && viewDimensionVal->IsString()) {
868
+ auto viewDimensionStr = ConvertFromV8String(isolate, viewDimensionVal);
869
+ if (viewDimensionStr == "1d") {
870
+ view_dimension = CanvasTextureViewDimensionD1;
871
+ } else if (viewDimensionStr == "2d") {
872
+ view_dimension = CanvasTextureViewDimensionD2;
873
+ } else if (viewDimensionStr == "2d-array") {
874
+ view_dimension = CanvasTextureViewDimensionD2Array;
875
+ } else if (viewDimensionStr == "cube") {
876
+ view_dimension = CanvasTextureViewDimensionCube;
877
+ } else if (viewDimensionStr == "cube-array") {
878
+ view_dimension = CanvasTextureViewDimensionCubeArray;
879
+ } else if (viewDimensionStr == "3d") {
880
+ view_dimension = CanvasTextureViewDimensionD3;
881
+ }
882
+ }
883
+
884
+
885
+ CanvasBindingType texture{
886
+ CanvasBindingTypeTexture
887
+ };
888
+
889
+ texture.texture = CanvasTextureBindingLayout{
890
+ type,
891
+ view_dimension,
892
+ multisampled
893
+ };
894
+
895
+
896
+ CanvasBindGroupLayoutEntry entry{
897
+ binding,
898
+ visibility,
899
+ texture
900
+ };
901
+
902
+ entries.push_back(entry);
903
+
904
+ continue;
905
+
906
+ }
907
+
908
+ }
909
+ }
910
+ }
911
+
912
+
913
+ auto bind_group = canvas_native_webgpu_device_create_bind_group_layout(ptr->GetGPUDevice(),
914
+ label,
915
+ entries.data(),
916
+ entries.size());
917
+
918
+ if (bind_group != nullptr) {
919
+ auto ret = GPUBindGroupLayoutImpl::NewInstance(isolate,
920
+ new GPUBindGroupLayoutImpl(bind_group));
921
+ args.GetReturnValue().Set(ret);
922
+ return;
923
+ }
924
+ }
925
+
926
+ args.GetReturnValue().SetUndefined();
927
+ }
928
+
929
+ void GPUDeviceImpl::CreateBuffer(const v8::FunctionCallbackInfo<v8::Value> &args) {
930
+ GPUDeviceImpl *ptr = GetPointer(args.This());
931
+ if (ptr == nullptr) {
932
+ return;
933
+ }
934
+ auto isolate = args.GetIsolate();
935
+ auto context = isolate->GetCurrentContext();
936
+ char *label = nullptr;
937
+ bool mappedAtCreation = false;
938
+ uint64_t size = 0;
939
+ uint32_t usage = 0;
940
+
941
+ auto optionsVal = args[0];
942
+
943
+ if (optionsVal->IsObject()) {
944
+ auto options = optionsVal.As<v8::Object>();
945
+ v8::Local<v8::Value> labelVal;
946
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
947
+
948
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
949
+ label = *v8::String::Utf8Value(isolate, labelVal);
950
+ }
951
+
952
+ v8::Local<v8::Value> mappedAtCreationVal;
953
+
954
+ options->Get(context, ConvertToV8String(isolate, "mappedAtCreation")).ToLocal(
955
+ &mappedAtCreationVal);
956
+
957
+ if (!mappedAtCreationVal.IsEmpty()) {
958
+ mappedAtCreation = mappedAtCreationVal->BooleanValue(isolate);
959
+ }
960
+
961
+ v8::Local<v8::Value> sizeVal;
962
+ options->Get(context, ConvertToV8String(isolate, "size")).ToLocal(&sizeVal);
963
+
964
+ if (sizeVal->IsNumber()) {
965
+ size = (uint64_t) sizeVal->NumberValue(context).ToChecked();
966
+ }
967
+
968
+
969
+ v8::Local<v8::Value> usageVal;
970
+ options->Get(context, ConvertToV8String(isolate, "usage")).ToLocal(&usageVal);
971
+
972
+ if (usageVal->IsNumber()) {
973
+ usage = usageVal->Uint32Value(context).ToChecked();
974
+ }
975
+ }
976
+
977
+ auto buffer = canvas_native_webgpu_device_create_buffer(ptr->GetGPUDevice(), label, size, usage,
978
+ mappedAtCreation);
979
+
980
+ if (buffer != nullptr) {
981
+ auto bufImpl = new GPUBufferImpl(buffer);
982
+ auto ret = GPUBufferImpl::NewInstance(isolate, bufImpl);
983
+ args.GetReturnValue().Set(ret);
984
+
985
+ } else {
986
+ // todo return invalid buffer
987
+ args.GetReturnValue().SetUndefined();
988
+ }
989
+ }
990
+
991
+ void GPUDeviceImpl::CreateCommandEncoder(const v8::FunctionCallbackInfo<v8::Value> &args) {
992
+ GPUDeviceImpl *ptr = GetPointer(args.This());
993
+ if (ptr == nullptr) {
994
+ return;
995
+ }
996
+ auto isolate = args.GetIsolate();
997
+
998
+ char *label = nullptr;
999
+
1000
+ auto labelVal = args[0];
1001
+
1002
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
1003
+ label = *v8::String::Utf8Value(isolate, labelVal);
1004
+ }
1005
+
1006
+ auto encoder = canvas_native_webgpu_device_create_command_encoder(ptr->GetGPUDevice(), label);
1007
+
1008
+ if (encoder != nullptr) {
1009
+ auto instance = new GPUCommandEncoderImpl(encoder);
1010
+ auto ret = GPUCommandEncoderImpl::NewInstance(isolate, instance);
1011
+ args.GetReturnValue().Set(ret);
1012
+ return;
1013
+ }
1014
+
1015
+ args.GetReturnValue().SetUndefined();
1016
+
1017
+ }
1018
+
1019
+ void GPUDeviceImpl::CreateComputePipeline(const v8::FunctionCallbackInfo<v8::Value> &args) {
1020
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1021
+ if (ptr == nullptr) {
1022
+ return;
1023
+ }
1024
+ auto isolate = args.GetIsolate();
1025
+ auto context = isolate->GetCurrentContext();
1026
+
1027
+ auto optionsVal = args[0];
1028
+
1029
+ if (!optionsVal->IsObject()) {
1030
+ // should error at this point
1031
+ return;
1032
+ }
1033
+ auto options = optionsVal.As<v8::Object>();
1034
+
1035
+ v8::Local<v8::Value> labelVal;
1036
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1037
+
1038
+ char *label = nullptr;
1039
+
1040
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
1041
+ label = *v8::String::Utf8Value(isolate, labelVal);
1042
+ }
1043
+
1044
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout{
1045
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
1046
+ };
1047
+
1048
+ v8::Local<v8::Value> layoutVal;
1049
+ options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(&layoutVal);
1050
+
1051
+ if (!layoutVal.IsEmpty() && layoutVal->IsObject()) {
1052
+ auto layoutImpl = GPUPipelineLayoutImpl::GetPointer(layoutVal.As<v8::Object>());
1053
+ if (layoutImpl != nullptr) {
1054
+ layout.tag = CanvasGPUPipelineLayoutOrGPUAutoLayoutModeLayout;
1055
+ layout.layout = layoutImpl->GetPipeline();
1056
+ }
1057
+ }
1058
+
1059
+
1060
+ v8::Local<v8::Value> computeVal;
1061
+ options->Get(context, ConvertToV8String(isolate, "compute")).ToLocal(&computeVal);
1062
+
1063
+ if (!computeVal.IsEmpty() && computeVal->IsObject()) {
1064
+
1065
+ auto computeObj = computeVal.As<v8::Object>();
1066
+
1067
+ v8::Local<v8::Value> constantsVal;
1068
+ computeObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(
1069
+ &constantsVal);
1070
+
1071
+ CanvasConstants *store = nullptr;
1072
+
1073
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
1074
+ auto constants = constantsVal.As<v8::Map>();
1075
+ auto keyValues = constants->AsArray();
1076
+ auto length = keyValues->Length();
1077
+ if (length > 0) {
1078
+ store = canvas_native_webgpu_constants_create();
1079
+ for (int i = 0; i < length; i += 2) {
1080
+ auto k = i;
1081
+ auto v = k + 1;
1082
+
1083
+ v8::Local<v8::Value> keyVal;
1084
+ keyValues->Get(context, k).ToLocal(&keyVal);
1085
+ v8::Local<v8::Value> valueVal;
1086
+ keyValues->Get(context, v).ToLocal(&valueVal);
1087
+
1088
+
1089
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
1090
+ valueVal->IsNumber()) {
1091
+ auto val = ConvertFromV8String(isolate, keyVal);
1092
+ canvas_native_webgpu_constants_insert(
1093
+ store,
1094
+ val.c_str(),
1095
+ valueVal.As<v8::Number>()->Value()
1096
+ );
1097
+ }
1098
+
1099
+ }
1100
+ }
1101
+ }
1102
+
1103
+
1104
+ v8::Local<v8::Value> entryPoint;
1105
+ computeObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(
1106
+ &entryPoint);
1107
+
1108
+ char *entry_point = nullptr;
1109
+
1110
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
1111
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
1112
+ entry_point = (char *) malloc(ep.length());
1113
+ std::strcpy(entry_point, *ep);
1114
+ }
1115
+
1116
+ v8::Local<v8::Value> moduleVal;
1117
+ computeObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
1118
+
1119
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
1120
+
1121
+ CanvasProgrammableStage stage{
1122
+ module->GetShaderModule(),
1123
+ entry_point,
1124
+ store
1125
+ };
1126
+
1127
+ auto pipeline = canvas_native_webgpu_device_create_compute_pipeline(ptr->GetGPUDevice(),
1128
+ label, layout, &stage);
1129
+
1130
+ if (entry_point != nullptr) {
1131
+ free(entry_point);
1132
+ }
1133
+
1134
+ if (store != nullptr) {
1135
+ canvas_native_webgpu_constants_destroy(store);
1136
+ }
1137
+
1138
+ if (pipeline != nullptr) {
1139
+ auto ret = GPUComputePipelineImpl::NewInstance(isolate,
1140
+ new GPUComputePipelineImpl(pipeline));
1141
+ args.GetReturnValue().Set(ret);
1142
+ return;
1143
+ }
1144
+
1145
+
1146
+ }
1147
+
1148
+ args.GetReturnValue().SetUndefined();
1149
+ }
1150
+
1151
+ void GPUDeviceImpl::CreatePipelineLayout(const v8::FunctionCallbackInfo<v8::Value> &args) {
1152
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1153
+ if (ptr == nullptr) {
1154
+ return;
1155
+ }
1156
+ auto isolate = args.GetIsolate();
1157
+ auto context = isolate->GetCurrentContext();
1158
+
1159
+ auto optionsVal = args[0];
1160
+
1161
+ if (!optionsVal->IsObject()) {
1162
+ // should error at this point
1163
+ return;
1164
+ }
1165
+ auto options = optionsVal.As<v8::Object>();
1166
+
1167
+ v8::Local<v8::Value> labelVal;
1168
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1169
+
1170
+ char *label = nullptr;
1171
+
1172
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
1173
+ label = *v8::String::Utf8Value(isolate, labelVal);
1174
+ }
1175
+
1176
+
1177
+ std::vector<const CanvasGPUBindGroupLayout *> group_layouts;
1178
+
1179
+ v8::Local<v8::Value> groupLayoutsVal;
1180
+ options->Get(context, ConvertToV8String(isolate, "bindGroupLayouts")).ToLocal(&groupLayoutsVal);
1181
+
1182
+ if (!groupLayoutsVal.IsEmpty() && groupLayoutsVal->IsArray()) {
1183
+ auto groupLayoutsArray = groupLayoutsVal.As<v8::Array>();
1184
+ auto len = groupLayoutsArray->Length();
1185
+ for (int i = 0; i < len; i++) {
1186
+ v8::Local<v8::Value> groupVal;
1187
+ groupLayoutsArray->Get(context, i).ToLocal(&groupVal);
1188
+ if (GetNativeType(groupVal) == NativeType::GPUBindGroupLayout) {
1189
+ auto layout = GPUBindGroupLayoutImpl::GetPointer(groupVal.As<v8::Object>());
1190
+ if (layout != nullptr) {
1191
+ group_layouts.push_back(layout->GetBindGroupLayout());
1192
+ }
1193
+ }
1194
+ }
1195
+
1196
+ auto layout = canvas_native_webgpu_device_create_pipeline_layout(ptr->GetGPUDevice(), label,
1197
+ group_layouts.data(),
1198
+ group_layouts.size());
1199
+
1200
+ if (layout != nullptr) {
1201
+ auto ret = GPUPipelineLayoutImpl::NewInstance(isolate,
1202
+ new GPUPipelineLayoutImpl(layout));
1203
+ args.GetReturnValue().Set(ret);
1204
+ return;
1205
+ }
1206
+ }
1207
+
1208
+
1209
+ args.GetReturnValue().SetUndefined();
1210
+ }
1211
+
1212
+ void GPUDeviceImpl::CreateQuerySet(const v8::FunctionCallbackInfo<v8::Value> &args) {
1213
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1214
+ if (ptr == nullptr) {
1215
+ return;
1216
+ }
1217
+ auto isolate = args.GetIsolate();
1218
+ auto context = isolate->GetCurrentContext();
1219
+
1220
+ auto optionsVal = args[0];
1221
+
1222
+ if (!optionsVal->IsObject()) {
1223
+ // should error at this point
1224
+ return;
1225
+ }
1226
+ auto options = optionsVal.As<v8::Object>();
1227
+
1228
+ v8::Local<v8::Value> labelVal;
1229
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1230
+
1231
+ char *label = nullptr;
1232
+
1233
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
1234
+ label = *v8::String::Utf8Value(isolate, labelVal);
1235
+ }
1236
+
1237
+
1238
+ v8::Local<v8::Value> typeVal;
1239
+ options->Get(context, ConvertToV8String(isolate, "type")).ToLocal(&labelVal);
1240
+
1241
+
1242
+ v8::Local<v8::Value> countVal;
1243
+ options->Get(context, ConvertToV8String(isolate, "count")).ToLocal(&labelVal);
1244
+
1245
+ auto typeStr = ConvertFromV8String(isolate, typeVal);
1246
+
1247
+ const CanvasGPUQuerySet *query_set = nullptr;
1248
+ if (typeStr == "occlusion") {
1249
+ query_set = canvas_native_webgpu_device_create_query_set(ptr->GetGPUDevice(), label,
1250
+ CanvasQueryTypeOcclusion,
1251
+ countVal->Uint32Value(
1252
+ context).FromJust());
1253
+ } else if (typeStr == "timestamp") {
1254
+ query_set = canvas_native_webgpu_device_create_query_set(ptr->GetGPUDevice(), label,
1255
+ CanvasQueryTypeTimestamp,
1256
+ countVal->Uint32Value(
1257
+ context).FromJust());
1258
+ } else {
1259
+ // todo throw
1260
+ }
1261
+
1262
+
1263
+ if (query_set != nullptr) {
1264
+ auto ret = GPUQuerySetImpl::NewInstance(isolate, new GPUQuerySetImpl(query_set));
1265
+ args.GetReturnValue().Set(ret);
1266
+ return;
1267
+ }
1268
+
1269
+ args.GetReturnValue().SetUndefined();
1270
+
1271
+ }
1272
+
1273
+ void GPUDeviceImpl::CreateRenderBundleEncoder(const v8::FunctionCallbackInfo<v8::Value> &args) {
1274
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1275
+ if (ptr == nullptr) {
1276
+ return;
1277
+ }
1278
+ auto isolate = args.GetIsolate();
1279
+ auto context = isolate->GetCurrentContext();
1280
+
1281
+ auto optionsVal = args[0];
1282
+
1283
+ if (!optionsVal->IsObject()) {
1284
+ // should error at this point
1285
+ return;
1286
+ }
1287
+ auto options = optionsVal.As<v8::Object>();
1288
+
1289
+ v8::Local<v8::Value> labelVal;
1290
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1291
+
1292
+ char *label = nullptr;
1293
+
1294
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
1295
+ label = *v8::String::Utf8Value(isolate, labelVal);
1296
+ }
1297
+
1298
+
1299
+ std::vector<CanvasGPUTextureFormat> colorFormats;
1300
+
1301
+ v8::Local<v8::Value> colorFormatsVal;
1302
+ options->Get(context, ConvertToV8String(isolate, "colorFormats")).ToLocal(&colorFormatsVal);
1303
+
1304
+ if (!colorFormatsVal.IsEmpty() && colorFormatsVal->IsArray()) {
1305
+ auto colorFormatsArray = colorFormatsVal.As<v8::Array>();
1306
+ auto len = colorFormatsArray->Length();
1307
+ for (int i = 0; i < len; i++) {
1308
+ v8::Local<v8::Value> formatVal;
1309
+ colorFormatsArray->Get(context, i).ToLocal(&formatVal);
1310
+ if (!formatVal.IsEmpty() && formatVal->IsString()) {
1311
+ auto formatStr = ConvertFromV8String(isolate, formatVal);
1312
+ auto format = canvas_native_webgpu_enum_string_to_gpu_texture(formatStr.c_str());
1313
+ if (format.tag == CanvasOptionalGPUTextureFormatSome) {
1314
+ colorFormats.push_back(format.some);
1315
+ }
1316
+ }
1317
+
1318
+ }
1319
+ }
1320
+
1321
+
1322
+ auto depthStencilFormat = CanvasOptionalGPUTextureFormat{
1323
+ CanvasOptionalGPUTextureFormatNone
1324
+ };
1325
+
1326
+ v8::Local<v8::Value> depthStencilFormatVal;
1327
+ options->Get(context, ConvertToV8String(isolate, "depthStencilFormat")).ToLocal(
1328
+ &depthStencilFormatVal);
1329
+
1330
+ if (!depthStencilFormatVal.IsEmpty() && depthStencilFormatVal->IsString()) {
1331
+ auto depthStencilFormatStr = ConvertFromV8String(isolate, depthStencilFormatVal);
1332
+ depthStencilFormat = canvas_native_webgpu_enum_string_to_gpu_texture(
1333
+ depthStencilFormatStr.c_str());
1334
+ }
1335
+
1336
+ uint32_t sampleCount = 1;
1337
+
1338
+ bool depthReadOnly = false;
1339
+
1340
+ bool stencilReadOnly = false;
1341
+
1342
+ CanvasCreateRenderBundleEncoderDescriptor descriptor{
1343
+ label,
1344
+ colorFormats.data(),
1345
+ colorFormats.size(),
1346
+ depthStencilFormat,
1347
+ sampleCount,
1348
+ depthReadOnly,
1349
+ stencilReadOnly
1350
+ };
1351
+
1352
+
1353
+ auto encoder = canvas_native_webgpu_device_create_render_bundle_encoder(ptr->GetGPUDevice(),
1354
+ &descriptor);
1355
+
1356
+ if (encoder != nullptr) {
1357
+ auto ret = GPURenderBundleEncoderImpl::NewInstance(isolate,
1358
+ new GPURenderBundleEncoderImpl(encoder));
1359
+ args.GetReturnValue().Set(ret);
1360
+ return;
1361
+ }
1362
+
1363
+ args.GetReturnValue().SetUndefined();
1364
+ }
1365
+
1366
+ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Value> &args) {
1367
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1368
+ if (ptr == nullptr) {
1369
+ return;
1370
+ }
1371
+ auto isolate = args.GetIsolate();
1372
+ auto context = isolate->GetCurrentContext();
1373
+
1374
+ CanvasCreateRenderPipelineDescriptor descriptor{};
1375
+ descriptor.label = nullptr;
1376
+
1377
+ auto optionsVal = args[0];
1378
+
1379
+ if (!optionsVal->IsObject()) {
1380
+ // should error at this point
1381
+ return;
1382
+ }
1383
+ auto options = optionsVal.As<v8::Object>();
1384
+
1385
+
1386
+ v8::Local<v8::Value> stencilValue;
1387
+ options->Get(context, ConvertToV8String(isolate, "depthStencil")).ToLocal(
1388
+ &stencilValue);
1389
+
1390
+ CanvasDepthStencilState *stencil = nullptr;
1391
+
1392
+ if (!stencilValue.IsEmpty() && stencilValue->IsObject()) {
1393
+ auto stencilObj = stencilValue.As<v8::Object>();
1394
+ stencil = new CanvasDepthStencilState{};
1395
+ stencil->depth_bias = 0;
1396
+ stencil->depth_bias_clamp = 0;
1397
+ stencil->depth_bias_slope_scale = 0;
1398
+ stencil->stencil_read_mask = 0xFFFFFFFF;
1399
+ stencil->stencil_write_mask = 0xFFFFFFFF;
1400
+ stencil->stencil_front = CanvasStencilFaceState{
1401
+ CanvasCompareFunctionAlways,
1402
+ CanvasStencilOperationKeep,
1403
+ CanvasStencilOperationKeep,
1404
+ CanvasStencilOperationKeep
1405
+ };
1406
+
1407
+ stencil->stencil_back = CanvasStencilFaceState{
1408
+ CanvasCompareFunctionAlways,
1409
+ CanvasStencilOperationKeep,
1410
+ CanvasStencilOperationKeep,
1411
+ CanvasStencilOperationKeep
1412
+ };
1413
+ // todo throw if failed
1414
+ v8::Local<v8::Value> formatValue;
1415
+
1416
+ stencilObj->Get(context, ConvertToV8String(isolate, "format")).ToLocal(&formatValue);
1417
+ if (!formatValue.IsEmpty() && formatValue->IsString()) {
1418
+ auto val = ConvertFromV8String(isolate, formatValue);
1419
+ auto format = canvas_native_webgpu_enum_string_to_gpu_texture(
1420
+ val.c_str());
1421
+ if (format.tag ==
1422
+ CanvasOptionalGPUTextureFormat_Tag::CanvasOptionalGPUTextureFormatSome) {
1423
+ stencil->format = format.some;
1424
+ }
1425
+ } else {
1426
+ // todo throw
1427
+ }
1428
+
1429
+ v8::Local<v8::Value> depthBiasVal;
1430
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBias")).ToLocal(&depthBiasVal);
1431
+
1432
+ if (!depthBiasVal.IsEmpty() && depthBiasVal->IsInt32()) {
1433
+ stencil->depth_bias = depthBiasVal->Int32Value(context).FromJust();
1434
+ }
1435
+
1436
+ v8::Local<v8::Value> depthBiasClampVal;
1437
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBiasClamp")).ToLocal(
1438
+ &depthBiasClampVal);
1439
+
1440
+ if (!depthBiasClampVal.IsEmpty() && depthBiasClampVal->IsNumber()) {
1441
+ stencil->depth_bias_clamp = (float)depthBiasClampVal->NumberValue(context).FromJust();
1442
+ }
1443
+
1444
+
1445
+ v8::Local<v8::Value> depthBiasSlopeScaleVal;
1446
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBiasSlopeScale")).ToLocal(
1447
+ &depthBiasSlopeScaleVal);
1448
+
1449
+ if (!depthBiasSlopeScaleVal.IsEmpty() && depthBiasSlopeScaleVal->IsNumber()) {
1450
+ stencil->depth_bias_slope_scale = (float)depthBiasSlopeScaleVal->NumberValue(
1451
+ context).FromJust();
1452
+ }
1453
+
1454
+ v8::Local<v8::Value> depthCompareVal;
1455
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthCompare")).ToLocal(
1456
+ &depthCompareVal);
1457
+
1458
+ auto depthCompareStr = ConvertFromV8String(isolate, depthCompareVal);
1459
+
1460
+ if (depthCompareStr == "never") {
1461
+ stencil->depth_compare = CanvasCompareFunctionNever;
1462
+ } else if (depthCompareStr == "less") {
1463
+ stencil->depth_compare = CanvasCompareFunctionLess;
1464
+ } else if (depthCompareStr == "equal") {
1465
+ stencil->depth_compare = CanvasCompareFunctionEqual;
1466
+ } else if (depthCompareStr == "less-equal") {
1467
+ stencil->depth_compare = CanvasCompareFunctionLessEqual;
1468
+ } else if (depthCompareStr == "greater") {
1469
+ stencil->depth_compare = CanvasCompareFunctionGreater;
1470
+ } else if (depthCompareStr == "not-equal") {
1471
+ stencil->depth_compare = CanvasCompareFunctionNotEqual;
1472
+ } else if (depthCompareStr == "greater-equal") {
1473
+ stencil->depth_compare = CanvasCompareFunctionGreaterEqual;
1474
+ } else if (depthCompareStr == "always") {
1475
+ stencil->depth_compare = CanvasCompareFunctionAlways;
1476
+ }
1477
+
1478
+ stencil->depth_write_enabled = stencilObj->Get(context, ConvertToV8String(isolate,
1479
+ "depthWriteEnabled")).ToLocalChecked()->BooleanValue(
1480
+ isolate);
1481
+
1482
+
1483
+ v8::Local<v8::Value> stencilBackVal;
1484
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilBack")).ToLocal(
1485
+ &stencilBackVal);
1486
+
1487
+ if (!stencilBackVal.IsEmpty() && stencilBackVal->IsObject()) {
1488
+ auto stencilBackObj = stencilBackVal.As<v8::Object>();
1489
+
1490
+ v8::Local<v8::Value> compareVal;
1491
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(
1492
+ &compareVal);
1493
+
1494
+ stencil->stencil_back.compare = ParseCompareFunction(isolate, compareVal,
1495
+ stencil->stencil_back.compare);
1496
+
1497
+ v8::Local<v8::Value> depthFailOpVal;
1498
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "depthFailOp")).ToLocal(
1499
+ &depthFailOpVal);
1500
+
1501
+ stencil->stencil_back.depth_fail_op = ParseStencilOperation(isolate, depthFailOpVal,
1502
+ stencil->stencil_back.depth_fail_op);
1503
+
1504
+
1505
+ v8::Local<v8::Value> failOpVal;
1506
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "failOp")).ToLocal(
1507
+ &failOpVal);
1508
+
1509
+ stencil->stencil_back.fail_op = ParseStencilOperation(isolate, failOpVal,
1510
+ stencil->stencil_back.fail_op);
1511
+
1512
+ v8::Local<v8::Value> passOpVal;
1513
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "passOp")).ToLocal(
1514
+ &passOpVal);
1515
+
1516
+ stencil->stencil_back.pass_op = ParseStencilOperation(isolate, passOpVal,
1517
+ stencil->stencil_back.pass_op);
1518
+
1519
+ }
1520
+
1521
+
1522
+ v8::Local<v8::Value> stencilFrontVal;
1523
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilFront")).ToLocal(
1524
+ &stencilFrontVal);
1525
+
1526
+ if (!stencilFrontVal.IsEmpty() && stencilFrontVal->IsObject()) {
1527
+ auto stencilFrontObj = stencilFrontVal.As<v8::Object>();
1528
+
1529
+ v8::Local<v8::Value> compareVal;
1530
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(
1531
+ &compareVal);
1532
+
1533
+ stencil->stencil_front.compare = ParseCompareFunction(isolate, compareVal,
1534
+ stencil->stencil_front.compare);
1535
+
1536
+ v8::Local<v8::Value> depthFailOpVal;
1537
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "depthFailOp")).ToLocal(
1538
+ &depthFailOpVal);
1539
+
1540
+ stencil->stencil_front.depth_fail_op = ParseStencilOperation(isolate, depthFailOpVal,
1541
+ stencil->stencil_front.depth_fail_op);
1542
+
1543
+
1544
+ v8::Local<v8::Value> failOpVal;
1545
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "failOp")).ToLocal(
1546
+ &failOpVal);
1547
+
1548
+ stencil->stencil_front.fail_op = ParseStencilOperation(isolate, failOpVal,
1549
+ stencil->stencil_front.fail_op);
1550
+
1551
+ v8::Local<v8::Value> passOpVal;
1552
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "passOp")).ToLocal(
1553
+ &passOpVal);
1554
+
1555
+ stencil->stencil_front.pass_op = ParseStencilOperation(isolate, passOpVal,
1556
+ stencil->stencil_front.pass_op);
1557
+
1558
+ }
1559
+
1560
+ v8::Local<v8::Value> stencilReadMaskVal;
1561
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilReadMask")).ToLocal(
1562
+ &stencilReadMaskVal);
1563
+
1564
+ if (!stencilReadMaskVal.IsEmpty() && stencilReadMaskVal->IsUint32()) {
1565
+ stencil->stencil_read_mask = stencilReadMaskVal->Uint32Value(context).FromJust();
1566
+ }
1567
+
1568
+
1569
+ v8::Local<v8::Value> stencilWriteMaskVal;
1570
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilWriteMask")).ToLocal(
1571
+ &stencilWriteMaskVal);
1572
+
1573
+ if (!stencilWriteMaskVal.IsEmpty() && stencilWriteMaskVal->IsUint32()) {
1574
+ stencil->stencil_write_mask = stencilWriteMaskVal->Uint32Value(context).FromJust();
1575
+ }
1576
+
1577
+ descriptor.depth_stencil = stencil;
1578
+
1579
+ }
1580
+
1581
+
1582
+ v8::Local<v8::Value> fragmentValue;
1583
+ options->Get(context, ConvertToV8String(isolate, "fragment")).ToLocal(
1584
+ &fragmentValue);
1585
+
1586
+ CanvasFragmentState *fragment = nullptr;
1587
+
1588
+ std::vector<CanvasColorTargetState> targets;
1589
+
1590
+ if (!fragmentValue.IsEmpty() && fragmentValue->IsObject()) {
1591
+ auto fragmentValueObj = fragmentValue.As<v8::Object>();
1592
+ fragment = new CanvasFragmentState{};
1593
+
1594
+ v8::Local<v8::Value> targetsVal;
1595
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "targets")).ToLocal(&targetsVal);
1596
+
1597
+
1598
+ auto targetsArray = targetsVal.As<v8::Array>();
1599
+ auto len = targetsArray->Length();
1600
+
1601
+ for (int i = 0; i < len; i++) {
1602
+ auto state = targetsArray->Get(context, i).ToLocalChecked().As<v8::Object>();
1603
+
1604
+ auto formatVal = state->Get(context,
1605
+ ConvertToV8String(isolate, "format")).ToLocalChecked();
1606
+ auto formatStr = ConvertFromV8String(isolate, formatVal);
1607
+ auto formatResult = canvas_native_webgpu_enum_string_to_gpu_texture(formatStr.c_str());
1608
+
1609
+
1610
+ if (formatResult.tag == CanvasOptionalGPUTextureFormatNone) {
1611
+ // todo throw
1612
+ args.GetReturnValue().SetUndefined();
1613
+ return;
1614
+ } else {}
1615
+
1616
+ auto format = CanvasGPUTextureFormat{
1617
+ formatResult.some.tag
1618
+ };
1619
+
1620
+ uint32_t writeMask = 0xF;
1621
+
1622
+ v8::Local<v8::Value> writeMaskVal;
1623
+
1624
+ state->Get(context, ConvertToV8String(isolate, "writeMask")).ToLocal(&writeMaskVal);
1625
+
1626
+ if (!writeMaskVal.IsEmpty() && writeMaskVal->IsUint32()) {
1627
+ writeMask = writeMaskVal->Uint32Value(context).FromJust();
1628
+ }
1629
+
1630
+ CanvasOptionalBlendState blend{
1631
+ CanvasOptionalBlendStateNone
1632
+ };
1633
+
1634
+ v8::Local<v8::Value> blendVal;
1635
+
1636
+ state->Get(context, ConvertToV8String(isolate, "blend")).ToLocal(&blendVal);
1637
+
1638
+ if (!blendVal.IsEmpty() && blendVal->IsObject()) {
1639
+ auto blendObj = blendVal.As<v8::Object>();
1640
+ auto alpha = blendObj->Get(context, ConvertToV8String(isolate,
1641
+ "alpha")).ToLocalChecked().As<v8::Object>();
1642
+
1643
+ v8::Local<v8::Value> alphaSrcFactorVal;
1644
+
1645
+ alpha->Get(context,
1646
+ ConvertToV8String(isolate,
1647
+ "srcFactor")).ToLocal(&alphaSrcFactorVal);
1648
+
1649
+ auto alphaSrcFactor = ParseBlendFactor(isolate, alphaSrcFactorVal,
1650
+ CanvasBlendFactorZero);
1651
+
1652
+ v8::Local<v8::Value> alphaDstFactorVal;
1653
+ alpha->Get(context,
1654
+ ConvertToV8String(isolate,
1655
+ "dstFactor")).ToLocal(&alphaDstFactorVal);
1656
+
1657
+ auto alphaDstFactor = ParseBlendFactor(isolate, alphaDstFactorVal,
1658
+ CanvasBlendFactorZero);
1659
+
1660
+ v8::Local<v8::Value> alphaOperationVal;
1661
+
1662
+ alpha->Get(context,
1663
+ ConvertToV8String(isolate,
1664
+ "operation")).ToLocal(&alphaOperationVal);
1665
+
1666
+ auto alphaOperation = ParseBlendOperation(isolate, alphaOperationVal,
1667
+ CanvasBlendOperationAdd);
1668
+
1669
+ auto alpha_val = CanvasBlendComponent{alphaSrcFactor, alphaDstFactor,
1670
+ alphaOperation};
1671
+
1672
+ auto color = blendObj->Get(context, ConvertToV8String(isolate,
1673
+ "color")).ToLocalChecked().As<v8::Object>();
1674
+
1675
+
1676
+ v8::Local<v8::Value> colorSrcFactorVal;
1677
+
1678
+ color->Get(context,
1679
+ ConvertToV8String(isolate,
1680
+ "srcFactor")).ToLocal(&colorSrcFactorVal);
1681
+
1682
+ auto colorSrcFactor = ParseBlendFactor(isolate, colorSrcFactorVal,
1683
+ CanvasBlendFactorZero);
1684
+
1685
+ v8::Local<v8::Value> colorDstFactorVal;
1686
+ color->Get(context,
1687
+ ConvertToV8String(isolate,
1688
+ "dstFactor")).ToLocal(&colorDstFactorVal);
1689
+
1690
+ auto colorDstFactor = ParseBlendFactor(isolate, colorDstFactorVal,
1691
+ CanvasBlendFactorZero);
1692
+
1693
+ v8::Local<v8::Value> colorOperationVal;
1694
+
1695
+ color->Get(context,
1696
+ ConvertToV8String(isolate,
1697
+ "operation")).ToLocal(&colorOperationVal);
1698
+
1699
+ auto colorOperation = ParseBlendOperation(isolate, colorOperationVal,
1700
+ CanvasBlendOperationAdd);
1701
+
1702
+
1703
+ auto color_val = CanvasBlendComponent{colorSrcFactor, colorDstFactor,
1704
+ colorOperation};
1705
+
1706
+
1707
+ blend = CanvasOptionalBlendState{
1708
+ CanvasOptionalBlendStateSome,
1709
+ CanvasBlendState{
1710
+ color_val, alpha_val
1711
+ }
1712
+ };
1713
+ }
1714
+
1715
+ auto targetState = CanvasColorTargetState{
1716
+ format,
1717
+ blend,
1718
+ writeMask
1719
+ };
1720
+
1721
+ targets.push_back(targetState);
1722
+ }
1723
+
1724
+ if (!targets.empty()) {
1725
+ fragment->targets = targets.data();
1726
+ fragment->targets_size = targets.size();
1727
+ }
1728
+
1729
+ v8::Local<v8::Value> constantsVal;
1730
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(
1731
+ &constantsVal);
1732
+
1733
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
1734
+ auto constants = constantsVal.As<v8::Map>();
1735
+ auto keyValues = constants->AsArray();
1736
+ auto length = keyValues->Length();
1737
+ CanvasConstants *store = nullptr;
1738
+
1739
+ if (length > 0) {
1740
+ store = canvas_native_webgpu_constants_create();
1741
+ for (int i = 0; i < length; i += 2) {
1742
+ auto k = i;
1743
+ auto v = k + 1;
1744
+
1745
+ v8::Local<v8::Value> keyVal;
1746
+ keyValues->Get(context, k).ToLocal(&keyVal);
1747
+ v8::Local<v8::Value> valueVal;
1748
+ keyValues->Get(context, v).ToLocal(&valueVal);
1749
+
1750
+
1751
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
1752
+ valueVal->IsNumber()) {
1753
+ canvas_native_webgpu_constants_insert(
1754
+ store,
1755
+ *v8::String::Utf8Value(isolate, keyVal),
1756
+ valueVal.As<v8::Number>()->Value()
1757
+ );
1758
+ }
1759
+
1760
+ }
1761
+ }
1762
+ fragment->constants = store;
1763
+ }
1764
+
1765
+
1766
+ v8::Local<v8::Value> entryPoint;
1767
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(
1768
+ &entryPoint);
1769
+
1770
+
1771
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
1772
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
1773
+ char *entry_point = (char *) malloc(ep.length());
1774
+ std::strcpy(entry_point, *ep);
1775
+
1776
+ fragment->entry_point = entry_point;
1777
+ }
1778
+
1779
+
1780
+ v8::Local<v8::Value> moduleVal;
1781
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
1782
+
1783
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
1784
+
1785
+ fragment->module = module->GetShaderModule();
1786
+
1787
+ descriptor.fragment = fragment;
1788
+
1789
+ }
1790
+
1791
+
1792
+ v8::Local<v8::Value> labelVal;
1793
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(
1794
+ &labelVal);
1795
+
1796
+
1797
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
1798
+ descriptor.label = *v8::String::Utf8Value(isolate, labelVal);
1799
+ }
1800
+
1801
+
1802
+ v8::Local<v8::Value> layoutVal;
1803
+ options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(
1804
+ &layoutVal);
1805
+
1806
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout;
1807
+
1808
+ if (layoutVal->IsString()) {
1809
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1810
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
1811
+ };
1812
+ } else if (!layoutVal->IsNullOrUndefined() && layoutVal->IsObject()) {
1813
+ auto pipeline = GPUPipelineLayoutImpl::GetPointer(layoutVal.As<v8::Object>());
1814
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1815
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeLayout,
1816
+ layout.layout = pipeline->GetPipeline()
1817
+ };
1818
+ } else {
1819
+ // todo throw ?
1820
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1821
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
1822
+ };
1823
+ }
1824
+
1825
+ descriptor.layout = layout;
1826
+
1827
+
1828
+ v8::Local<v8::Value> multisampleValue;
1829
+ options->Get(context, ConvertToV8String(isolate, "multisample")).ToLocal(
1830
+ &multisampleValue);
1831
+
1832
+
1833
+ CanvasMultisampleState *multisample = nullptr;
1834
+
1835
+ if (!multisampleValue.IsEmpty() && multisampleValue->IsObject()) {
1836
+ auto multisampleObj = multisampleValue.As<v8::Object>();
1837
+ multisample = new CanvasMultisampleState{};
1838
+ multisample->alpha_to_coverage_enabled = true;
1839
+ multisample->count = 1;
1840
+ multisample->mask = 0xFFFFFFFF;
1841
+
1842
+ v8::Local<v8::Value> alphaToCoverageEnabled;
1843
+ v8::Local<v8::Value> count;
1844
+ v8::Local<v8::Value> mask;
1845
+
1846
+ multisampleObj->Get(context, ConvertToV8String(isolate, "alphaToCoverageEnabled")).
1847
+ ToLocal(&alphaToCoverageEnabled);
1848
+
1849
+ if (!alphaToCoverageEnabled.IsEmpty() && alphaToCoverageEnabled->IsBoolean()) {
1850
+ multisample->alpha_to_coverage_enabled = alphaToCoverageEnabled->BooleanValue(
1851
+ isolate);
1852
+ }
1853
+
1854
+ multisampleObj->Get(context, ConvertToV8String(isolate, "count")).
1855
+ ToLocal(&count);
1856
+
1857
+ if (!count.IsEmpty() && count->IsUint32()) {
1858
+ multisample->count = count.As<v8::Uint32>()->Value();
1859
+ }
1860
+
1861
+ multisampleObj->Get(context, ConvertToV8String(isolate, "mask")).
1862
+ ToLocal(&mask);
1863
+
1864
+ if (!mask.IsEmpty() && mask->IsNumber()) {
1865
+ // todo verify mask
1866
+ auto maskValue = mask.As<v8::Number>()->Value();
1867
+ multisample->mask = (uint64_t) maskValue;
1868
+ }
1869
+
1870
+
1871
+ descriptor.multisample = multisample;
1872
+
1873
+ }
1874
+
1875
+
1876
+ v8::Local<v8::Value> primitiveValue;
1877
+ options->Get(context, ConvertToV8String(isolate, "primitive")).ToLocal(
1878
+ &primitiveValue);
1879
+
1880
+
1881
+ CanvasPrimitiveState *primitive = nullptr;
1882
+
1883
+ if (!primitiveValue.IsEmpty() && primitiveValue->IsObject()) {
1884
+ auto primitiveObj = primitiveValue.As<v8::Object>();
1885
+ primitive = new CanvasPrimitiveState{};
1886
+
1887
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1888
+ primitive->front_face = CanvasFrontFaceCcw;
1889
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1890
+ CanvasOptionalIndexFormatNone
1891
+ };
1892
+
1893
+ primitive->topology = CanvasPrimitiveTopologyTriangleList;
1894
+
1895
+ primitive->unclipped_depth = false;
1896
+
1897
+
1898
+ v8::Local<v8::Value> cullModeValue;
1899
+
1900
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "cullMode")).ToLocal(
1901
+ &cullModeValue)) {
1902
+ if (cullModeValue->IsUint32()) {
1903
+ auto cullMode = cullModeValue.As<v8::Uint32>()->Value();
1904
+
1905
+ switch (cullMode) {
1906
+ case 0:
1907
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1908
+ break;
1909
+ case 1:
1910
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeFront;
1911
+ break;
1912
+ case 2:
1913
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeBack;
1914
+ break;
1915
+ default:
1916
+ break;
1917
+ }
1918
+ } else if (cullModeValue->IsString()) {
1919
+
1920
+ auto cullMode = ConvertFromV8String(isolate, cullModeValue);
1921
+
1922
+ if (cullMode == "none") {
1923
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1924
+ } else if (cullMode == "front") {
1925
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeFront;
1926
+ } else if (cullMode == "back") {
1927
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeBack;
1928
+ }
1929
+ }
1930
+
1931
+ }
1932
+
1933
+ v8::Local<v8::Value> frontFaceValue;
1934
+
1935
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "frontFace")).ToLocal(
1936
+ &frontFaceValue)) {
1937
+ if (frontFaceValue->IsUint32()) {
1938
+ auto frontFace = frontFaceValue.As<v8::Uint32>()->Value();
1939
+ switch (frontFace) {
1940
+ case 0:
1941
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCcw;
1942
+ break;
1943
+ case 1:
1944
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCw;
1945
+ break;
1946
+ default:
1947
+ break;
1948
+ }
1949
+ } else if (frontFaceValue->IsString()) {
1950
+ auto frontFace = ConvertFromV8String(isolate, frontFaceValue);
1951
+ if (frontFace == "ccw") {
1952
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCcw;
1953
+ } else if (frontFace == "cw") {
1954
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCw;
1955
+ }
1956
+ }
1957
+ }
1958
+
1959
+
1960
+ v8::Local<v8::Value> stripIndexFormatValue;
1961
+
1962
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "stripIndexFormat")).ToLocal(
1963
+ &stripIndexFormatValue)) {
1964
+ if (stripIndexFormatValue->IsUint32()) {
1965
+ auto stripIndexFormat = stripIndexFormatValue.As<v8::Uint32>()->Value();
1966
+ switch (stripIndexFormat) {
1967
+ case 0:
1968
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1969
+ CanvasOptionalIndexFormatSome,
1970
+ CanvasIndexFormat::CanvasIndexFormatUint16
1971
+ };
1972
+ break;
1973
+ case 1:
1974
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1975
+ CanvasOptionalIndexFormatSome,
1976
+ CanvasIndexFormat::CanvasIndexFormatUint32
1977
+ };
1978
+ break;
1979
+ default:
1980
+ break;
1981
+ }
1982
+ } else if (stripIndexFormatValue->IsString()) {
1983
+ auto stripIndexFormat = ConvertFromV8String(isolate, stripIndexFormatValue);
1984
+
1985
+
1986
+ if (stripIndexFormat == "uint16") {
1987
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1988
+ CanvasOptionalIndexFormatSome,
1989
+ CanvasIndexFormat::CanvasIndexFormatUint16
1990
+ };
1991
+ } else if (stripIndexFormat == "uint32") {
1992
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1993
+ CanvasOptionalIndexFormatSome,
1994
+ CanvasIndexFormat::CanvasIndexFormatUint32
1995
+ };
1996
+ }
1997
+ }
1998
+ }
1999
+
2000
+
2001
+ v8::Local<v8::Value> topologyValue;
2002
+
2003
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "topology")).ToLocal(
2004
+ &topologyValue)) {
2005
+
2006
+ if (topologyValue->IsUint32()) {
2007
+ auto topology = topologyValue.As<v8::Uint32>()->Value();
2008
+ switch (topology) {
2009
+ case 0:
2010
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyPointList;
2011
+ break;
2012
+ case 1:
2013
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineList;
2014
+ break;
2015
+ case 2:
2016
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineStrip;
2017
+ break;
2018
+ case 3:
2019
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleList;
2020
+ break;
2021
+ case 4:
2022
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleStrip;
2023
+ break;
2024
+ default:
2025
+ break;
2026
+ }
2027
+ } else if (topologyValue->IsString()) {
2028
+ auto topology = ConvertFromV8String(isolate, topologyValue);
2029
+ if (topology == "line-list") {
2030
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineList;
2031
+ } else if (topology == "line-strip") {
2032
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineStrip;
2033
+ } else if (topology == "point-list") {
2034
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyPointList;
2035
+ } else if (topology == "triangle-list") {
2036
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleList;
2037
+ } else if (topology == "triangle-strip") {
2038
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleStrip;
2039
+ }
2040
+ }
2041
+
2042
+ }
2043
+
2044
+
2045
+ v8::Local<v8::Value> unclippedDepthValue;
2046
+ primitiveObj->Get(context, ConvertToV8String(isolate, "unclippedDepth")).ToLocal(
2047
+ &unclippedDepthValue);
2048
+
2049
+ if (!unclippedDepthValue.IsEmpty() && unclippedDepthValue->IsBoolean()) {
2050
+ primitive->unclipped_depth = unclippedDepthValue->BooleanValue(isolate);
2051
+ }
2052
+
2053
+ descriptor.primitive = primitive;
2054
+
2055
+ }
2056
+
2057
+
2058
+ v8::Local<v8::Value> vertexValue;
2059
+ options->Get(context, ConvertToV8String(isolate, "vertex")).ToLocal(
2060
+ &vertexValue);
2061
+
2062
+
2063
+ CanvasVertexState *vertex = nullptr;
2064
+
2065
+ std::vector<CanvasVertexBufferLayout> bufferLayout;
2066
+
2067
+ std::vector<std::vector<CanvasVertexAttribute>> attributes;
2068
+
2069
+ if (!vertexValue.IsEmpty() && vertexValue->IsObject()) {
2070
+ auto vertexObj = vertexValue.As<v8::Object>();
2071
+ vertex = new CanvasVertexState{};
2072
+
2073
+ v8::Local<v8::Value> moduleVal;
2074
+ vertexObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
2075
+
2076
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
2077
+
2078
+ vertex->module = module->GetShaderModule();
2079
+
2080
+ v8::Local<v8::Value> constantsVal;
2081
+ vertexObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(&constantsVal);
2082
+
2083
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
2084
+ auto constants = constantsVal.As<v8::Map>();
2085
+ auto keyValues = constants->AsArray();
2086
+ auto len = keyValues->Length();
2087
+ CanvasConstants *store = nullptr;
2088
+
2089
+ if (len > 0) {
2090
+ store = canvas_native_webgpu_constants_create();
2091
+ for (int i = 0; i < len; i += 2) {
2092
+ auto k = i;
2093
+ auto v = k + 1;
2094
+
2095
+ v8::Local<v8::Value> keyVal;
2096
+ keyValues->Get(context, k).ToLocal(&keyVal);
2097
+ v8::Local<v8::Value> valueVal;
2098
+ keyValues->Get(context, v).ToLocal(&valueVal);
2099
+
2100
+
2101
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
2102
+ valueVal->IsNumber()) {
2103
+ canvas_native_webgpu_constants_insert(
2104
+ store,
2105
+ *v8::String::Utf8Value(isolate, keyVal),
2106
+ valueVal.As<v8::Number>()->Value()
2107
+ );
2108
+ }
2109
+
2110
+ }
2111
+ }
2112
+
2113
+ vertex->constants = store;
2114
+
2115
+ }
2116
+
2117
+ v8::Local<v8::Value> buffersVal;
2118
+ vertexObj->Get(context, ConvertToV8String(isolate, "buffers")).ToLocal(&buffersVal);
2119
+
2120
+ uint64_t stride = 0;
2121
+ if (!buffersVal.IsEmpty() && buffersVal->IsArray()) {
2122
+ auto buffers = buffersVal.As<v8::Array>();
2123
+ auto len = buffers->Length();
2124
+
2125
+ for (int i = 0; i < len; i++) {
2126
+ auto buffer = buffers->Get(context, i).ToLocalChecked().As<v8::Object>();
2127
+
2128
+ v8::Local<v8::Value> arrayStride;
2129
+
2130
+ buffer->Get(context, ConvertToV8String(isolate, "arrayStride")).ToLocal(
2131
+ &arrayStride);
2132
+
2133
+ if (!arrayStride.IsEmpty() && arrayStride->IsNumber()) {
2134
+ stride = (uint64_t) arrayStride.As<v8::Number>()->Value();
2135
+ }
2136
+
2137
+ std::vector<CanvasVertexAttribute> attributes_;
2138
+
2139
+ v8::Local<v8::Value> attributesValue;
2140
+
2141
+ buffer->Get(context, ConvertToV8String(isolate, "attributes")).ToLocal(
2142
+ &attributesValue);
2143
+
2144
+ if (!attributesValue.IsEmpty() && attributesValue->IsArray()) {
2145
+ auto attributes_array = attributesValue.As<v8::Array>();
2146
+ auto attributes_len = attributes_array->Length();
2147
+
2148
+ for (int j = 0; j < attributes_len; j++) {
2149
+ auto attr = attributes_array->Get(context,
2150
+ j).ToLocalChecked().As<v8::Object>();
2151
+ auto format = attr->Get(context, ConvertToV8String(isolate,
2152
+ "format")).ToLocalChecked()->Uint32Value(
2153
+ context).ToChecked();
2154
+
2155
+ auto offset = (uint64_t) attr->Get(context, ConvertToV8String(isolate,
2156
+ "offset")).ToLocalChecked()->NumberValue(
2157
+ context).ToChecked();
2158
+ auto shaderLocation = attr->Get(context, ConvertToV8String(isolate,
2159
+ "shaderLocation")).ToLocalChecked()->Uint32Value(
2160
+ context).ToChecked();
2161
+
2162
+ auto attribute = CanvasVertexAttribute{
2163
+ (CanvasVertexFormat) format,
2164
+ offset,
2165
+ shaderLocation
2166
+ };
2167
+
2168
+ attributes_.push_back(attribute);
2169
+ }
2170
+
2171
+ attributes.push_back(attributes_);
2172
+ }
2173
+
2174
+
2175
+ CanvasVertexStepMode stepMode = CanvasVertexStepModeVertex;
2176
+
2177
+ v8::Local<v8::Value> stepModeVal;
2178
+
2179
+ buffer->Get(context, ConvertToV8String(isolate, "stepMode")).ToLocal(
2180
+ &stepModeVal);
2181
+
2182
+
2183
+ if (!stepModeVal.IsEmpty()) {
2184
+ if (stepModeVal->IsUint32()) {
2185
+ switch (stepModeVal.As<v8::Uint32>()->Value()) {
2186
+ case 0:
2187
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeVertex;
2188
+ break;
2189
+ case 1:
2190
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeInstance;
2191
+ break;
2192
+ }
2193
+ } else if (stepModeVal->IsString()) {
2194
+ auto stepModeStr = ConvertFromV8String(isolate, stepModeVal);
2195
+ if (stepModeStr == "vertex") {
2196
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeVertex;
2197
+ } else if (stepModeStr == "instance") {
2198
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeInstance;
2199
+ }
2200
+ }
2201
+ }
2202
+
2203
+ auto vertexBufferLayout = CanvasVertexBufferLayout{
2204
+ stride,
2205
+ stepMode,
2206
+ attributes[i].data(),
2207
+ attributes[i].size()
2208
+ };
2209
+
2210
+ bufferLayout.push_back(vertexBufferLayout);
2211
+ }
2212
+
2213
+ vertex->buffers = bufferLayout.data();
2214
+ vertex->buffers_size = bufferLayout.size();
2215
+
2216
+ }
2217
+
2218
+
2219
+ v8::Local<v8::Value> entryPoint;
2220
+ vertexObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(&entryPoint);
2221
+
2222
+
2223
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
2224
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
2225
+ char *entry_point = (char *) malloc(ep.length());
2226
+ std::strcpy(entry_point, *ep);
2227
+ vertex->entry_point = entry_point;
2228
+ }
2229
+
2230
+ descriptor.vertex = vertex;
2231
+
2232
+ }
2233
+
2234
+
2235
+ auto pipeline = canvas_native_webgpu_device_create_render_pipeline(ptr->GetGPUDevice(),
2236
+ &descriptor);
2237
+
2238
+
2239
+ if (descriptor.fragment != nullptr) {
2240
+ if (descriptor.fragment->entry_point != nullptr) {
2241
+ free((void *) descriptor.fragment->entry_point);
2242
+ }
2243
+ }
2244
+
2245
+ if (descriptor.primitive != nullptr) {
2246
+ delete descriptor.primitive;
2247
+ }
2248
+
2249
+ if (descriptor.multisample != nullptr) {
2250
+ delete descriptor.multisample;
2251
+ }
2252
+
2253
+
2254
+ if (descriptor.vertex != nullptr) {
2255
+ if (descriptor.vertex->constants != nullptr) {
2256
+ canvas_native_webgpu_constants_destroy(
2257
+ (CanvasConstants *) descriptor.vertex->constants);
2258
+ }
2259
+
2260
+ if (descriptor.vertex->entry_point != nullptr) {
2261
+ free((void *) descriptor.vertex->entry_point);
2262
+ }
2263
+
2264
+ }
2265
+
2266
+ if(descriptor.depth_stencil != nullptr){
2267
+ delete descriptor.depth_stencil;
2268
+ }
2269
+
2270
+
2271
+ if (pipeline != nullptr) {
2272
+ auto ret = GPURenderPipelineImpl::NewInstance(isolate, new GPURenderPipelineImpl(pipeline));
2273
+ args.GetReturnValue().Set(ret);
2274
+ return;
2275
+ }
2276
+
2277
+ args.GetReturnValue().SetUndefined();
2278
+ }
2279
+
2280
+ void GPUDeviceImpl::CreateSampler(const v8::FunctionCallbackInfo<v8::Value> &args) {
2281
+ GPUDeviceImpl *ptr = GetPointer(args.This());
2282
+ if (ptr == nullptr) {
2283
+ return;
2284
+ }
2285
+ auto isolate = args.GetIsolate();
2286
+ auto context = isolate->GetCurrentContext();
2287
+
2288
+
2289
+ auto optionsVal = args[0];
2290
+
2291
+ if (!optionsVal->IsNullOrUndefined() && optionsVal->IsObject()) {
2292
+ auto options = optionsVal.As<v8::Object>();
2293
+
2294
+ v8::Local<v8::Value> labelVal;
2295
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
2296
+
2297
+ char *label = nullptr;
2298
+
2299
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
2300
+ label = *v8::String::Utf8Value(isolate, labelVal);
2301
+ }
2302
+
2303
+ auto addressModeU = CanvasAddressModeClampToEdge;
2304
+
2305
+ v8::Local<v8::Value> addressModeUVal;
2306
+ options->Get(context, ConvertToV8String(isolate, "addressModeU")).ToLocal(&addressModeUVal);
2307
+ auto addressModeUStr = ConvertFromV8String(isolate, addressModeUVal);
2308
+ if (addressModeUStr == "repeat") {
2309
+ addressModeU = CanvasAddressModeRepeat;
2310
+ } else if (addressModeUStr == "mirror-repeat") {
2311
+ addressModeU = CanvasAddressModeMirrorRepeat;
2312
+ }
2313
+
2314
+
2315
+ auto addressModeV = CanvasAddressModeClampToEdge;
2316
+
2317
+ v8::Local<v8::Value> addressModeVVal;
2318
+ options->Get(context, ConvertToV8String(isolate, "addressModeV")).ToLocal(&addressModeVVal);
2319
+ auto addressModeVStr = ConvertFromV8String(isolate, addressModeVVal);
2320
+ if (addressModeVStr == "repeat") {
2321
+ addressModeV = CanvasAddressModeRepeat;
2322
+ } else if (addressModeVStr == "mirror-repeat") {
2323
+ addressModeV = CanvasAddressModeMirrorRepeat;
2324
+ }
2325
+
2326
+
2327
+ auto addressModeW = CanvasAddressModeClampToEdge;
2328
+
2329
+ v8::Local<v8::Value> addressModeWVal;
2330
+ options->Get(context, ConvertToV8String(isolate, "addressModeW")).ToLocal(&addressModeWVal);
2331
+ auto addressModeWStr = ConvertFromV8String(isolate, addressModeWVal);
2332
+ if (addressModeWStr == "repeat") {
2333
+ addressModeW = CanvasAddressModeRepeat;
2334
+ } else if (addressModeWStr == "mirror-repeat") {
2335
+ addressModeW = CanvasAddressModeMirrorRepeat;
2336
+ }
2337
+
2338
+
2339
+ auto magFilter = CanvasFilterModeNearest;
2340
+
2341
+ v8::Local<v8::Value> magFilterVal;
2342
+ options->Get(context, ConvertToV8String(isolate, "magFilter")).ToLocal(&magFilterVal);
2343
+ auto magFilterStr = ConvertFromV8String(isolate, magFilterVal);
2344
+ if (magFilterStr == "linear") {
2345
+ magFilter = CanvasFilterModeLinear;
2346
+ }
2347
+
2348
+ auto minFilter = CanvasFilterModeNearest;
2349
+
2350
+ v8::Local<v8::Value> minFilterVal;
2351
+ options->Get(context, ConvertToV8String(isolate, "minFilter")).ToLocal(&minFilterVal);
2352
+ auto minFilterStr = ConvertFromV8String(isolate, minFilterVal);
2353
+ if (minFilterStr == "linear") {
2354
+ minFilter = CanvasFilterModeLinear;
2355
+ }
2356
+
2357
+
2358
+ auto mipmapFilter = CanvasFilterModeNearest;
2359
+
2360
+ v8::Local<v8::Value> mipmapFilterVal;
2361
+ options->Get(context, ConvertToV8String(isolate, "mipmapFilter")).ToLocal(&mipmapFilterVal);
2362
+ auto mipmapFilterStr = ConvertFromV8String(isolate, mipmapFilterVal);
2363
+ if (mipmapFilterStr == "linear") {
2364
+ mipmapFilter = CanvasFilterModeLinear;
2365
+ }
2366
+
2367
+
2368
+ float lodMinClamp = 0;
2369
+
2370
+ v8::Local<v8::Value> lodMinClampVal;
2371
+ options->Get(context, ConvertToV8String(isolate, "lodMinClamp")).ToLocal(&lodMinClampVal);
2372
+
2373
+ if (!lodMinClampVal.IsEmpty() && lodMinClampVal->IsNumber()) {
2374
+ lodMinClamp = (float) lodMinClampVal->NumberValue(context).FromJust();
2375
+ }
2376
+
2377
+
2378
+ float lodMaxClamp = 32;
2379
+
2380
+ v8::Local<v8::Value> lodMaxClampVal;
2381
+ options->Get(context, ConvertToV8String(isolate, "lodMaxClamp")).ToLocal(&lodMaxClampVal);
2382
+
2383
+ if (!lodMaxClampVal.IsEmpty() && lodMaxClampVal->IsNumber()) {
2384
+ lodMaxClamp = (float) lodMaxClampVal->NumberValue(context).FromJust();
2385
+ }
2386
+
2387
+
2388
+ CanvasOptionalCompareFunction compare{
2389
+ CanvasOptionalCompareFunctionNone
2390
+ };
2391
+
2392
+
2393
+ v8::Local<v8::Value> compareVal;
2394
+ options->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(&compareVal);
2395
+
2396
+ auto compareStr = ConvertFromV8String(isolate, compareVal);
2397
+
2398
+ if (compareStr == "never") {
2399
+ compare.tag = CanvasOptionalCompareFunctionSome;
2400
+ compare.some = CanvasCompareFunctionNever;
2401
+ } else if (compareStr == "less") {
2402
+ compare.tag = CanvasOptionalCompareFunctionSome;
2403
+ compare.some = CanvasCompareFunctionLess;
2404
+ } else if (compareStr == "equal") {
2405
+ compare.tag = CanvasOptionalCompareFunctionSome;
2406
+ compare.some = CanvasCompareFunctionEqual;
2407
+ } else if (compareStr == "less-equal") {
2408
+ compare.tag = CanvasOptionalCompareFunctionSome;
2409
+ compare.some = CanvasCompareFunctionLessEqual;
2410
+ } else if (compareStr == "greater") {
2411
+ compare.tag = CanvasOptionalCompareFunctionSome;
2412
+ compare.some = CanvasCompareFunctionGreater;
2413
+ } else if (compareStr == "not-equal") {
2414
+ compare.tag = CanvasOptionalCompareFunctionSome;
2415
+ compare.some = CanvasCompareFunctionNotEqual;
2416
+ } else if (compareStr == "greater-equal") {
2417
+ compare.tag = CanvasOptionalCompareFunctionSome;
2418
+ compare.some = CanvasCompareFunctionGreaterEqual;
2419
+ } else if (compareStr == "always") {
2420
+ compare.tag = CanvasOptionalCompareFunctionSome;
2421
+ compare.some = CanvasCompareFunctionAlways;
2422
+ }
2423
+
2424
+ uint16_t maxAnisotropy = 1;
2425
+
2426
+ v8::Local<v8::Value> maxAnisotropyVal;
2427
+ options->Get(context, ConvertToV8String(isolate, "maxAnisotropy")).ToLocal(
2428
+ &maxAnisotropyVal);
2429
+
2430
+ if (!maxAnisotropyVal.IsEmpty() && maxAnisotropyVal->IsNumber()) {
2431
+ maxAnisotropy = (u_short) maxAnisotropyVal->NumberValue(context).FromJust();
2432
+ }
2433
+
2434
+
2435
+ CanvasCreateSamplerDescriptor descriptor{
2436
+ label,
2437
+ addressModeU,
2438
+ addressModeV,
2439
+ addressModeW,
2440
+ magFilter,
2441
+ minFilter,
2442
+ mipmapFilter,
2443
+ lodMinClamp,
2444
+ lodMaxClamp,
2445
+ compare,
2446
+ maxAnisotropy
2447
+ };
2448
+
2449
+ auto sampler = canvas_native_webgpu_device_create_sampler(ptr->GetGPUDevice(), &descriptor);
2450
+ if (sampler != nullptr) {
2451
+ auto ret = GPUSamplerImpl::NewInstance(isolate, new GPUSamplerImpl(sampler));
2452
+ args.GetReturnValue().Set(ret);
2453
+ return;
2454
+ }
2455
+
2456
+ } else {
2457
+ auto sampler = canvas_native_webgpu_device_create_sampler(ptr->GetGPUDevice(), nullptr);
2458
+ if (sampler != nullptr) {
2459
+ auto ret = GPUSamplerImpl::NewInstance(isolate, new GPUSamplerImpl(sampler));
2460
+ args.GetReturnValue().Set(ret);
2461
+ return;
2462
+ }
2463
+ }
2464
+
2465
+ args.GetReturnValue().SetUndefined();
2466
+
2467
+ }
2468
+
2469
+ void GPUDeviceImpl::CreateShaderModule(const v8::FunctionCallbackInfo<v8::Value> &args) {
2470
+ GPUDeviceImpl *ptr = GetPointer(args.This());
2471
+ if (ptr == nullptr) {
2472
+ return;
2473
+ }
2474
+ auto isolate = args.GetIsolate();
2475
+ auto context = isolate->GetCurrentContext();
2476
+
2477
+ auto descVal = args[0];
2478
+
2479
+
2480
+ if (!descVal->IsNullOrUndefined() && descVal->IsObject()) {
2481
+ auto desc = descVal.As<v8::Object>();
2482
+
2483
+
2484
+ v8::Local<v8::Value> labelVal;
2485
+ desc->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
2486
+
2487
+ char *label = nullptr;
2488
+
2489
+ if (!labelVal.IsEmpty() && labelVal->IsString()) {
2490
+ label = *v8::String::Utf8Value(isolate, labelVal);
2491
+ }
2492
+
2493
+ v8::Local<v8::Value> codeVal;
2494
+
2495
+ std::string code;
2496
+ if (desc->Get(context, ConvertToV8String(isolate, "code")).ToLocal(&codeVal) && codeVal->IsString()) {
2497
+ code = ConvertFromV8String(isolate, codeVal);
2498
+ }
2499
+
2500
+ auto module = canvas_native_webgpu_device_create_shader_module(ptr->GetGPUDevice(), label,
2501
+ code.c_str());
2502
+
2503
+ if (module != nullptr) {
2504
+ auto instance = new GPUShaderModuleImpl(module);
2505
+ auto ret = GPUShaderModuleImpl::NewInstance(isolate, instance);
2506
+ args.GetReturnValue().Set(ret);
2507
+ return;
2508
+ }
2509
+
2510
+ }
2511
+
2512
+ args.GetReturnValue().SetUndefined();
2513
+
2514
+
2515
+ }
2516
+
2517
+ void GPUDeviceImpl::CreateTexture(const v8::FunctionCallbackInfo<v8::Value> &args) {
2518
+ GPUDeviceImpl *ptr = GetPointer(args.This());
2519
+ if (ptr == nullptr) {
2520
+ return;
2521
+ }
2522
+ auto isolate = args.GetIsolate();
2523
+ auto context = isolate->GetCurrentContext();
2524
+
2525
+ CanvasCreateTextureDescriptor descriptor{};
2526
+ descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD2;
2527
+ descriptor.depthOrArrayLayers = 1;
2528
+ descriptor.sampleCount = 1;
2529
+ descriptor.mipLevelCount = 1;
2530
+ descriptor.view_formats = nullptr;
2531
+ descriptor.view_formats_size = 0;
2532
+
2533
+
2534
+ char *error = nullptr;
2535
+
2536
+
2537
+ auto optionsVal = args[0];
2538
+
2539
+
2540
+ if (optionsVal->IsObject()) {
2541
+ auto options = optionsVal.As<v8::Object>();
2542
+ v8::Local<v8::Value> depthOrArrayLayersVal;
2543
+
2544
+ if (options->Get(context, ConvertToV8String(isolate, "depthOrArrayLayers")).ToLocal(
2545
+ &depthOrArrayLayersVal) && depthOrArrayLayersVal->IsUint32()) {
2546
+ descriptor.depthOrArrayLayers = depthOrArrayLayersVal.As<v8::Uint32>()->Value();
2547
+ }
2548
+
2549
+
2550
+ v8::Local<v8::Value> widthVal;
2551
+
2552
+ if ( options->Get(context, ConvertToV8String(isolate, "width")).ToLocal(
2553
+ &widthVal) &&widthVal->IsUint32()) {
2554
+ descriptor.width = widthVal.As<v8::Uint32>()->Value();
2555
+ }
2556
+
2557
+
2558
+ v8::Local<v8::Value> heightVal;
2559
+
2560
+ if (options->Get(context, ConvertToV8String(isolate, "height")).ToLocal(
2561
+ &heightVal) && heightVal->IsUint32()) {
2562
+ descriptor.height = heightVal.As<v8::Uint32>()->Value();
2563
+ }
2564
+
2565
+
2566
+ v8::Local<v8::Value> usageVal;
2567
+
2568
+ if (options->Get(context, ConvertToV8String(isolate, "usage")).ToLocal(
2569
+ &usageVal) && usageVal->IsUint32()) {
2570
+ descriptor.usage = usageVal.As<v8::Uint32>()->Value();
2571
+ }
2572
+
2573
+
2574
+ v8::Local<v8::Value> sampleCountVal;
2575
+ options->Get(context, ConvertToV8String(isolate, "sampleCount")).ToLocal(
2576
+ &sampleCountVal);
2577
+
2578
+ if (sampleCountVal->IsUint32()) {
2579
+ descriptor.sampleCount = sampleCountVal.As<v8::Uint32>()->Value();
2580
+ }
2581
+
2582
+
2583
+ v8::Local<v8::Value> mipLevelCountVal;
2584
+ options->Get(context, ConvertToV8String(isolate, "mipLevelCount")).ToLocal(
2585
+ &mipLevelCountVal);
2586
+
2587
+ if (mipLevelCountVal->IsUint32()) {
2588
+ descriptor.mipLevelCount = mipLevelCountVal.As<v8::Uint32>()->Value();
2589
+ }
2590
+
2591
+
2592
+ v8::Local<v8::Value> dimensionVal;
2593
+ options->Get(context, ConvertToV8String(isolate, "dimension")).ToLocal(
2594
+ &dimensionVal);
2595
+
2596
+ if (dimensionVal->IsString()) {
2597
+ auto dimension = ConvertFromV8String(isolate, dimensionVal);
2598
+
2599
+ // todo use enum
2600
+ if (dimension == "1d") {
2601
+ descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD1;
2602
+ } else if (dimension == "2d") {
2603
+ descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD2;
2604
+ } else if (dimension == "3d") {
2605
+ descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD3;
2606
+ }
2607
+
2608
+ }
2609
+
2610
+
2611
+ v8::Local<v8::Value> formatVal;
2612
+
2613
+ if (options->Get(context, ConvertToV8String(isolate, "format")).ToLocal(
2614
+ &formatVal) && formatVal->IsString()) {
2615
+ auto format = ConvertFromV8String(isolate, formatVal);
2616
+
2617
+ // todo use enum
2618
+ //CanvasGPUTextureFormat fmt{};
2619
+
2620
+ auto fmtOpt = canvas_native_webgpu_enum_string_to_gpu_texture(format.c_str());
2621
+ if (fmtOpt.tag == CanvasOptionalGPUTextureFormatSome) {
2622
+ descriptor.format = fmtOpt.some;
2623
+ }
2624
+ // if (strcmp(format.c_str(), "bgra8unorm") == 0) {
2625
+ // fmt.tag = CanvasGPUTextureFormat_Tag::CanvasGPUTextureFormatBgra8Unorm;
2626
+ // descriptor.format = fmt;
2627
+ // } else if (strcmp(format.c_str(), "rgba8unorm") == 0) {
2628
+ // fmt.tag = CanvasGPUTextureFormat_Tag::CanvasGPUTextureFormatRgba8Unorm;
2629
+ // descriptor.format = fmt;
2630
+ // }
2631
+
2632
+ }
2633
+
2634
+ }
2635
+
2636
+ auto texture = canvas_native_webgpu_device_create_texture(ptr->GetGPUDevice(), &descriptor);
2637
+
2638
+ if (texture != nullptr) {
2639
+ auto textureImpl = new GPUTextureImpl(texture);
2640
+ auto ret = GPUTextureImpl::NewInstance(isolate, textureImpl);
2641
+ args.GetReturnValue().Set(ret);
2642
+
2643
+ } else {
2644
+ if (error != nullptr) {
2645
+ isolate->ThrowError(ConvertToV8String(isolate, error));
2646
+ }
2647
+
2648
+ args.GetReturnValue().SetUndefined();
2649
+ }
2650
+ }
2651
+
2652
+ void GPUDeviceImpl::Destroy(const v8::FunctionCallbackInfo<v8::Value> &args) {
2653
+ GPUDeviceImpl *ptr = GetPointer(args.This());
2654
+ if (ptr == nullptr) {
2655
+ return;
2656
+ }
2657
+ canvas_native_webgpu_device_destroy(ptr->GetGPUDevice());
2658
+ }
2659
+
2660
+ void GPUDeviceImpl::PopErrorScope(const v8::FunctionCallbackInfo<v8::Value> &args) {
2661
+ GPUDeviceImpl *ptr = GetPointer(args.This());
2662
+ if (ptr == nullptr) {
2663
+ return;
2664
+ }
2665
+ auto isolate = args.GetIsolate();
2666
+ auto cb = args[0];
2667
+ auto callback = new JSICallback(isolate, cb.As<v8::Function>());
2668
+
2669
+ canvas_native_webgpu_device_pop_error_scope(ptr->GetGPUDevice(), [](CanvasGPUErrorType type,
2670
+ char *msg,
2671
+ void *data) {
2672
+ auto cb = static_cast<JSICallback *>(data);
2673
+
2674
+ v8::Isolate *isolate = cb->isolate_;
2675
+ v8::Locker locker(isolate);
2676
+ v8::Isolate::Scope isolate_scope(
2677
+ isolate);
2678
+ v8::HandleScope handle_scope(
2679
+ isolate);
2680
+ v8::Local<v8::Function> callback = cb->callback_->Get(
2681
+ isolate);
2682
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
2683
+ v8::Context::Scope context_scope(
2684
+ context);
2685
+ v8::Local<v8::Value> typ;
2686
+ v8::Local<v8::Value> message;
2687
+ switch (type) {
2688
+ case CanvasGPUErrorType::CanvasGPUErrorTypeNone:
2689
+ typ = v8::Number::New(
2690
+ isolate, 0);
2691
+ message = v8::Null(
2692
+ isolate);
2693
+ break;
2694
+ case CanvasGPUErrorType::CanvasGPUErrorTypeLost:
2695
+ typ = v8::Number::New(
2696
+ isolate, 1);
2697
+ message = v8::Null(
2698
+ isolate);
2699
+ break;
2700
+ case CanvasGPUErrorType::CanvasGPUErrorTypeOutOfMemory:
2701
+ typ = v8::Number::New(
2702
+ isolate, 2);
2703
+ message = v8::Null(
2704
+ isolate);
2705
+ break;
2706
+ case CanvasGPUErrorType::CanvasGPUErrorTypeValidation:
2707
+ typ = v8::Number::New(
2708
+ isolate, 3);
2709
+ message = ConvertToV8String(
2710
+ isolate, msg);
2711
+ break;
2712
+ case CanvasGPUErrorType::CanvasGPUErrorTypeInternal:
2713
+ typ = v8::Number::New(
2714
+ isolate, 4);
2715
+ message = v8::Null(
2716
+ isolate);
2717
+ break;
2718
+ }
2719
+ v8::Local<v8::Value> args[2] = {
2720
+ typ, message
2721
+ };
2722
+
2723
+ callback->Call(context,
2724
+ context->Global(),
2725
+ 2, args);
2726
+
2727
+ delete static_cast<JSICallback *>(data);
2728
+ }, callback);
2729
+ }
2730
+
2731
+ void GPUDeviceImpl::PushErrorScope(const v8::FunctionCallbackInfo<v8::Value> &args) {
2732
+ GPUDeviceImpl *ptr = GetPointer(args.This());
2733
+ if (ptr == nullptr) {
2734
+ return;
2735
+ }
2736
+ auto scope = ConvertFromV8String(args.GetIsolate(), args[0]);
2737
+
2738
+ if (scope == "internal") {
2739
+ canvas_native_webgpu_device_push_error_scope(ptr->GetGPUDevice(),
2740
+ CanvasGPUErrorFilterInternal);
2741
+ } else if (scope == "out-of-memory") {
2742
+ canvas_native_webgpu_device_push_error_scope(ptr->GetGPUDevice(),
2743
+ CanvasGPUErrorFilterOutOfMemory);
2744
+ } else if (scope == "validation") {
2745
+ canvas_native_webgpu_device_push_error_scope(ptr->GetGPUDevice(),
2746
+ CanvasGPUErrorFilterValidation);
2747
+ }
2748
+
2749
+
2750
+ }