@nativescript/canvas 2.0.0-beta.9 → 2.0.0-rc.0

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 (454) hide show
  1. package/Canvas/common.d.ts +15 -24
  2. package/Canvas/common.js +147 -203
  3. package/Canvas/common.js.map +1 -1
  4. package/Canvas/index.android.d.ts +13 -15
  5. package/Canvas/index.android.js +152 -151
  6. package/Canvas/index.android.js.map +1 -1
  7. package/Canvas/index.d.ts +23 -11
  8. package/Canvas/index.ios.d.ts +14 -6
  9. package/Canvas/index.ios.js +213 -124
  10. package/Canvas/index.ios.js.map +1 -1
  11. package/Canvas/utils.d.ts +3 -0
  12. package/Canvas/utils.js +85 -0
  13. package/Canvas/utils.js.map +1 -0
  14. package/Canvas2D/CanvasRenderingContext2D/index.d.ts +4 -2
  15. package/Canvas2D/CanvasRenderingContext2D/index.js +79 -85
  16. package/Canvas2D/CanvasRenderingContext2D/index.js.map +1 -1
  17. package/Canvas2D/DOMMatrix/index.d.ts +14 -0
  18. package/Canvas2D/DOMMatrix/index.js +62 -0
  19. package/Canvas2D/DOMMatrix/index.js.map +1 -1
  20. package/Canvas2D/ImageData/index.js +4 -6
  21. package/Canvas2D/ImageData/index.js.map +1 -1
  22. package/Canvas2D/Path2D/index.js.map +1 -1
  23. package/Dom/Dom.js +8 -1
  24. package/Dom/Dom.js.map +1 -1
  25. package/Dom/Group.d.ts +1 -2
  26. package/Dom/Group.js.map +1 -1
  27. package/Dom/Image.d.ts +4 -1
  28. package/Dom/Image.js +15 -2
  29. package/Dom/Image.js.map +1 -1
  30. package/Dom/Paint.d.ts +1 -1
  31. package/Dom/Paint.js.map +1 -1
  32. package/Dom/Text.js.map +1 -1
  33. package/Dom/shaders/LinearGradient.js.map +1 -1
  34. package/Dom/shaders/TwoPointConicalGradient.js.map +1 -1
  35. package/Dom/shapes/Atlas.js.map +1 -1
  36. package/Dom/shapes/Circle.js.map +1 -1
  37. package/Dom/shapes/Line.js.map +1 -1
  38. package/Dom/shapes/Oval.js.map +1 -1
  39. package/Dom/shapes/Path.d.ts +1 -1
  40. package/Dom/shapes/Path.js.map +1 -1
  41. package/Dom/shapes/Rect.js.map +1 -1
  42. package/Dom/shapes/RoundedRect.js.map +1 -1
  43. package/Dom/shapes/index.js.map +1 -1
  44. package/Fonts/FontFace.android.d.ts +46 -0
  45. package/Fonts/FontFace.android.js +197 -0
  46. package/Fonts/FontFace.android.js.map +1 -0
  47. package/Fonts/FontFace.ios.d.ts +45 -0
  48. package/Fonts/FontFace.ios.js +169 -0
  49. package/Fonts/FontFace.ios.js.map +1 -0
  50. package/Fonts/FontFaceSet.android.d.ts +31 -0
  51. package/Fonts/FontFaceSet.android.js +119 -0
  52. package/Fonts/FontFaceSet.android.js.map +1 -0
  53. package/Fonts/FontFaceSet.ios.d.ts +31 -0
  54. package/Fonts/FontFaceSet.ios.js +109 -0
  55. package/Fonts/FontFaceSet.ios.js.map +1 -0
  56. package/Fonts/index.d.ts +2 -0
  57. package/Fonts/index.js +3 -0
  58. package/Fonts/index.js.map +1 -0
  59. package/ImageAsset/index.d.ts +8 -3
  60. package/ImageAsset/index.js +206 -11
  61. package/ImageAsset/index.js.map +1 -1
  62. package/ImageBitmap/index.js +110 -23
  63. package/ImageBitmap/index.js.map +1 -1
  64. package/README.md +62 -3
  65. package/TextDecoder/index.js +3 -3
  66. package/TextDecoder/index.js.map +1 -1
  67. package/TextEncoder/index.js +3 -3
  68. package/TextEncoder/index.js.map +1 -1
  69. package/WebGL/WebGLExtensions/index.js +5 -5
  70. package/WebGL/WebGLExtensions/index.js.map +1 -1
  71. package/WebGL/WebGLRenderingContext/common.d.ts +1 -1
  72. package/WebGL/WebGLRenderingContext/common.js.map +1 -1
  73. package/WebGL/WebGLRenderingContext/index.d.ts +1 -0
  74. package/WebGL/WebGLRenderingContext/index.js +144 -46
  75. package/WebGL/WebGLRenderingContext/index.js.map +1 -1
  76. package/WebGL2/WebGL2RenderingContext/index.d.ts +1 -0
  77. package/WebGL2/WebGL2RenderingContext/index.js +7 -8
  78. package/WebGL2/WebGL2RenderingContext/index.js.map +1 -1
  79. package/WebGPU/Constants.d.ts +36 -0
  80. package/WebGPU/Constants.js +42 -0
  81. package/WebGPU/Constants.js.map +1 -0
  82. package/WebGPU/Errors.d.ts +18 -0
  83. package/WebGPU/Errors.js +21 -0
  84. package/WebGPU/Errors.js.map +1 -0
  85. package/WebGPU/GPU.d.ts +13 -0
  86. package/WebGPU/GPU.js +36 -0
  87. package/WebGPU/GPU.js.map +1 -0
  88. package/WebGPU/GPUAdapter.d.ts +26 -0
  89. package/WebGPU/GPUAdapter.js +93 -0
  90. package/WebGPU/GPUAdapter.js.map +1 -0
  91. package/WebGPU/GPUAdapterInfo.d.ts +9 -0
  92. package/WebGPU/GPUAdapterInfo.js +24 -0
  93. package/WebGPU/GPUAdapterInfo.js.map +1 -0
  94. package/WebGPU/GPUBindGroup.d.ts +6 -0
  95. package/WebGPU/GPUBindGroup.js +15 -0
  96. package/WebGPU/GPUBindGroup.js.map +1 -0
  97. package/WebGPU/GPUBindGroupLayout.d.ts +6 -0
  98. package/WebGPU/GPUBindGroupLayout.js +15 -0
  99. package/WebGPU/GPUBindGroupLayout.js.map +1 -0
  100. package/WebGPU/GPUBuffer.d.ts +15 -0
  101. package/WebGPU/GPUBuffer.js +66 -0
  102. package/WebGPU/GPUBuffer.js.map +1 -0
  103. package/WebGPU/GPUCanvasContext.d.ts +42 -0
  104. package/WebGPU/GPUCanvasContext.js +149 -0
  105. package/WebGPU/GPUCanvasContext.js.map +1 -0
  106. package/WebGPU/GPUCommandBuffer.d.ts +6 -0
  107. package/WebGPU/GPUCommandBuffer.js +15 -0
  108. package/WebGPU/GPUCommandBuffer.js.map +1 -0
  109. package/WebGPU/GPUCommandEncoder.d.ts +35 -0
  110. package/WebGPU/GPUCommandEncoder.js +163 -0
  111. package/WebGPU/GPUCommandEncoder.js.map +1 -0
  112. package/WebGPU/GPUComputePassEncoder.d.ts +17 -0
  113. package/WebGPU/GPUComputePassEncoder.js +53 -0
  114. package/WebGPU/GPUComputePassEncoder.js.map +1 -0
  115. package/WebGPU/GPUComputePipeline.d.ts +8 -0
  116. package/WebGPU/GPUComputePipeline.js +19 -0
  117. package/WebGPU/GPUComputePipeline.js.map +1 -0
  118. package/WebGPU/GPUDevice.d.ts +111 -0
  119. package/WebGPU/GPUDevice.js +341 -0
  120. package/WebGPU/GPUDevice.js.map +1 -0
  121. package/WebGPU/GPUDeviceLostInfo.d.ts +1 -0
  122. package/WebGPU/GPUDeviceLostInfo.js +10 -0
  123. package/WebGPU/GPUDeviceLostInfo.js.map +1 -0
  124. package/WebGPU/GPUExternalTexture.d.ts +6 -0
  125. package/WebGPU/GPUExternalTexture.js +15 -0
  126. package/WebGPU/GPUExternalTexture.js.map +1 -0
  127. package/WebGPU/GPUPipelineLayout.d.ts +6 -0
  128. package/WebGPU/GPUPipelineLayout.js +15 -0
  129. package/WebGPU/GPUPipelineLayout.js.map +1 -0
  130. package/WebGPU/GPUQuerySet.d.ts +6 -0
  131. package/WebGPU/GPUQuerySet.js +15 -0
  132. package/WebGPU/GPUQuerySet.js.map +1 -0
  133. package/WebGPU/GPUQueue.d.ts +15 -0
  134. package/WebGPU/GPUQueue.js +128 -0
  135. package/WebGPU/GPUQueue.js.map +1 -0
  136. package/WebGPU/GPURenderBundle.d.ts +6 -0
  137. package/WebGPU/GPURenderBundle.js +15 -0
  138. package/WebGPU/GPURenderBundle.js.map +1 -0
  139. package/WebGPU/GPURenderBundleEncoder.d.ts +22 -0
  140. package/WebGPU/GPURenderBundleEncoder.js +65 -0
  141. package/WebGPU/GPURenderBundleEncoder.js.map +1 -0
  142. package/WebGPU/GPURenderPassEncoder.d.ts +33 -0
  143. package/WebGPU/GPURenderPassEncoder.js +106 -0
  144. package/WebGPU/GPURenderPassEncoder.js.map +1 -0
  145. package/WebGPU/GPURenderPipeline.d.ts +8 -0
  146. package/WebGPU/GPURenderPipeline.js +19 -0
  147. package/WebGPU/GPURenderPipeline.js.map +1 -0
  148. package/WebGPU/GPUSampler.d.ts +6 -0
  149. package/WebGPU/GPUSampler.js +15 -0
  150. package/WebGPU/GPUSampler.js.map +1 -0
  151. package/WebGPU/GPUShaderModule.d.ts +6 -0
  152. package/WebGPU/GPUShaderModule.js +15 -0
  153. package/WebGPU/GPUShaderModule.js.map +1 -0
  154. package/WebGPU/GPUTexture.d.ts +18 -0
  155. package/WebGPU/GPUTexture.js +47 -0
  156. package/WebGPU/GPUTexture.js.map +1 -0
  157. package/WebGPU/GPUTextureView.d.ts +6 -0
  158. package/WebGPU/GPUTextureView.js +15 -0
  159. package/WebGPU/GPUTextureView.js.map +1 -0
  160. package/WebGPU/Interfaces.d.ts +246 -0
  161. package/WebGPU/Interfaces.js +2 -0
  162. package/WebGPU/Interfaces.js.map +1 -0
  163. package/WebGPU/Types.d.ts +47 -0
  164. package/WebGPU/Types.js +2 -0
  165. package/WebGPU/Types.js.map +1 -0
  166. package/WebGPU/Utils.d.ts +7 -0
  167. package/WebGPU/Utils.js +301 -0
  168. package/WebGPU/Utils.js.map +1 -0
  169. package/WebGPU/index.d.ts +28 -0
  170. package/WebGPU/index.js +29 -0
  171. package/WebGPU/index.js.map +1 -0
  172. package/angular/{esm2020 → esm2022}/index.mjs +5 -5
  173. package/angular/{fesm2015 → fesm2022}/nativescript-canvas-angular.mjs +4 -4
  174. package/angular/{fesm2015 → fesm2022}/nativescript-canvas-angular.mjs.map +1 -1
  175. package/angular/package.json +4 -10
  176. package/common.d.ts +0 -3
  177. package/common.js +1 -5
  178. package/common.js.map +1 -1
  179. package/helpers.js.map +1 -1
  180. package/index.d.ts +4 -2
  181. package/index.js +37 -3
  182. package/index.js.map +1 -1
  183. package/package.json +2 -5
  184. package/platforms/android/canvas-release.aar +0 -0
  185. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/CanvasNative +0 -0
  186. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/CanvasNative-Swift.h +194 -56
  187. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/CanvasNative.h +1 -0
  188. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/NSCMTLView.h +32 -0
  189. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/canvas_ios.h +152 -151
  190. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/canvas_native.h +2901 -411
  191. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Info.plist +0 -0
  192. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
  193. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.abi.json +10901 -8099
  194. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.private.swiftinterface +259 -52
  195. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  196. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.swiftinterface +259 -52
  197. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Black.ttf +0 -0
  198. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Bold.ttf +0 -0
  199. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-ExtraBold.ttf +0 -0
  200. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-ExtraLight.ttf +0 -0
  201. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Light.ttf +0 -0
  202. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Medium.ttf +0 -0
  203. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Regular.ttf +0 -0
  204. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-SemiBold.ttf +0 -0
  205. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoMath-Regular.ttf +0 -0
  206. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-Bold.ttf +0 -0
  207. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-BoldItalic.ttf +0 -0
  208. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-Italic.ttf +0 -0
  209. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-Medium.ttf +0 -0
  210. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-MediumItalic.ttf +0 -0
  211. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-Regular.ttf +0 -0
  212. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-SemiBold.ttf +0 -0
  213. package/platforms/ios/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-SemiBoldItalic.ttf +0 -0
  214. package/platforms/ios/CanvasNative.xcframework/ios-arm64/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/DWARF/CanvasNative +0 -0
  215. package/platforms/ios/CanvasNative.xcframework/ios-arm64/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/aarch64/CanvasNative.yml +994 -663
  216. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/CanvasNative +0 -0
  217. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/CanvasNative-Swift.h +388 -112
  218. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/CanvasNative.h +1 -0
  219. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/NSCMTLView.h +32 -0
  220. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/canvas_ios.h +152 -151
  221. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Headers/canvas_native.h +2901 -411
  222. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Info.plist +0 -0
  223. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
  224. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo +0 -0
  225. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.abi.json +10901 -8099
  226. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +259 -52
  227. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  228. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios-simulator.swiftinterface +259 -52
  229. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.abi.json +10901 -8099
  230. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +259 -52
  231. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  232. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/Modules/CanvasNative.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +259 -52
  233. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/_CodeSignature/CodeResources +143 -33
  234. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Black.ttf +0 -0
  235. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Bold.ttf +0 -0
  236. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-ExtraBold.ttf +0 -0
  237. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-ExtraLight.ttf +0 -0
  238. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Light.ttf +0 -0
  239. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Medium.ttf +0 -0
  240. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-Regular.ttf +0 -0
  241. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/Noto_Serif_CJK/NotoSerifTC-SemiBold.ttf +0 -0
  242. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoMath-Regular.ttf +0 -0
  243. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-Bold.ttf +0 -0
  244. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-BoldItalic.ttf +0 -0
  245. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-Italic.ttf +0 -0
  246. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-Medium.ttf +0 -0
  247. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-MediumItalic.ttf +0 -0
  248. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-Regular.ttf +0 -0
  249. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-SemiBold.ttf +0 -0
  250. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/CanvasNative.framework/fonts/STIXTwoMath/STIXTwoText-SemiBoldItalic.ttf +0 -0
  251. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/DWARF/CanvasNative +0 -0
  252. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/aarch64/CanvasNative.yml +993 -662
  253. package/platforms/ios/CanvasNative.xcframework/ios-arm64_x86_64-simulator/dSYMs/CanvasNative.framework.dSYM/Contents/Resources/Relocations/x86_64/CanvasNative.yml +1037 -641
  254. package/platforms/ios/build.xcconfig +3 -1
  255. package/platforms/ios/src/NSOperationQueueWrapper.h +3 -1
  256. package/platforms/ios/src/NSOperationQueueWrapper.mm +41 -9
  257. package/platforms/ios/src/cpp/AsyncCallback.h +214 -0
  258. package/platforms/ios/src/cpp/Caches.h +69 -1
  259. package/platforms/ios/src/cpp/CanvasJSIModule.cpp +647 -1166
  260. package/platforms/ios/src/cpp/CanvasJSIModule.h +11 -1
  261. package/platforms/ios/src/cpp/Helpers.h +2 -129
  262. package/platforms/ios/src/cpp/ImageAssetImpl.cpp +600 -437
  263. package/platforms/ios/src/cpp/ImageAssetImpl.h +18 -10
  264. package/platforms/ios/src/cpp/ImageBitmapImpl.cpp +63 -6
  265. package/platforms/ios/src/cpp/ImageBitmapImpl.h +12 -4
  266. package/platforms/ios/src/cpp/JSIReadFileCallback.h +4 -4
  267. package/platforms/ios/src/cpp/NativeType.h +87 -0
  268. package/platforms/ios/src/cpp/ObjectWrapperImpl.h +50 -0
  269. package/platforms/ios/src/cpp/OneByteStringResource.cpp +2 -2
  270. package/platforms/ios/src/cpp/PromiseCallback.h +197 -0
  271. package/platforms/ios/src/cpp/RafImpl.h +2 -2
  272. package/platforms/ios/src/cpp/TextDecoderImpl.cpp +0 -6
  273. package/platforms/ios/src/cpp/TextDecoderImpl.h +3 -3
  274. package/platforms/ios/src/cpp/TextEncoderImpl.cpp +1 -1
  275. package/platforms/ios/src/cpp/TextEncoderImpl.h +3 -3
  276. package/platforms/ios/src/cpp/canvas2d/CanvasGradient.h +8 -7
  277. package/platforms/ios/src/cpp/canvas2d/CanvasPattern.cpp +1 -11
  278. package/platforms/ios/src/cpp/canvas2d/CanvasPattern.h +3 -3
  279. package/platforms/ios/src/cpp/canvas2d/CanvasRenderingContext2DImpl.cpp +193 -90
  280. package/platforms/ios/src/cpp/canvas2d/CanvasRenderingContext2DImpl.h +77 -23
  281. package/platforms/ios/src/cpp/canvas2d/ImageDataImpl.cpp +5 -6
  282. package/platforms/ios/src/cpp/canvas2d/ImageDataImpl.h +4 -4
  283. package/platforms/ios/src/cpp/canvas2d/MatrixImpl.cpp +409 -3
  284. package/platforms/ios/src/cpp/canvas2d/MatrixImpl.h +29 -2
  285. package/platforms/ios/src/cpp/canvas2d/Path2D.cpp +6 -3
  286. package/platforms/ios/src/cpp/canvas2d/Path2D.h +7 -7
  287. package/platforms/ios/src/cpp/canvas2d/TextMetricsImpl.h +3 -3
  288. package/platforms/ios/src/cpp/webgl/WebGLActiveInfoImpl.h +1 -1
  289. package/platforms/ios/src/cpp/webgl/WebGLBuffer.h +1 -1
  290. package/platforms/ios/src/cpp/webgl/WebGLFramebuffer.h +1 -1
  291. package/platforms/ios/src/cpp/webgl/WebGLProgram.h +3 -3
  292. package/platforms/ios/src/cpp/webgl/WebGLRenderbuffer.h +3 -3
  293. package/platforms/ios/src/cpp/webgl/WebGLRenderingContext.cpp +247 -160
  294. package/platforms/ios/src/cpp/webgl/WebGLRenderingContext.h +1 -1
  295. package/platforms/ios/src/cpp/webgl/WebGLRenderingContextBase.cpp +6 -6
  296. package/platforms/ios/src/cpp/webgl/WebGLShader.h +1 -1
  297. package/platforms/ios/src/cpp/webgl/WebGLShaderPrecisionFormatImpl.h +5 -5
  298. package/platforms/ios/src/cpp/webgl/WebGLTexture.h +3 -2
  299. package/platforms/ios/src/cpp/webgl/WebGLUniformLocation.h +2 -2
  300. package/platforms/ios/src/cpp/webgl/extensions/ANGLE_instanced_arraysImpl.h +1 -1
  301. package/platforms/ios/src/cpp/webgl/extensions/EXT_blend_minmaxImpl.h +1 -1
  302. package/platforms/ios/src/cpp/webgl/extensions/EXT_color_buffer_half_floatImpl.h +1 -1
  303. package/platforms/ios/src/cpp/webgl/extensions/EXT_disjoint_timer_queryImpl.h +1 -1
  304. package/platforms/ios/src/cpp/webgl/extensions/EXT_sRGBImpl.h +1 -1
  305. package/platforms/ios/src/cpp/webgl/extensions/EXT_shader_texture_lodImpl.h +1 -1
  306. package/platforms/ios/src/cpp/webgl/extensions/EXT_texture_filter_anisotropicImpl.h +1 -1
  307. package/platforms/ios/src/cpp/webgl/extensions/OES_element_index_uintImpl.h +2 -2
  308. package/platforms/ios/src/cpp/webgl/extensions/OES_fbo_render_mipmap.h +5 -5
  309. package/platforms/ios/src/cpp/webgl/extensions/OES_standard_derivativesImpl.h +1 -1
  310. package/platforms/ios/src/cpp/webgl/extensions/OES_texture_floatImpl.h +1 -1
  311. package/platforms/ios/src/cpp/webgl/extensions/OES_texture_float_linearImpl.h +1 -1
  312. package/platforms/ios/src/cpp/webgl/extensions/OES_texture_half_floatImpl.h +1 -1
  313. package/platforms/ios/src/cpp/webgl/extensions/OES_texture_half_float_linearImpl.h +1 -1
  314. package/platforms/ios/src/cpp/webgl/extensions/OES_vertex_array_objectImpl.h +1 -1
  315. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_color_buffer_floatImpl.h +1 -1
  316. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_atcImpl.h +1 -1
  317. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_etc1Impl.h +1 -1
  318. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_etcImpl.h +2 -2
  319. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_pvrtcImpl.h +1 -1
  320. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_s3tcImpl.h +1 -1
  321. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_compressed_texture_s3tc_srgbImpl.h +1 -1
  322. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_depth_textureImpl.h +1 -1
  323. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_draw_buffersImpl.h +1 -1
  324. package/platforms/ios/src/cpp/webgl/extensions/WEBGL_lose_contextImpl.h +1 -1
  325. package/platforms/ios/src/cpp/webgl2/WebGL2RenderingContext.cpp +1067 -960
  326. package/platforms/ios/src/cpp/webgl2/WebGL2RenderingContext.h +1 -1
  327. package/platforms/ios/src/cpp/webgl2/WebGLQuery.h +1 -1
  328. package/platforms/ios/src/cpp/webgl2/WebGLSampler.h +1 -1
  329. package/platforms/ios/src/cpp/webgl2/WebGLSyncImpl.h +1 -1
  330. package/platforms/ios/src/cpp/webgl2/WebGLTransformFeedback.h +1 -1
  331. package/platforms/ios/src/cpp/webgl2/WebGLVertexArrayObject.h +2 -2
  332. package/platforms/ios/src/cpp/webgpu/GPUAdapterImpl.cpp +371 -0
  333. package/platforms/ios/src/cpp/webgpu/GPUAdapterImpl.h +63 -0
  334. package/platforms/ios/src/cpp/webgpu/GPUAdapterInfoImpl.cpp +174 -0
  335. package/platforms/ios/src/cpp/webgpu/GPUAdapterInfoImpl.h +58 -0
  336. package/platforms/ios/src/cpp/webgpu/GPUBindGroupImpl.cpp +79 -0
  337. package/platforms/ios/src/cpp/webgpu/GPUBindGroupImpl.h +48 -0
  338. package/platforms/ios/src/cpp/webgpu/GPUBindGroupLayoutImpl.cpp +79 -0
  339. package/platforms/ios/src/cpp/webgpu/GPUBindGroupLayoutImpl.h +48 -0
  340. package/platforms/ios/src/cpp/webgpu/GPUBufferImpl.cpp +277 -0
  341. package/platforms/ios/src/cpp/webgpu/GPUBufferImpl.h +63 -0
  342. package/platforms/ios/src/cpp/webgpu/GPUCanvasContextImpl.cpp +379 -0
  343. package/platforms/ios/src/cpp/webgpu/GPUCanvasContextImpl.h +57 -0
  344. package/platforms/ios/src/cpp/webgpu/GPUCommandBufferImpl.cpp +81 -0
  345. package/platforms/ios/src/cpp/webgpu/GPUCommandBufferImpl.h +48 -0
  346. package/platforms/ios/src/cpp/webgpu/GPUCommandEncoderImpl.cpp +1217 -0
  347. package/platforms/ios/src/cpp/webgpu/GPUCommandEncoderImpl.h +73 -0
  348. package/platforms/ios/src/cpp/webgpu/GPUComputePassEncoderImpl.cpp +293 -0
  349. package/platforms/ios/src/cpp/webgpu/GPUComputePassEncoderImpl.h +65 -0
  350. package/platforms/ios/src/cpp/webgpu/GPUComputePipelineImpl.cpp +109 -0
  351. package/platforms/ios/src/cpp/webgpu/GPUComputePipelineImpl.h +51 -0
  352. package/platforms/ios/src/cpp/webgpu/GPUDeviceImpl.cpp +3701 -0
  353. package/platforms/ios/src/cpp/webgpu/GPUDeviceImpl.h +97 -0
  354. package/platforms/ios/src/cpp/webgpu/GPUImpl.cpp +200 -0
  355. package/platforms/ios/src/cpp/webgpu/GPUImpl.h +55 -0
  356. package/platforms/ios/src/cpp/webgpu/GPULabel.h +33 -0
  357. package/platforms/ios/src/cpp/webgpu/GPUPipelineLayoutImpl.cpp +80 -0
  358. package/platforms/ios/src/cpp/webgpu/GPUPipelineLayoutImpl.h +49 -0
  359. package/platforms/ios/src/cpp/webgpu/GPUQuerySetImpl.cpp +136 -0
  360. package/platforms/ios/src/cpp/webgpu/GPUQuerySetImpl.h +55 -0
  361. package/platforms/ios/src/cpp/webgpu/GPUQueueImpl.cpp +605 -0
  362. package/platforms/ios/src/cpp/webgpu/GPUQueueImpl.h +59 -0
  363. package/platforms/ios/src/cpp/webgpu/GPURenderBundleEncoderImpl.cpp +501 -0
  364. package/platforms/ios/src/cpp/webgpu/GPURenderBundleEncoderImpl.h +74 -0
  365. package/platforms/ios/src/cpp/webgpu/GPURenderBundleImpl.cpp +78 -0
  366. package/platforms/ios/src/cpp/webgpu/GPURenderBundleImpl.h +48 -0
  367. package/platforms/ios/src/cpp/webgpu/GPURenderPassEncoderImpl.cpp +723 -0
  368. package/platforms/ios/src/cpp/webgpu/GPURenderPassEncoderImpl.h +92 -0
  369. package/platforms/ios/src/cpp/webgpu/GPURenderPipelineImpl.cpp +109 -0
  370. package/platforms/ios/src/cpp/webgpu/GPURenderPipelineImpl.h +52 -0
  371. package/platforms/ios/src/cpp/webgpu/GPUSamplerImpl.cpp +79 -0
  372. package/platforms/ios/src/cpp/webgpu/GPUSamplerImpl.h +48 -0
  373. package/platforms/ios/src/cpp/webgpu/GPUShaderModuleImpl.cpp +80 -0
  374. package/platforms/ios/src/cpp/webgpu/GPUShaderModuleImpl.h +48 -0
  375. package/platforms/ios/src/cpp/webgpu/GPUSupportedLimitsImpl.cpp +1304 -0
  376. package/platforms/ios/src/cpp/webgpu/GPUSupportedLimitsImpl.h +288 -0
  377. package/platforms/ios/src/cpp/webgpu/GPUTextureImpl.cpp +386 -0
  378. package/platforms/ios/src/cpp/webgpu/GPUTextureImpl.h +77 -0
  379. package/platforms/ios/src/cpp/webgpu/GPUTextureViewImpl.cpp +79 -0
  380. package/platforms/ios/src/cpp/webgpu/GPUTextureViewImpl.h +48 -0
  381. package/platforms/ios/src/cpp/webgpu/GPUUtils.h +756 -0
  382. package/react/index.d.ts +1 -1
  383. package/utils.d.ts +1 -1
  384. package/utils.js.map +1 -1
  385. package/SVG/Circle.d.ts +0 -11
  386. package/SVG/Circle.js +0 -21
  387. package/SVG/Circle.js.map +0 -1
  388. package/SVG/ClipPath.d.ts +0 -4
  389. package/SVG/ClipPath.js +0 -9
  390. package/SVG/ClipPath.js.map +0 -1
  391. package/SVG/Defs.d.ts +0 -4
  392. package/SVG/Defs.js +0 -9
  393. package/SVG/Defs.js.map +0 -1
  394. package/SVG/Ellipse.d.ts +0 -13
  395. package/SVG/Ellipse.js +0 -26
  396. package/SVG/Ellipse.js.map +0 -1
  397. package/SVG/G.d.ts +0 -7
  398. package/SVG/G.js +0 -9
  399. package/SVG/G.js.map +0 -1
  400. package/SVG/Image.d.ts +0 -11
  401. package/SVG/Image.js +0 -40
  402. package/SVG/Image.js.map +0 -1
  403. package/SVG/Line.d.ts +0 -13
  404. package/SVG/Line.js +0 -26
  405. package/SVG/Line.js.map +0 -1
  406. package/SVG/LinearGradient.d.ts +0 -10
  407. package/SVG/LinearGradient.js +0 -13
  408. package/SVG/LinearGradient.js.map +0 -1
  409. package/SVG/Path.d.ts +0 -7
  410. package/SVG/Path.js +0 -14
  411. package/SVG/Path.js.map +0 -1
  412. package/SVG/Pattern.d.ts +0 -4
  413. package/SVG/Pattern.js +0 -9
  414. package/SVG/Pattern.js.map +0 -1
  415. package/SVG/Polygon.d.ts +0 -7
  416. package/SVG/Polygon.js +0 -14
  417. package/SVG/Polygon.js.map +0 -1
  418. package/SVG/Polyline.d.ts +0 -7
  419. package/SVG/Polyline.js +0 -14
  420. package/SVG/Polyline.js.map +0 -1
  421. package/SVG/Rect.d.ts +0 -8
  422. package/SVG/Rect.js +0 -13
  423. package/SVG/Rect.js.map +0 -1
  424. package/SVG/SVG.d.ts +0 -32
  425. package/SVG/SVG.js +0 -204
  426. package/SVG/SVG.js.map +0 -1
  427. package/SVG/SVGItem.d.ts +0 -5
  428. package/SVG/SVGItem.js +0 -8
  429. package/SVG/SVGItem.js.map +0 -1
  430. package/SVG/Stop.d.ts +0 -5
  431. package/SVG/Stop.js +0 -9
  432. package/SVG/Stop.js.map +0 -1
  433. package/SVG/Symbol.d.ts +0 -4
  434. package/SVG/Symbol.js +0 -9
  435. package/SVG/Symbol.js.map +0 -1
  436. package/SVG/Text.d.ts +0 -14
  437. package/SVG/Text.js +0 -26
  438. package/SVG/Text.js.map +0 -1
  439. package/SVG/Use.d.ts +0 -4
  440. package/SVG/Use.js +0 -9
  441. package/SVG/Use.js.map +0 -1
  442. package/SVG/index.d.ts +0 -18
  443. package/SVG/index.js +0 -19
  444. package/SVG/index.js.map +0 -1
  445. package/angular/fesm2020/nativescript-canvas-angular.mjs +0 -24
  446. package/angular/fesm2020/nativescript-canvas-angular.mjs.map +0 -1
  447. package/platforms/ios/src/cpp/PerIsolateData.cpp +0 -49
  448. package/platforms/ios/src/cpp/PerIsolateData.h +0 -54
  449. package/platforms/ios/src/cpp/URLImpl.cpp +0 -464
  450. package/platforms/ios/src/cpp/URLImpl.h +0 -121
  451. package/typings/objc!CanvasNative.d.ts +0 -2038
  452. package/typings/objc!CanvasNative.js +0 -1
  453. package/typings/objc!CanvasNative.js.map +0 -1
  454. /package/angular/{esm2020 → esm2022}/nativescript-canvas-angular.mjs +0 -0
@@ -0,0 +1,3701 @@
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
+ #include "GPULabel.h"
25
+
26
+ GPUDeviceImpl::GPUDeviceImpl(const CanvasGPUDevice *device) : device_(device) {}
27
+
28
+ const CanvasGPUDevice *GPUDeviceImpl::GetGPUDevice() {
29
+ return this->device_;
30
+ }
31
+
32
+
33
+ void GPUDeviceImpl::Init(v8::Local<v8::Object> canvasModule, v8::Isolate *isolate) {
34
+ v8::Locker locker(isolate);
35
+ v8::Isolate::Scope isolate_scope(isolate);
36
+ v8::HandleScope handle_scope(isolate);
37
+
38
+ auto ctor = GetCtor(isolate);
39
+ auto context = isolate->GetCurrentContext();
40
+ auto func = ctor->GetFunction(context).ToLocalChecked();
41
+
42
+ canvasModule->Set(context, ConvertToV8String(isolate, "GPUDevice"), func).FromJust();
43
+ }
44
+
45
+ GPUDeviceImpl *GPUDeviceImpl::GetPointer(const v8::Local<v8::Object> &object) {
46
+ auto ptr = object->GetAlignedPointerFromInternalField(0);
47
+ if (ptr == nullptr) {
48
+ return nullptr;
49
+ }
50
+ return static_cast<GPUDeviceImpl *>(ptr);
51
+ }
52
+
53
+ v8::Local<v8::FunctionTemplate> GPUDeviceImpl::GetCtor(v8::Isolate *isolate) {
54
+ auto cache = Caches::Get(isolate);
55
+ auto ctor = cache->GPUDeviceTmpl.get();
56
+ if (ctor != nullptr) {
57
+ return ctor->Get(isolate);
58
+ }
59
+
60
+ v8::Local<v8::FunctionTemplate> ctorTmpl = v8::FunctionTemplate::New(isolate);
61
+ ctorTmpl->InstanceTemplate()->SetInternalFieldCount(2);
62
+ ctorTmpl->SetClassName(ConvertToV8String(isolate, "GPUDevice"));
63
+
64
+ auto tmpl = ctorTmpl->InstanceTemplate();
65
+ tmpl->SetInternalFieldCount(2);
66
+
67
+ tmpl->SetLazyDataProperty(
68
+ ConvertToV8String(isolate, "label"),
69
+ GetLabel
70
+ );
71
+
72
+ tmpl->SetLazyDataProperty(
73
+ ConvertToV8String(isolate, "features"),
74
+ GetFeatures
75
+ );
76
+
77
+ tmpl->SetLazyDataProperty(
78
+ ConvertToV8String(isolate, "queue"),
79
+ GetQueue
80
+ );
81
+
82
+ tmpl->SetLazyDataProperty(
83
+ ConvertToV8String(isolate, "limits"),
84
+ GetLimits
85
+ );
86
+
87
+ tmpl->SetLazyDataProperty(
88
+ ConvertToV8String(isolate, "lost"),
89
+ GetLost
90
+ );
91
+
92
+ tmpl->Set(
93
+ ConvertToV8String(isolate, "createBindGroup"),
94
+ v8::FunctionTemplate::New(isolate, &CreateBindGroup));
95
+
96
+ tmpl->Set(
97
+ ConvertToV8String(isolate, "createBindGroupLayout"),
98
+ v8::FunctionTemplate::New(isolate, &CreateBindGroupLayout));
99
+
100
+ tmpl->Set(
101
+ ConvertToV8String(isolate, "createBuffer"),
102
+ v8::FunctionTemplate::New(isolate, &CreateBuffer));
103
+
104
+ tmpl->Set(
105
+ ConvertToV8String(isolate, "createCommandEncoder"),
106
+ v8::FunctionTemplate::New(isolate, &CreateCommandEncoder));
107
+
108
+ tmpl->Set(
109
+ ConvertToV8String(isolate, "createComputePipeline"),
110
+ v8::FunctionTemplate::New(isolate, &CreateComputePipeline));
111
+
112
+ tmpl->Set(
113
+ ConvertToV8String(isolate, "createComputePipelineAsync"),
114
+ v8::FunctionTemplate::New(isolate, &CreateComputePipelineAsync));
115
+
116
+ tmpl->Set(
117
+ ConvertToV8String(isolate, "createPipelineLayout"),
118
+ v8::FunctionTemplate::New(isolate, &CreatePipelineLayout));
119
+
120
+ tmpl->Set(
121
+ ConvertToV8String(isolate, "createQuerySet"),
122
+ v8::FunctionTemplate::New(isolate, &CreateQuerySet));
123
+
124
+ tmpl->Set(
125
+ ConvertToV8String(isolate, "createRenderBundleEncoder"),
126
+ v8::FunctionTemplate::New(isolate, &CreateRenderBundleEncoder));
127
+
128
+ tmpl->Set(
129
+ ConvertToV8String(isolate, "createRenderPipeline"),
130
+ v8::FunctionTemplate::New(isolate, &CreateRenderPipeline));
131
+
132
+ tmpl->Set(
133
+ ConvertToV8String(isolate, "createRenderPipelineAsync"),
134
+ v8::FunctionTemplate::New(isolate, &CreateRenderPipelineAsync));
135
+
136
+ tmpl->Set(
137
+ ConvertToV8String(isolate, "createSampler"),
138
+ v8::FunctionTemplate::New(isolate, &CreateSampler));
139
+
140
+ tmpl->Set(
141
+ ConvertToV8String(isolate, "createShaderModule"),
142
+ v8::FunctionTemplate::New(isolate, &CreateShaderModule));
143
+
144
+ tmpl->Set(
145
+ ConvertToV8String(isolate, "createTexture"),
146
+ v8::FunctionTemplate::New(isolate, &CreateTexture));
147
+
148
+ tmpl->Set(
149
+ ConvertToV8String(isolate, "destroy"),
150
+ v8::FunctionTemplate::New(isolate, &Destroy));
151
+
152
+ tmpl->Set(
153
+ ConvertToV8String(isolate, "popErrorScope"),
154
+ v8::FunctionTemplate::New(isolate, &PopErrorScope));
155
+
156
+ tmpl->Set(
157
+ ConvertToV8String(isolate, "pushErrorScope"),
158
+ v8::FunctionTemplate::New(isolate, &PushErrorScope));
159
+
160
+
161
+ tmpl->Set(
162
+ ConvertToV8String(isolate, "setuncapturederror"),
163
+ v8::FunctionTemplate::New(isolate, &SetUncapturedError));
164
+
165
+
166
+ cache->GPUDeviceTmpl =
167
+ std::make_unique<v8::Persistent<v8::FunctionTemplate>>(isolate, ctorTmpl);
168
+ return ctorTmpl;
169
+ }
170
+
171
+ void
172
+ GPUDeviceImpl::GetLabel(v8::Local<v8::Name> name,
173
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
174
+ auto ptr = GetPointer(info.This());
175
+ if (ptr != nullptr) {
176
+ auto label = canvas_native_webgpu_device_get_label(ptr->device_);
177
+ if (label == nullptr) {
178
+ info.GetReturnValue().SetEmptyString();
179
+ return;
180
+ }
181
+ info.GetReturnValue().Set(
182
+ ConvertToV8String(info.GetIsolate(), label)
183
+ );
184
+ canvas_native_string_destroy(label);
185
+ return;
186
+ }
187
+
188
+ info.GetReturnValue().SetEmptyString();
189
+ }
190
+
191
+ void
192
+ GPUDeviceImpl::SetUncapturedError(const v8::FunctionCallbackInfo<v8::Value> &args) {
193
+ auto *ptr = GetPointer(args.This());
194
+ if (ptr == nullptr) {
195
+ return;
196
+ }
197
+ auto isolate = args.GetIsolate();
198
+ auto cb = args[0];
199
+ auto callback = new JSICallback(isolate, cb.As<v8::Function>());
200
+
201
+ canvas_native_webgpu_device_set_uncaptured_error_callback(ptr->GetGPUDevice(),
202
+ [](CanvasGPUErrorType type, char *msg,
203
+ void *data) {
204
+
205
+ auto cb = static_cast<JSICallback *>(data);
206
+
207
+ v8::Isolate *isolate = cb->isolate_;
208
+ v8::Locker locker(isolate);
209
+ v8::Isolate::Scope isolate_scope(
210
+ isolate);
211
+ v8::HandleScope handle_scope(
212
+ isolate);
213
+ v8::Local<v8::Function> callback = cb->callback_->Get(
214
+ isolate);
215
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
216
+ v8::Context::Scope context_scope(
217
+ context);
218
+ v8::Local<v8::Value> typ;
219
+ v8::Local<v8::Value> message;
220
+ switch (type) {
221
+ case CanvasGPUErrorType::CanvasGPUErrorTypeNone:
222
+ typ = v8::Number::New(
223
+ isolate, 0);
224
+ message = v8::Null(
225
+ isolate);
226
+ break;
227
+ case CanvasGPUErrorType::CanvasGPUErrorTypeLost:
228
+ typ = v8::Number::New(
229
+ isolate, 1);
230
+ message = v8::Null(
231
+ isolate);
232
+ break;
233
+ case CanvasGPUErrorType::CanvasGPUErrorTypeOutOfMemory:
234
+ typ = v8::Number::New(
235
+ isolate, 2);
236
+ message = v8::Null(
237
+ isolate);
238
+ break;
239
+ case CanvasGPUErrorType::CanvasGPUErrorTypeValidation:
240
+ typ = v8::Number::New(
241
+ isolate, 3);
242
+ message = ConvertToV8String(
243
+ isolate, msg);
244
+ break;
245
+ case CanvasGPUErrorType::CanvasGPUErrorTypeInternal:
246
+ typ = v8::Number::New(
247
+ isolate, 4);
248
+ message = v8::Null(
249
+ isolate);
250
+ break;
251
+ }
252
+ v8::Local<v8::Value> args[2] = {
253
+ typ, message
254
+ };
255
+
256
+ callback->Call(context,
257
+ context->Global(),
258
+ 2, args);
259
+
260
+ // todo clean up
261
+ // delete static_cast<JSICallback *>(data);
262
+
263
+ }, callback);
264
+
265
+
266
+ }
267
+
268
+
269
+ void
270
+ GPUDeviceImpl::GetFeatures(v8::Local<v8::Name> name,
271
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
272
+ auto ptr = GetPointer(info.This());
273
+ auto isolate = info.GetIsolate();
274
+ if (ptr != nullptr) {
275
+ auto context = isolate->GetCurrentContext();
276
+
277
+ auto features = canvas_native_webgpu_device_get_features(ptr->GetGPUDevice());
278
+
279
+ auto len = canvas_native_string_buffer_get_length(features);
280
+
281
+ auto set = v8::Set::New(isolate);
282
+ for (int i = 0; i < len; ++i) {
283
+ auto item = canvas_native_string_buffer_get_value_at(features, i);
284
+ if (item != nullptr) {
285
+ auto keyValue = ConvertToV8String(isolate, (char *) item);
286
+ set->Add(context, keyValue);
287
+ canvas_native_string_destroy(item);
288
+ }
289
+
290
+ }
291
+ canvas_native_string_buffer_release(features);
292
+
293
+ info.GetReturnValue().Set(set);
294
+
295
+ return;
296
+ }
297
+
298
+ info.GetReturnValue().Set(v8::Map::New(info.GetIsolate()));
299
+ }
300
+
301
+
302
+ void
303
+ GPUDeviceImpl::GetLimits(v8::Local<v8::Name> name,
304
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
305
+ auto ptr = GetPointer(info.This());
306
+ if (ptr != nullptr) {
307
+ auto limits = canvas_native_webgpu_device_get_limits(ptr->GetGPUDevice());
308
+
309
+ auto ret = GPUSupportedLimitsImpl::NewInstance(info.GetIsolate(),
310
+ new GPUSupportedLimitsImpl(limits));
311
+ info.GetReturnValue().Set(ret);
312
+ return;
313
+ }
314
+ info.GetReturnValue().SetUndefined();
315
+ }
316
+
317
+
318
+ void
319
+ GPUDeviceImpl::GetQueue(v8::Local<v8::Name> name,
320
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
321
+ auto ptr = GetPointer(info.This());
322
+ if (ptr != nullptr) {
323
+ auto queue = canvas_native_webgpu_device_get_queue(ptr->GetGPUDevice());
324
+ auto ret = GPUQueueImpl::NewInstance(info.GetIsolate(),
325
+ new GPUQueueImpl(queue));
326
+ info.GetReturnValue().Set(ret);
327
+ return;
328
+ }
329
+ info.GetReturnValue().SetUndefined();
330
+ }
331
+
332
+
333
+ struct LostData {
334
+ int32_t reason;
335
+ char *message;
336
+ };
337
+
338
+ void
339
+ GPUDeviceImpl::GetLost(v8::Local<v8::Name> name,
340
+ const v8::PropertyCallbackInfo<v8::Value> &info) {
341
+ auto ptr = GetPointer(info.This());
342
+ auto isolate = info.GetIsolate();
343
+ auto resolver = v8::Promise::Resolver::New(isolate->GetCurrentContext()).ToLocalChecked();
344
+ info.GetReturnValue().Set(resolver->GetPromise());
345
+ if (ptr != nullptr) {
346
+ auto callback = new PromiseCallback{
347
+ isolate,
348
+ resolver,
349
+ [](bool done, void *data) {
350
+ if (data != nullptr) {
351
+ auto async_data = static_cast<PromiseCallback *>(data);
352
+ auto func = async_data->inner_.get();
353
+ if (func != nullptr && func->isolate_ != nullptr) {
354
+ v8::Isolate *isolate = func->isolate_;
355
+ v8::Locker locker(isolate);
356
+ v8::Isolate::Scope isolate_scope(
357
+ isolate);
358
+ v8::HandleScope handle_scope(
359
+ isolate);
360
+ v8::Local<v8::Promise::Resolver> callback = func->callback_.Get(
361
+ isolate);
362
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
363
+ v8::Context::Scope context_scope(
364
+ context);
365
+
366
+ auto ret = v8::Object::New(
367
+ isolate);
368
+ LostData *lostData = nullptr;
369
+ if (func->data != nullptr) {
370
+ lostData = static_cast<LostData *>(func->data);
371
+ }
372
+
373
+ if (lostData != nullptr) {
374
+
375
+ if (lostData->message != nullptr) {
376
+ ret->Set(context,
377
+ ConvertToV8String(
378
+ isolate,
379
+ "message"),
380
+ ConvertToV8String(
381
+ isolate,
382
+ lostData->message));
383
+ canvas_native_string_destroy(
384
+ lostData->message);
385
+ }
386
+
387
+ ret->Set(context,
388
+ ConvertToV8String(
389
+ isolate,
390
+ "reason"),
391
+ v8::Int32::New(isolate,
392
+ lostData->reason)).IsJust();
393
+ } else {
394
+ ret->Set(context,
395
+ ConvertToV8String(
396
+ isolate,
397
+ "message"),
398
+ v8::String::Empty(
399
+ isolate));
400
+ }
401
+
402
+ callback->Resolve(context, ret);
403
+ delete static_cast<PromiseCallback *>(data);
404
+ }
405
+ }
406
+ }
407
+ };
408
+
409
+ callback->prepare();
410
+
411
+ canvas_native_webgpu_device_set_lost_callback(ptr->GetGPUDevice(),
412
+ [](int32_t reason, char *message,
413
+ void *data) {
414
+ if (data != nullptr) {
415
+ auto async_data = static_cast<PromiseCallback *>(data);
416
+ auto inner = async_data->inner_.get();
417
+ if (inner != nullptr) {
418
+ inner->data = new LostData{
419
+ reason, message
420
+ };
421
+ async_data->execute(true);
422
+ }
423
+ }
424
+ }, callback);
425
+ }
426
+ }
427
+
428
+
429
+ void GPUDeviceImpl::CreateBindGroup(const v8::FunctionCallbackInfo<v8::Value> &args) {
430
+ GPUDeviceImpl *ptr = GetPointer(args.This());
431
+ if (ptr == nullptr) {
432
+ return;
433
+ }
434
+ auto isolate = args.GetIsolate();
435
+ auto context = isolate->GetCurrentContext();
436
+ GPULabel label;
437
+
438
+ auto optionsVal = args[0];
439
+
440
+ std::vector<CanvasBindGroupEntry> entries;
441
+
442
+ if (optionsVal->IsObject()) {
443
+ auto options = optionsVal.As<v8::Object>();
444
+ v8::Local<v8::Value> labelVal;
445
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
446
+
447
+
448
+ label = GPULabel(isolate, labelVal);
449
+
450
+ const CanvasGPUBindGroupLayout *layout = nullptr;
451
+
452
+ v8::Local<v8::Value> layoutVal;
453
+ options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(&layoutVal);
454
+
455
+ if (!layoutVal.IsEmpty() && layoutVal->IsObject()) {
456
+ auto layoutObj = layoutVal.As<v8::Object>();
457
+ auto layoutImpl = GPUBindGroupLayoutImpl::GetPointer(layoutObj);
458
+ if (layoutImpl != nullptr) {
459
+ layout = layoutImpl->GetBindGroupLayout();
460
+ }
461
+ }
462
+
463
+
464
+ v8::Local<v8::Value> entriesVal;
465
+ options->Get(context, ConvertToV8String(isolate, "entries")).ToLocal(&entriesVal);
466
+
467
+ entries = ParseBindGroupEntries(isolate, entriesVal);
468
+
469
+ auto bind_group = canvas_native_webgpu_device_create_bind_group(ptr->GetGPUDevice(),
470
+ *label,
471
+ layout, entries.data(),
472
+ entries.size());
473
+
474
+ if (bind_group != nullptr) {
475
+ auto ret = GPUBindGroupImpl::NewInstance(isolate, new GPUBindGroupImpl(bind_group));
476
+ args.GetReturnValue().Set(ret);
477
+ return;
478
+ }
479
+ }
480
+
481
+ args.GetReturnValue().SetUndefined();
482
+ }
483
+
484
+ void GPUDeviceImpl::CreateBindGroupLayout(const v8::FunctionCallbackInfo<v8::Value> &args) {
485
+ GPUDeviceImpl *ptr = GetPointer(args.This());
486
+ if (ptr == nullptr) {
487
+ return;
488
+ }
489
+ auto isolate = args.GetIsolate();
490
+ auto context = isolate->GetCurrentContext();
491
+ GPULabel label;
492
+
493
+ auto optionsVal = args[0];
494
+
495
+ if (optionsVal->IsObject()) {
496
+ auto options = optionsVal.As<v8::Object>();
497
+ v8::Local<v8::Value> labelVal;
498
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
499
+
500
+ label = GPULabel(isolate, labelVal);
501
+
502
+ v8::Local<v8::Value> entriesVal;
503
+ options->Get(context, ConvertToV8String(isolate, "entries")).ToLocal(&entriesVal);
504
+
505
+ std::vector<CanvasBindGroupLayoutEntry> entries = ParseBindGroupLayoutEntries(isolate,
506
+ entriesVal);
507
+
508
+ auto bind_group = canvas_native_webgpu_device_create_bind_group_layout(ptr->GetGPUDevice(),
509
+ *label,
510
+ entries.data(),
511
+ entries.size());
512
+
513
+ if (bind_group != nullptr) {
514
+ auto ret = GPUBindGroupLayoutImpl::NewInstance(isolate,
515
+ new GPUBindGroupLayoutImpl(bind_group));
516
+ args.GetReturnValue().Set(ret);
517
+ return;
518
+ }
519
+ }
520
+
521
+ args.GetReturnValue().SetUndefined();
522
+ }
523
+
524
+ void GPUDeviceImpl::CreateBuffer(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
+ GPULabel label;
532
+ bool mappedAtCreation = false;
533
+ uint64_t size = 0;
534
+ uint32_t usage = 0;
535
+
536
+ auto optionsVal = args[0];
537
+
538
+ if (optionsVal->IsObject()) {
539
+ auto options = optionsVal.As<v8::Object>();
540
+ v8::Local<v8::Value> labelVal;
541
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
542
+
543
+ label = GPULabel(isolate, labelVal);
544
+ v8::Local<v8::Value> mappedAtCreationVal;
545
+
546
+ options->Get(context, ConvertToV8String(isolate, "mappedAtCreation")).ToLocal(
547
+ &mappedAtCreationVal);
548
+
549
+ if (!mappedAtCreationVal.IsEmpty()) {
550
+ mappedAtCreation = mappedAtCreationVal->BooleanValue(isolate);
551
+ }
552
+
553
+ v8::Local<v8::Value> sizeVal;
554
+ options->Get(context, ConvertToV8String(isolate, "size")).ToLocal(&sizeVal);
555
+
556
+ if (sizeVal->IsNumber()) {
557
+ size = (uint64_t) sizeVal->NumberValue(context).ToChecked();
558
+ }
559
+
560
+
561
+ v8::Local<v8::Value> usageVal;
562
+ options->Get(context, ConvertToV8String(isolate, "usage")).ToLocal(&usageVal);
563
+
564
+ if (usageVal->IsNumber()) {
565
+ usage = usageVal->Uint32Value(context).ToChecked();
566
+ }
567
+ }
568
+
569
+ auto buffer = canvas_native_webgpu_device_create_buffer(ptr->GetGPUDevice(), *label,
570
+ size, usage,
571
+ mappedAtCreation);
572
+
573
+ if (buffer != nullptr) {
574
+ auto bufImpl = new GPUBufferImpl(buffer);
575
+ auto ret = GPUBufferImpl::NewInstance(isolate, bufImpl);
576
+ args.GetReturnValue().Set(ret);
577
+
578
+ } else {
579
+ // todo return invalid buffer
580
+ args.GetReturnValue().SetUndefined();
581
+ }
582
+ }
583
+
584
+ void GPUDeviceImpl::CreateCommandEncoder(const v8::FunctionCallbackInfo<v8::Value> &args) {
585
+ GPUDeviceImpl *ptr = GetPointer(args.This());
586
+ if (ptr == nullptr) {
587
+ return;
588
+ }
589
+ auto isolate = args.GetIsolate();
590
+
591
+ auto label = GPULabel(isolate, args[0]);
592
+
593
+ auto encoder = canvas_native_webgpu_device_create_command_encoder(ptr->GetGPUDevice(),
594
+ *label);
595
+
596
+ if (encoder != nullptr) {
597
+ auto instance = new GPUCommandEncoderImpl(encoder);
598
+ auto ret = GPUCommandEncoderImpl::NewInstance(isolate, instance);
599
+ args.GetReturnValue().Set(ret);
600
+ return;
601
+ }
602
+
603
+ args.GetReturnValue().SetUndefined();
604
+
605
+ }
606
+
607
+ void GPUDeviceImpl::CreateComputePipeline(const v8::FunctionCallbackInfo<v8::Value> &args) {
608
+ GPUDeviceImpl *ptr = GetPointer(args.This());
609
+ if (ptr == nullptr) {
610
+ return;
611
+ }
612
+ auto isolate = args.GetIsolate();
613
+ auto context = isolate->GetCurrentContext();
614
+
615
+ auto optionsVal = args[0];
616
+
617
+ if (!optionsVal->IsObject()) {
618
+ // should error at this point
619
+ return;
620
+ }
621
+ auto options = optionsVal.As<v8::Object>();
622
+
623
+ v8::Local<v8::Value> labelVal;
624
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
625
+
626
+ GPULabel label(isolate, labelVal);
627
+
628
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout{
629
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
630
+ };
631
+
632
+ v8::Local<v8::Value> layoutVal;
633
+ options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(&layoutVal);
634
+
635
+ if (!layoutVal.IsEmpty() && layoutVal->IsObject()) {
636
+ auto layoutImpl = GPUPipelineLayoutImpl::GetPointer(layoutVal.As<v8::Object>());
637
+ if (layoutImpl != nullptr) {
638
+ layout.tag = CanvasGPUPipelineLayoutOrGPUAutoLayoutModeLayout;
639
+ layout.layout = layoutImpl->GetPipeline();
640
+ }
641
+ }
642
+
643
+
644
+ v8::Local<v8::Value> computeVal;
645
+ options->Get(context, ConvertToV8String(isolate, "compute")).ToLocal(&computeVal);
646
+
647
+ if (!computeVal.IsEmpty() && computeVal->IsObject()) {
648
+
649
+ auto computeObj = computeVal.As<v8::Object>();
650
+
651
+ v8::Local<v8::Value> constantsVal;
652
+ computeObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(
653
+ &constantsVal);
654
+
655
+ CanvasConstants *store = nullptr;
656
+
657
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
658
+ auto constants = constantsVal.As<v8::Map>();
659
+ auto keyValues = constants->AsArray();
660
+ auto length = keyValues->Length();
661
+ if (length > 0) {
662
+ store = canvas_native_webgpu_constants_create();
663
+ for (int i = 0; i < length; i += 2) {
664
+ auto k = i;
665
+ auto v = k + 1;
666
+
667
+ v8::Local<v8::Value> keyVal;
668
+ keyValues->Get(context, k).ToLocal(&keyVal);
669
+ v8::Local<v8::Value> valueVal;
670
+ keyValues->Get(context, v).ToLocal(&valueVal);
671
+
672
+
673
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
674
+ valueVal->IsNumber()) {
675
+ auto val = ConvertFromV8String(isolate, keyVal);
676
+ canvas_native_webgpu_constants_insert(
677
+ store,
678
+ val.c_str(),
679
+ valueVal.As<v8::Number>()->Value()
680
+ );
681
+ }
682
+
683
+ }
684
+ }
685
+ }
686
+
687
+
688
+ v8::Local<v8::Value> entryPoint;
689
+ computeObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(
690
+ &entryPoint);
691
+
692
+ char *entry_point = nullptr;
693
+
694
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
695
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
696
+ entry_point = (char *) malloc(ep.length());
697
+ std::strcpy(entry_point, *ep);
698
+ }
699
+
700
+ v8::Local<v8::Value> moduleVal;
701
+ computeObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
702
+
703
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
704
+
705
+ CanvasProgrammableStage stage{
706
+ module->GetShaderModule(),
707
+ entry_point,
708
+ store
709
+ };
710
+
711
+ auto pipeline = canvas_native_webgpu_device_create_compute_pipeline(ptr->GetGPUDevice(),
712
+ *label, layout,
713
+ &stage);
714
+
715
+ if (entry_point != nullptr) {
716
+ free(entry_point);
717
+ }
718
+
719
+ if (store != nullptr) {
720
+ canvas_native_webgpu_constants_destroy(store);
721
+ }
722
+
723
+ if (pipeline != nullptr) {
724
+ auto ret = GPUComputePipelineImpl::NewInstance(isolate,
725
+ new GPUComputePipelineImpl(pipeline));
726
+ args.GetReturnValue().Set(ret);
727
+ return;
728
+ }
729
+
730
+
731
+ }
732
+
733
+ args.GetReturnValue().SetUndefined();
734
+ }
735
+
736
+ struct ComputePipeLineAsyncData {
737
+ char *label;
738
+ CanvasConstants *constants;
739
+ enum CanvasGPUErrorType type;
740
+ char *errorMessage;
741
+ const CanvasGPUComputePipeline *pipeline;
742
+
743
+ ~ComputePipeLineAsyncData() {
744
+ if (label != nullptr) {
745
+ free(label);
746
+ label = nullptr;
747
+ canvas_native_webgpu_constants_destroy(constants);
748
+ constants = nullptr;
749
+ }
750
+
751
+ if (constants != nullptr) {
752
+ canvas_native_webgpu_constants_destroy(constants);
753
+ constants = nullptr;
754
+ }
755
+
756
+ if (errorMessage != nullptr) {
757
+ canvas_native_string_destroy(errorMessage);
758
+ errorMessage = nullptr;
759
+ }
760
+ }
761
+ };
762
+
763
+ void GPUDeviceImpl::CreateComputePipelineAsync(const v8::FunctionCallbackInfo<v8::Value> &args) {
764
+ GPUDeviceImpl *ptr = GetPointer(args.This());
765
+ if (ptr == nullptr) {
766
+ return;
767
+ }
768
+ auto isolate = args.GetIsolate();
769
+ auto context = isolate->GetCurrentContext();
770
+
771
+ auto optionsVal = args[0];
772
+ auto callback = args[1];
773
+
774
+ if (!optionsVal->IsObject()) {
775
+ // should error at this point
776
+ return;
777
+ }
778
+ auto options = optionsVal.As<v8::Object>();
779
+
780
+ v8::Local<v8::Value> labelVal;
781
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
782
+
783
+ auto label = GPULabel(isolate, labelVal);
784
+
785
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout{
786
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
787
+ };
788
+
789
+ v8::Local<v8::Value> layoutVal;
790
+
791
+ if (options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(&layoutVal) &&
792
+ layoutVal->IsObject()) {
793
+ auto layoutImpl = GPUPipelineLayoutImpl::GetPointer(layoutVal.As<v8::Object>());
794
+ if (layoutImpl != nullptr) {
795
+ layout.tag = CanvasGPUPipelineLayoutOrGPUAutoLayoutModeLayout;
796
+ layout.layout = layoutImpl->GetPipeline();
797
+ }
798
+ }
799
+
800
+
801
+ v8::Local<v8::Value> computeVal;
802
+ options->Get(context, ConvertToV8String(isolate, "compute")).ToLocal(&computeVal);
803
+
804
+ if (!computeVal.IsEmpty() && computeVal->IsObject()) {
805
+
806
+ auto computeObj = computeVal.As<v8::Object>();
807
+
808
+ v8::Local<v8::Value> constantsVal;
809
+ computeObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(
810
+ &constantsVal);
811
+
812
+ CanvasConstants *store = nullptr;
813
+
814
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
815
+ auto constants = constantsVal.As<v8::Map>();
816
+ auto keyValues = constants->AsArray();
817
+ auto length = keyValues->Length();
818
+ if (length > 0) {
819
+ store = canvas_native_webgpu_constants_create();
820
+ for (int i = 0; i < length; i += 2) {
821
+ auto k = i;
822
+ auto v = k + 1;
823
+
824
+ v8::Local<v8::Value> keyVal;
825
+ keyValues->Get(context, k).ToLocal(&keyVal);
826
+ v8::Local<v8::Value> valueVal;
827
+ keyValues->Get(context, v).ToLocal(&valueVal);
828
+
829
+
830
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
831
+ valueVal->IsNumber()) {
832
+ auto val = ConvertFromV8String(isolate, keyVal);
833
+ canvas_native_webgpu_constants_insert(
834
+ store,
835
+ val.c_str(),
836
+ valueVal.As<v8::Number>()->Value()
837
+ );
838
+ }
839
+
840
+ }
841
+ }
842
+ }
843
+
844
+
845
+ v8::Local<v8::Value> entryPoint;
846
+ computeObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(
847
+ &entryPoint);
848
+
849
+ char *entry_point = nullptr;
850
+
851
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
852
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
853
+ entry_point = (char *) malloc(ep.length());
854
+ std::strcpy(entry_point, *ep);
855
+ }
856
+
857
+ v8::Local<v8::Value> moduleVal;
858
+ computeObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
859
+
860
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
861
+
862
+ CanvasProgrammableStage stage{
863
+ module->GetShaderModule(),
864
+ entry_point,
865
+ store
866
+ };
867
+
868
+
869
+ auto async_callback = new AsyncCallback(isolate, callback.As<v8::Function>(),
870
+ [](bool success, void *data) {
871
+ if (data != nullptr) {
872
+
873
+ auto async_data = static_cast<AsyncCallback *>(data);
874
+ auto func = async_data->inner_.get();
875
+ if (func != nullptr &&
876
+ func->isolate_ != nullptr) {
877
+ v8::Isolate *isolate = func->isolate_;
878
+ v8::Locker locker(isolate);
879
+ v8::Isolate::Scope isolate_scope(
880
+ isolate);
881
+ v8::HandleScope handle_scope(isolate);
882
+ v8::Local<v8::Function> callback = func->callback_.Get(
883
+ isolate);
884
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
885
+ v8::Context::Scope context_scope(
886
+ context);
887
+
888
+ ComputePipeLineAsyncData *pipelineData = nullptr;
889
+ if (func->data != nullptr) {
890
+ pipelineData = static_cast<ComputePipeLineAsyncData *>(func->data);
891
+ }
892
+
893
+ if (pipelineData == nullptr) {
894
+ // Should never happen
895
+
896
+ auto error = v8::Object::New(
897
+ isolate);
898
+ error->Set(context,
899
+ ConvertToV8String(
900
+ isolate,
901
+ "error"),
902
+ v8::Exception::Error(
903
+ ConvertToV8String(
904
+ isolate,
905
+ "Internal Error")));
906
+ error->Set(context,
907
+ ConvertToV8String(
908
+ isolate,
909
+ "type"),
910
+ v8::Uint32::NewFromUnsigned(
911
+ isolate,
912
+ (uint32_t) CanvasGPUErrorType::CanvasGPUErrorTypeInternal));
913
+
914
+
915
+ v8::Local<v8::Value> args[1] = {
916
+ error};
917
+
918
+ callback->Call(context,
919
+ context->Global(),
920
+ 1,
921
+ args); // ignore JS return value
922
+ delete static_cast<AsyncCallback *>(data);
923
+
924
+ return;
925
+ }
926
+
927
+ if (pipelineData->type !=
928
+ CanvasGPUErrorType::CanvasGPUErrorTypeNone) {
929
+
930
+ auto error = v8::Object::New(
931
+ isolate);
932
+ error->Set(context,
933
+ ConvertToV8String(
934
+ isolate,
935
+ "error"),
936
+ v8::Exception::Error(
937
+ ConvertToV8String(
938
+ isolate,
939
+ pipelineData->errorMessage)));
940
+
941
+ error->Set(context,
942
+ ConvertToV8String(
943
+ isolate,
944
+ "type"),
945
+ v8::Uint32::NewFromUnsigned(
946
+ isolate,
947
+ (uint32_t) pipelineData->type));
948
+
949
+ v8::Local<v8::Value> args[1] = {
950
+ error};
951
+
952
+ callback->Call(context,
953
+ context->Global(),
954
+ 1,
955
+ args); // ignore JS return value
956
+ } else {
957
+
958
+ auto ret = GPUComputePipelineImpl::NewInstance(
959
+ isolate,
960
+ new GPUComputePipelineImpl(
961
+ pipelineData->pipeline));
962
+
963
+ v8::Local<v8::Value> args[2] = {
964
+ v8::Null(isolate), ret};
965
+
966
+
967
+ callback->Call(context,
968
+ context->Global(),
969
+ 2,
970
+ args); // ignore JS return value
971
+ }
972
+
973
+ if (pipelineData != nullptr) {
974
+ delete pipelineData;
975
+ pipelineData = nullptr;
976
+ }
977
+
978
+ delete static_cast<AsyncCallback *>(data);
979
+ }
980
+ }
981
+ });
982
+ async_callback->inner_->data = new ComputePipeLineAsyncData{
983
+ entry_point,
984
+ store,
985
+ CanvasGPUErrorType::CanvasGPUErrorTypeNone,
986
+ nullptr,
987
+ nullptr
988
+ };
989
+ async_callback->prepare();
990
+ canvas_native_webgpu_device_create_compute_pipeline_async(ptr->GetGPUDevice(),
991
+ *label, layout, &stage,
992
+ [](const struct CanvasGPUComputePipeline *pipeline,
993
+ enum CanvasGPUErrorType type,
994
+ char *message,
995
+ void *data) {
996
+ if (data != nullptr) {
997
+ auto async_data = static_cast<AsyncCallback *>(data);
998
+ auto inner = async_data->inner_.get();
999
+ if (inner != nullptr) {
1000
+ auto pipeline_data = static_cast<ComputePipeLineAsyncData *>(inner->data);
1001
+ pipeline_data->errorMessage = message;
1002
+ pipeline_data->type = type;
1003
+ pipeline_data->pipeline = pipeline;
1004
+ async_data->execute(
1005
+ true);
1006
+ }
1007
+ }
1008
+ }, async_callback);
1009
+
1010
+
1011
+ }
1012
+
1013
+ args.GetReturnValue().SetUndefined();
1014
+ }
1015
+
1016
+ void GPUDeviceImpl::CreatePipelineLayout(const v8::FunctionCallbackInfo<v8::Value> &args) {
1017
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1018
+ if (ptr == nullptr) {
1019
+ return;
1020
+ }
1021
+ auto isolate = args.GetIsolate();
1022
+ auto context = isolate->GetCurrentContext();
1023
+
1024
+ auto optionsVal = args[0];
1025
+
1026
+ if (!optionsVal->IsObject()) {
1027
+ // should error at this point
1028
+ return;
1029
+ }
1030
+ auto options = optionsVal.As<v8::Object>();
1031
+
1032
+ v8::Local<v8::Value> labelVal;
1033
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1034
+
1035
+ auto label = GPULabel(isolate, labelVal);
1036
+
1037
+
1038
+ std::vector<const CanvasGPUBindGroupLayout *> group_layouts;
1039
+
1040
+ v8::Local<v8::Value> groupLayoutsVal;
1041
+ options->Get(context, ConvertToV8String(isolate, "bindGroupLayouts")).ToLocal(&groupLayoutsVal);
1042
+
1043
+ if (!groupLayoutsVal.IsEmpty() && groupLayoutsVal->IsArray()) {
1044
+ auto groupLayoutsArray = groupLayoutsVal.As<v8::Array>();
1045
+ auto len = groupLayoutsArray->Length();
1046
+ for (int i = 0; i < len; i++) {
1047
+ v8::Local<v8::Value> groupVal;
1048
+ groupLayoutsArray->Get(context, i).ToLocal(&groupVal);
1049
+ if (GetNativeType(groupVal) == NativeType::GPUBindGroupLayout) {
1050
+ auto layout = GPUBindGroupLayoutImpl::GetPointer(groupVal.As<v8::Object>());
1051
+ if (layout != nullptr) {
1052
+ group_layouts.push_back(layout->GetBindGroupLayout());
1053
+ }
1054
+ }
1055
+ }
1056
+
1057
+ auto layout = canvas_native_webgpu_device_create_pipeline_layout(ptr->GetGPUDevice(),
1058
+ *label,
1059
+ group_layouts.data(),
1060
+ group_layouts.size());
1061
+
1062
+ if (layout != nullptr) {
1063
+ auto ret = GPUPipelineLayoutImpl::NewInstance(isolate,
1064
+ new GPUPipelineLayoutImpl(layout));
1065
+ args.GetReturnValue().Set(ret);
1066
+ return;
1067
+ }
1068
+ }
1069
+
1070
+
1071
+ args.GetReturnValue().SetUndefined();
1072
+ }
1073
+
1074
+ void GPUDeviceImpl::CreateQuerySet(const v8::FunctionCallbackInfo<v8::Value> &args) {
1075
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1076
+ if (ptr == nullptr) {
1077
+ return;
1078
+ }
1079
+ auto isolate = args.GetIsolate();
1080
+ auto context = isolate->GetCurrentContext();
1081
+
1082
+ auto optionsVal = args[0];
1083
+
1084
+ if (!optionsVal->IsObject()) {
1085
+ // should error at this point
1086
+ return;
1087
+ }
1088
+ auto options = optionsVal.As<v8::Object>();
1089
+
1090
+ v8::Local<v8::Value> labelVal;
1091
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1092
+
1093
+ auto label = GPULabel(isolate, labelVal);
1094
+ v8::Local<v8::Value> typeVal;
1095
+ options->Get(context, ConvertToV8String(isolate, "type")).ToLocal(&typeVal);
1096
+
1097
+
1098
+ v8::Local<v8::Value> countVal;
1099
+ options->Get(context, ConvertToV8String(isolate, "count")).ToLocal(&countVal);
1100
+
1101
+ auto typeStr = ConvertFromV8String(isolate, typeVal);
1102
+
1103
+ const CanvasGPUQuerySet *query_set = nullptr;
1104
+ if (typeStr == "occlusion") {
1105
+ query_set = canvas_native_webgpu_device_create_query_set(ptr->GetGPUDevice(), *label,
1106
+ CanvasQueryTypeOcclusion,
1107
+ countVal->Uint32Value(
1108
+ context).FromJust());
1109
+ } else if (typeStr == "timestamp") {
1110
+ query_set = canvas_native_webgpu_device_create_query_set(ptr->GetGPUDevice(), *label,
1111
+ CanvasQueryTypeTimestamp,
1112
+ countVal->Uint32Value(
1113
+ context).FromJust());
1114
+ } else {
1115
+ // todo throw
1116
+ }
1117
+
1118
+
1119
+ if (query_set != nullptr) {
1120
+ auto ret = GPUQuerySetImpl::NewInstance(isolate, new GPUQuerySetImpl(query_set));
1121
+ args.GetReturnValue().Set(ret);
1122
+ return;
1123
+ }
1124
+
1125
+ args.GetReturnValue().SetUndefined();
1126
+
1127
+ }
1128
+
1129
+ void GPUDeviceImpl::CreateRenderBundleEncoder(const v8::FunctionCallbackInfo<v8::Value> &args) {
1130
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1131
+ if (ptr == nullptr) {
1132
+ return;
1133
+ }
1134
+ auto isolate = args.GetIsolate();
1135
+ auto context = isolate->GetCurrentContext();
1136
+
1137
+ auto optionsVal = args[0];
1138
+
1139
+ if (!optionsVal->IsObject()) {
1140
+ // should error at this point
1141
+ return;
1142
+ }
1143
+ auto options = optionsVal.As<v8::Object>();
1144
+
1145
+ v8::Local<v8::Value> labelVal;
1146
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
1147
+
1148
+ auto label = GPULabel(isolate, labelVal);
1149
+
1150
+ std::vector<CanvasGPUTextureFormat> colorFormats;
1151
+
1152
+ v8::Local<v8::Value> colorFormatsVal;
1153
+ options->Get(context, ConvertToV8String(isolate, "colorFormats")).ToLocal(&colorFormatsVal);
1154
+
1155
+ if (!colorFormatsVal.IsEmpty() && colorFormatsVal->IsArray()) {
1156
+ auto colorFormatsArray = colorFormatsVal.As<v8::Array>();
1157
+ auto len = colorFormatsArray->Length();
1158
+ for (int i = 0; i < len; i++) {
1159
+ v8::Local<v8::Value> formatVal;
1160
+ colorFormatsArray->Get(context, i).ToLocal(&formatVal);
1161
+ if (!formatVal.IsEmpty() && formatVal->IsString()) {
1162
+ auto formatStr = ConvertFromV8String(isolate, formatVal);
1163
+ auto format = canvas_native_webgpu_enum_string_to_gpu_texture(formatStr.c_str());
1164
+ if (format.tag == CanvasOptionalGPUTextureFormatSome) {
1165
+ colorFormats.push_back(format.some);
1166
+ }
1167
+ }
1168
+
1169
+ }
1170
+ }
1171
+
1172
+
1173
+ auto depthStencilFormat = CanvasOptionalGPUTextureFormat{
1174
+ CanvasOptionalGPUTextureFormatNone
1175
+ };
1176
+
1177
+ v8::Local<v8::Value> depthStencilFormatVal;
1178
+ options->Get(context, ConvertToV8String(isolate, "depthStencilFormat")).ToLocal(
1179
+ &depthStencilFormatVal);
1180
+
1181
+ if (!depthStencilFormatVal.IsEmpty() && depthStencilFormatVal->IsString()) {
1182
+ auto depthStencilFormatStr = ConvertFromV8String(isolate, depthStencilFormatVal);
1183
+ depthStencilFormat = canvas_native_webgpu_enum_string_to_gpu_texture(
1184
+ depthStencilFormatStr.c_str());
1185
+ }
1186
+
1187
+ uint32_t sampleCount = 1;
1188
+
1189
+ bool depthReadOnly = false;
1190
+
1191
+ bool stencilReadOnly = false;
1192
+
1193
+ CanvasCreateRenderBundleEncoderDescriptor descriptor{
1194
+ *label,
1195
+ colorFormats.data(),
1196
+ colorFormats.size(),
1197
+ depthStencilFormat,
1198
+ sampleCount,
1199
+ depthReadOnly,
1200
+ stencilReadOnly
1201
+ };
1202
+
1203
+
1204
+ auto encoder = canvas_native_webgpu_device_create_render_bundle_encoder(ptr->GetGPUDevice(),
1205
+ &descriptor);
1206
+
1207
+ if (encoder != nullptr) {
1208
+ auto ret = GPURenderBundleEncoderImpl::NewInstance(isolate,
1209
+ new GPURenderBundleEncoderImpl(encoder));
1210
+ args.GetReturnValue().Set(ret);
1211
+ return;
1212
+ }
1213
+
1214
+ args.GetReturnValue().SetUndefined();
1215
+ }
1216
+
1217
+ struct RenderPipeLineAsyncData {
1218
+ char *label;
1219
+ char *vertex_entry_point;
1220
+ char *fragment_entry_point;
1221
+ CanvasConstants *constants;
1222
+ enum CanvasGPUErrorType type;
1223
+ char *errorMessage;
1224
+ const CanvasGPURenderPipeline *pipeline;
1225
+ CanvasPrimitiveState *primitive;
1226
+ CanvasMultisampleState *multisample;
1227
+ CanvasDepthStencilState *depth_stencil;
1228
+ CanvasConstants *vertex_constants;
1229
+
1230
+ ~RenderPipeLineAsyncData() {
1231
+ if (label != nullptr) {
1232
+ free(label);
1233
+ label = nullptr;
1234
+ }
1235
+
1236
+ if (constants != nullptr) {
1237
+ canvas_native_webgpu_constants_destroy(constants);
1238
+ constants = nullptr;
1239
+ }
1240
+
1241
+ if (errorMessage != nullptr) {
1242
+ canvas_native_string_destroy(errorMessage);
1243
+ errorMessage = nullptr;
1244
+ }
1245
+
1246
+ if (primitive != nullptr) {
1247
+ delete primitive;
1248
+ primitive = nullptr;
1249
+ }
1250
+
1251
+ if (multisample != nullptr) {
1252
+ delete multisample;
1253
+ multisample = nullptr;
1254
+ }
1255
+
1256
+ if (vertex_entry_point != nullptr) {
1257
+ free(vertex_entry_point);
1258
+ vertex_entry_point = nullptr;
1259
+ }
1260
+
1261
+ if (fragment_entry_point != nullptr) {
1262
+ free(fragment_entry_point);
1263
+ fragment_entry_point = nullptr;
1264
+ }
1265
+
1266
+ if (depth_stencil != nullptr) {
1267
+ delete depth_stencil;
1268
+ depth_stencil = nullptr;
1269
+ }
1270
+
1271
+ if (vertex_constants != nullptr) {
1272
+ canvas_native_webgpu_constants_destroy(vertex_constants);
1273
+ vertex_constants = nullptr;
1274
+ }
1275
+ }
1276
+ };
1277
+
1278
+ void GPUDeviceImpl::CreateRenderPipeline(const v8::FunctionCallbackInfo<v8::Value> &args) {
1279
+ GPUDeviceImpl *ptr = GetPointer(args.This());
1280
+ if (ptr == nullptr) {
1281
+ return;
1282
+ }
1283
+ auto isolate = args.GetIsolate();
1284
+ auto context = isolate->GetCurrentContext();
1285
+
1286
+ CanvasCreateRenderPipelineDescriptor descriptor{};
1287
+ descriptor.label = nullptr;
1288
+
1289
+ auto optionsVal = args[0];
1290
+
1291
+ if (!optionsVal->IsObject()) {
1292
+ // should error at this point
1293
+ return;
1294
+ }
1295
+ auto options = optionsVal.As<v8::Object>();
1296
+
1297
+ v8::Local<v8::Value> stencilValue;
1298
+ auto hasDepthStencil = options->Get(context, ConvertToV8String(isolate, "depthStencil")).ToLocal(
1299
+ &stencilValue);
1300
+
1301
+ CanvasDepthStencilState *stencil = nullptr;
1302
+
1303
+ if (hasDepthStencil && stencilValue->IsObject()) {
1304
+ auto stencilObj = stencilValue.As<v8::Object>();
1305
+ stencil = new CanvasDepthStencilState{};
1306
+ stencil->depth_bias = 0;
1307
+ stencil->depth_bias_clamp = 0;
1308
+ stencil->depth_bias_slope_scale = 0;
1309
+ stencil->stencil_read_mask = 0xFFFFFFFF;
1310
+ stencil->stencil_write_mask = 0xFFFFFFFF;
1311
+ stencil->stencil_front = CanvasStencilFaceState{
1312
+ CanvasCompareFunctionAlways,
1313
+ CanvasStencilOperationKeep,
1314
+ CanvasStencilOperationKeep,
1315
+ CanvasStencilOperationKeep
1316
+ };
1317
+
1318
+ stencil->stencil_back = CanvasStencilFaceState{
1319
+ CanvasCompareFunctionAlways,
1320
+ CanvasStencilOperationKeep,
1321
+ CanvasStencilOperationKeep,
1322
+ CanvasStencilOperationKeep
1323
+ };
1324
+ // todo throw if failed
1325
+ v8::Local<v8::Value> formatValue;
1326
+
1327
+ stencilObj->Get(context, ConvertToV8String(isolate, "format")).ToLocal(&formatValue);
1328
+ if (!formatValue.IsEmpty() && formatValue->IsString()) {
1329
+ auto val = ConvertFromV8String(isolate, formatValue);
1330
+ auto format = canvas_native_webgpu_enum_string_to_gpu_texture(
1331
+ val.c_str());
1332
+ if (format.tag ==
1333
+ CanvasOptionalGPUTextureFormat_Tag::CanvasOptionalGPUTextureFormatSome) {
1334
+ stencil->format = format.some;
1335
+ }
1336
+ } else {
1337
+ // todo throw
1338
+ }
1339
+
1340
+ v8::Local<v8::Value> depthBiasVal;
1341
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBias")).ToLocal(&depthBiasVal);
1342
+
1343
+ if (!depthBiasVal.IsEmpty() && depthBiasVal->IsInt32()) {
1344
+ stencil->depth_bias = depthBiasVal->Int32Value(context).FromJust();
1345
+ }
1346
+
1347
+ v8::Local<v8::Value> depthBiasClampVal;
1348
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBiasClamp")).ToLocal(
1349
+ &depthBiasClampVal);
1350
+
1351
+ if (!depthBiasClampVal.IsEmpty() && depthBiasClampVal->IsNumber()) {
1352
+ stencil->depth_bias_clamp = (float) depthBiasClampVal->NumberValue(context).FromJust();
1353
+ }
1354
+
1355
+
1356
+ v8::Local<v8::Value> depthBiasSlopeScaleVal;
1357
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBiasSlopeScale")).ToLocal(
1358
+ &depthBiasSlopeScaleVal);
1359
+
1360
+ if (!depthBiasSlopeScaleVal.IsEmpty() && depthBiasSlopeScaleVal->IsNumber()) {
1361
+ stencil->depth_bias_slope_scale = (float) depthBiasSlopeScaleVal->NumberValue(
1362
+ context).FromJust();
1363
+ }
1364
+
1365
+ v8::Local<v8::Value> depthCompareVal;
1366
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthCompare")).ToLocal(
1367
+ &depthCompareVal);
1368
+
1369
+ auto depthCompareStr = ConvertFromV8String(isolate, depthCompareVal);
1370
+
1371
+ if (depthCompareStr == "never") {
1372
+ stencil->depth_compare = CanvasCompareFunctionNever;
1373
+ } else if (depthCompareStr == "less") {
1374
+ stencil->depth_compare = CanvasCompareFunctionLess;
1375
+ } else if (depthCompareStr == "equal") {
1376
+ stencil->depth_compare = CanvasCompareFunctionEqual;
1377
+ } else if (depthCompareStr == "less-equal") {
1378
+ stencil->depth_compare = CanvasCompareFunctionLessEqual;
1379
+ } else if (depthCompareStr == "greater") {
1380
+ stencil->depth_compare = CanvasCompareFunctionGreater;
1381
+ } else if (depthCompareStr == "not-equal") {
1382
+ stencil->depth_compare = CanvasCompareFunctionNotEqual;
1383
+ } else if (depthCompareStr == "greater-equal") {
1384
+ stencil->depth_compare = CanvasCompareFunctionGreaterEqual;
1385
+ } else if (depthCompareStr == "always") {
1386
+ stencil->depth_compare = CanvasCompareFunctionAlways;
1387
+ }
1388
+
1389
+ stencil->depth_write_enabled = stencilObj->Get(context, ConvertToV8String(isolate,
1390
+ "depthWriteEnabled")).ToLocalChecked()->BooleanValue(
1391
+ isolate);
1392
+
1393
+
1394
+ v8::Local<v8::Value> stencilBackVal;
1395
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilBack")).ToLocal(
1396
+ &stencilBackVal);
1397
+
1398
+ if (!stencilBackVal.IsEmpty() && stencilBackVal->IsObject()) {
1399
+ auto stencilBackObj = stencilBackVal.As<v8::Object>();
1400
+
1401
+ v8::Local<v8::Value> compareVal;
1402
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(
1403
+ &compareVal);
1404
+
1405
+ stencil->stencil_back.compare = ParseCompareFunction(isolate, compareVal,
1406
+ stencil->stencil_back.compare);
1407
+
1408
+ v8::Local<v8::Value> depthFailOpVal;
1409
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "depthFailOp")).ToLocal(
1410
+ &depthFailOpVal);
1411
+
1412
+ stencil->stencil_back.depth_fail_op = ParseStencilOperation(isolate, depthFailOpVal,
1413
+ stencil->stencil_back.depth_fail_op);
1414
+
1415
+
1416
+ v8::Local<v8::Value> failOpVal;
1417
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "failOp")).ToLocal(
1418
+ &failOpVal);
1419
+
1420
+ stencil->stencil_back.fail_op = ParseStencilOperation(isolate, failOpVal,
1421
+ stencil->stencil_back.fail_op);
1422
+
1423
+ v8::Local<v8::Value> passOpVal;
1424
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "passOp")).ToLocal(
1425
+ &passOpVal);
1426
+
1427
+ stencil->stencil_back.pass_op = ParseStencilOperation(isolate, passOpVal,
1428
+ stencil->stencil_back.pass_op);
1429
+
1430
+ }
1431
+
1432
+
1433
+ v8::Local<v8::Value> stencilFrontVal;
1434
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilFront")).ToLocal(
1435
+ &stencilFrontVal);
1436
+
1437
+ if (!stencilFrontVal.IsEmpty() && stencilFrontVal->IsObject()) {
1438
+ auto stencilFrontObj = stencilFrontVal.As<v8::Object>();
1439
+
1440
+ v8::Local<v8::Value> compareVal;
1441
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(
1442
+ &compareVal);
1443
+
1444
+ stencil->stencil_front.compare = ParseCompareFunction(isolate, compareVal,
1445
+ stencil->stencil_front.compare);
1446
+
1447
+ v8::Local<v8::Value> depthFailOpVal;
1448
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "depthFailOp")).ToLocal(
1449
+ &depthFailOpVal);
1450
+
1451
+ stencil->stencil_front.depth_fail_op = ParseStencilOperation(isolate, depthFailOpVal,
1452
+ stencil->stencil_front.depth_fail_op);
1453
+
1454
+
1455
+ v8::Local<v8::Value> failOpVal;
1456
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "failOp")).ToLocal(
1457
+ &failOpVal);
1458
+
1459
+ stencil->stencil_front.fail_op = ParseStencilOperation(isolate, failOpVal,
1460
+ stencil->stencil_front.fail_op);
1461
+
1462
+ v8::Local<v8::Value> passOpVal;
1463
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "passOp")).ToLocal(
1464
+ &passOpVal);
1465
+
1466
+ stencil->stencil_front.pass_op = ParseStencilOperation(isolate, passOpVal,
1467
+ stencil->stencil_front.pass_op);
1468
+
1469
+ }
1470
+
1471
+ v8::Local<v8::Value> stencilReadMaskVal;
1472
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilReadMask")).ToLocal(
1473
+ &stencilReadMaskVal);
1474
+
1475
+ if (!stencilReadMaskVal.IsEmpty() && stencilReadMaskVal->IsUint32()) {
1476
+ stencil->stencil_read_mask = stencilReadMaskVal->Uint32Value(context).FromJust();
1477
+ }
1478
+
1479
+
1480
+ v8::Local<v8::Value> stencilWriteMaskVal;
1481
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilWriteMask")).ToLocal(
1482
+ &stencilWriteMaskVal);
1483
+
1484
+ if (!stencilWriteMaskVal.IsEmpty() && stencilWriteMaskVal->IsUint32()) {
1485
+ stencil->stencil_write_mask = stencilWriteMaskVal->Uint32Value(context).FromJust();
1486
+ }
1487
+
1488
+ descriptor.depth_stencil = stencil;
1489
+
1490
+ }
1491
+
1492
+
1493
+ v8::Local<v8::Value> fragmentValue;
1494
+ auto hasFragment = options->Get(context, ConvertToV8String(isolate, "fragment")).ToLocal(
1495
+ &fragmentValue);
1496
+
1497
+ CanvasFragmentState *fragment = nullptr;
1498
+
1499
+ std::vector<CanvasColorTargetState> targets;
1500
+
1501
+ if (hasFragment && fragmentValue->IsObject()) {
1502
+ auto fragmentValueObj = fragmentValue.As<v8::Object>();
1503
+ fragment = new CanvasFragmentState{};
1504
+ fragment->entry_point = nullptr;
1505
+
1506
+ v8::Local<v8::Value> targetsVal;
1507
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "targets")).ToLocal(&targetsVal);
1508
+
1509
+
1510
+ auto targetsArray = targetsVal.As<v8::Array>();
1511
+ auto len = targetsArray->Length();
1512
+
1513
+ for (int i = 0; i < len; i++) {
1514
+ auto state = targetsArray->Get(context, i).ToLocalChecked().As<v8::Object>();
1515
+
1516
+ auto formatVal = state->Get(context,
1517
+ ConvertToV8String(isolate, "format")).ToLocalChecked();
1518
+ auto formatStr = ConvertFromV8String(isolate, formatVal);
1519
+ auto formatResult = canvas_native_webgpu_enum_string_to_gpu_texture(formatStr.c_str());
1520
+
1521
+
1522
+ if (formatResult.tag == CanvasOptionalGPUTextureFormatNone) {
1523
+ // todo throw
1524
+ args.GetReturnValue().SetUndefined();
1525
+ return;
1526
+ } else {}
1527
+
1528
+ auto format = CanvasGPUTextureFormat{
1529
+ formatResult.some.tag
1530
+ };
1531
+
1532
+ uint32_t writeMask = 0xF;
1533
+
1534
+ v8::Local<v8::Value> writeMaskVal;
1535
+
1536
+ auto hasWriteMask = state->Get(context, ConvertToV8String(isolate, "writeMask")).ToLocal(&writeMaskVal);
1537
+
1538
+ if (hasWriteMask && writeMaskVal->IsUint32()) {
1539
+ writeMask = writeMaskVal->Uint32Value(context).FromJust();
1540
+ }
1541
+
1542
+ CanvasOptionalBlendState blend{
1543
+ CanvasOptionalBlendStateNone
1544
+ };
1545
+
1546
+ v8::Local<v8::Value> blendVal;
1547
+
1548
+ auto hasBlend = state->Get(context, ConvertToV8String(isolate, "blend")).ToLocal(&blendVal);
1549
+
1550
+ if (hasBlend && blendVal->IsObject()) {
1551
+ auto blendObj = blendVal.As<v8::Object>();
1552
+ auto alpha = blendObj->Get(context, ConvertToV8String(isolate,
1553
+ "alpha")).ToLocalChecked().As<v8::Object>();
1554
+
1555
+ v8::Local<v8::Value> alphaSrcFactorVal;
1556
+
1557
+ alpha->Get(context,
1558
+ ConvertToV8String(isolate,
1559
+ "srcFactor")).ToLocal(&alphaSrcFactorVal);
1560
+
1561
+ auto alphaSrcFactor = ParseBlendFactor(isolate, alphaSrcFactorVal,
1562
+ CanvasBlendFactorZero);
1563
+
1564
+ v8::Local<v8::Value> alphaDstFactorVal;
1565
+ alpha->Get(context,
1566
+ ConvertToV8String(isolate,
1567
+ "dstFactor")).ToLocal(&alphaDstFactorVal);
1568
+
1569
+ auto alphaDstFactor = ParseBlendFactor(isolate, alphaDstFactorVal,
1570
+ CanvasBlendFactorZero);
1571
+
1572
+ v8::Local<v8::Value> alphaOperationVal;
1573
+
1574
+ alpha->Get(context,
1575
+ ConvertToV8String(isolate,
1576
+ "operation")).ToLocal(&alphaOperationVal);
1577
+
1578
+ auto alphaOperation = ParseBlendOperation(isolate, alphaOperationVal,
1579
+ CanvasBlendOperationAdd);
1580
+
1581
+ auto alpha_val = CanvasBlendComponent{alphaSrcFactor, alphaDstFactor,
1582
+ alphaOperation};
1583
+
1584
+ auto color = blendObj->Get(context, ConvertToV8String(isolate,
1585
+ "color")).ToLocalChecked().As<v8::Object>();
1586
+
1587
+
1588
+ v8::Local<v8::Value> colorSrcFactorVal;
1589
+
1590
+ color->Get(context,
1591
+ ConvertToV8String(isolate,
1592
+ "srcFactor")).ToLocal(&colorSrcFactorVal);
1593
+
1594
+ auto colorSrcFactor = ParseBlendFactor(isolate, colorSrcFactorVal,
1595
+ CanvasBlendFactorZero);
1596
+
1597
+ v8::Local<v8::Value> colorDstFactorVal;
1598
+ color->Get(context,
1599
+ ConvertToV8String(isolate,
1600
+ "dstFactor")).ToLocal(&colorDstFactorVal);
1601
+
1602
+ auto colorDstFactor = ParseBlendFactor(isolate, colorDstFactorVal,
1603
+ CanvasBlendFactorZero);
1604
+
1605
+ v8::Local<v8::Value> colorOperationVal;
1606
+
1607
+ color->Get(context,
1608
+ ConvertToV8String(isolate,
1609
+ "operation")).ToLocal(&colorOperationVal);
1610
+
1611
+ auto colorOperation = ParseBlendOperation(isolate, colorOperationVal,
1612
+ CanvasBlendOperationAdd);
1613
+
1614
+
1615
+ auto color_val = CanvasBlendComponent{colorSrcFactor, colorDstFactor,
1616
+ colorOperation};
1617
+
1618
+
1619
+ blend = CanvasOptionalBlendState{
1620
+ CanvasOptionalBlendStateSome,
1621
+ CanvasBlendState{
1622
+ color_val, alpha_val
1623
+ }
1624
+ };
1625
+ }
1626
+
1627
+ auto targetState = CanvasColorTargetState{
1628
+ format,
1629
+ blend,
1630
+ writeMask
1631
+ };
1632
+
1633
+ targets.push_back(targetState);
1634
+ }
1635
+
1636
+ if (!targets.empty()) {
1637
+ fragment->targets = targets.data();
1638
+ fragment->targets_size = targets.size();
1639
+ }
1640
+
1641
+ v8::Local<v8::Value> constantsVal;
1642
+ auto hasConstants = fragmentValueObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(
1643
+ &constantsVal);
1644
+
1645
+ if (hasConstants && constantsVal->IsMap()) {
1646
+ auto constants = constantsVal.As<v8::Map>();
1647
+ auto keyValues = constants->AsArray();
1648
+ auto length = keyValues->Length();
1649
+ CanvasConstants *store = nullptr;
1650
+
1651
+ if (length > 0) {
1652
+ store = canvas_native_webgpu_constants_create();
1653
+ for (int i = 0; i < length; i += 2) {
1654
+ auto k = i;
1655
+ auto v = k + 1;
1656
+
1657
+ v8::Local<v8::Value> keyVal;
1658
+ keyValues->Get(context, k).ToLocal(&keyVal);
1659
+ v8::Local<v8::Value> valueVal;
1660
+ keyValues->Get(context, v).ToLocal(&valueVal);
1661
+
1662
+
1663
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
1664
+ valueVal->IsNumber()) {
1665
+ canvas_native_webgpu_constants_insert(
1666
+ store,
1667
+ *v8::String::Utf8Value(isolate, keyVal),
1668
+ valueVal.As<v8::Number>()->Value()
1669
+ );
1670
+ }
1671
+
1672
+ }
1673
+ }
1674
+ fragment->constants = store;
1675
+ }
1676
+
1677
+
1678
+ v8::Local<v8::Value> entryPoint;
1679
+ auto hasEntryPoint = fragmentValueObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(
1680
+ &entryPoint);
1681
+
1682
+
1683
+ if (hasEntryPoint && entryPoint->IsString()) {
1684
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
1685
+ char *entry_point = (char *) malloc(ep.length());
1686
+ std::strcpy(entry_point, *ep);
1687
+
1688
+ fragment->entry_point = entry_point;
1689
+ }
1690
+
1691
+
1692
+ v8::Local<v8::Value> moduleVal;
1693
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
1694
+
1695
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
1696
+
1697
+ fragment->module = module->GetShaderModule();
1698
+
1699
+ descriptor.fragment = fragment;
1700
+
1701
+ }
1702
+
1703
+
1704
+ v8::Local<v8::Value> labelVal;
1705
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(
1706
+ &labelVal);
1707
+
1708
+
1709
+ auto label = GPULabel(isolate, labelVal);
1710
+
1711
+ descriptor.label = *label;
1712
+
1713
+
1714
+ v8::Local<v8::Value> layoutVal;
1715
+ options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(
1716
+ &layoutVal);
1717
+
1718
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout;
1719
+
1720
+ if (layoutVal->IsString()) {
1721
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1722
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
1723
+ };
1724
+ } else if (!layoutVal->IsNullOrUndefined() && layoutVal->IsObject()) {
1725
+ auto pipeline = GPUPipelineLayoutImpl::GetPointer(layoutVal.As<v8::Object>());
1726
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1727
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeLayout,
1728
+ layout.layout = pipeline->GetPipeline()
1729
+ };
1730
+ } else {
1731
+ // todo throw ?
1732
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
1733
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
1734
+ };
1735
+ }
1736
+
1737
+ descriptor.layout = layout;
1738
+
1739
+
1740
+ v8::Local<v8::Value> multisampleValue;
1741
+ auto hasMultisample = options->Get(context, ConvertToV8String(isolate, "multisample")).ToLocal(
1742
+ &multisampleValue);
1743
+
1744
+
1745
+ CanvasMultisampleState *multisample = nullptr;
1746
+
1747
+ if (hasMultisample && multisampleValue->IsObject()) {
1748
+ auto multisampleObj = multisampleValue.As<v8::Object>();
1749
+ multisample = new CanvasMultisampleState{};
1750
+ multisample->alpha_to_coverage_enabled = false;
1751
+ multisample->count = 1;
1752
+ multisample->mask = 0xFFFFFFFF;
1753
+
1754
+ v8::Local<v8::Value> alphaToCoverageEnabled;
1755
+ v8::Local<v8::Value> count;
1756
+ v8::Local<v8::Value> mask;
1757
+
1758
+ auto hasAlphaToCoverageEnabled = multisampleObj->Get(context, ConvertToV8String(isolate, "alphaToCoverageEnabled")).
1759
+ ToLocal(&alphaToCoverageEnabled);
1760
+
1761
+ if (hasAlphaToCoverageEnabled && alphaToCoverageEnabled->IsBoolean()) {
1762
+ multisample->alpha_to_coverage_enabled = alphaToCoverageEnabled->BooleanValue(
1763
+ isolate);
1764
+ }
1765
+
1766
+ auto hasCount = multisampleObj->Get(context, ConvertToV8String(isolate, "count")).
1767
+ ToLocal(&count);
1768
+
1769
+ if (hasCount && count->IsUint32()) {
1770
+ multisample->count = count.As<v8::Uint32>()->Value();
1771
+ }
1772
+
1773
+ auto hasMask = multisampleObj->Get(context, ConvertToV8String(isolate, "mask")).
1774
+ ToLocal(&mask);
1775
+
1776
+ if (hasMask && mask->IsNumber()) {
1777
+ // todo verify mask
1778
+ auto maskValue = mask.As<v8::Number>()->Value();
1779
+ multisample->mask = (uint64_t) maskValue;
1780
+ }
1781
+
1782
+
1783
+ descriptor.multisample = multisample;
1784
+
1785
+ }
1786
+
1787
+
1788
+ v8::Local<v8::Value> primitiveValue;
1789
+ auto hasPrimitive = options->Get(context, ConvertToV8String(isolate, "primitive")).ToLocal(
1790
+ &primitiveValue);
1791
+
1792
+
1793
+ CanvasPrimitiveState *primitive = nullptr;
1794
+
1795
+ if (hasPrimitive && primitiveValue->IsObject()) {
1796
+ auto primitiveObj = primitiveValue.As<v8::Object>();
1797
+ primitive = new CanvasPrimitiveState{};
1798
+
1799
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1800
+ primitive->front_face = CanvasFrontFaceCcw;
1801
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1802
+ CanvasOptionalIndexFormatNone
1803
+ };
1804
+
1805
+ primitive->topology = CanvasPrimitiveTopologyTriangleList;
1806
+
1807
+ primitive->unclipped_depth = false;
1808
+
1809
+
1810
+ v8::Local<v8::Value> cullModeValue;
1811
+
1812
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "cullMode")).ToLocal(
1813
+ &cullModeValue)) {
1814
+ if (cullModeValue->IsUint32()) {
1815
+ auto cullMode = cullModeValue.As<v8::Uint32>()->Value();
1816
+
1817
+ switch (cullMode) {
1818
+ case 0:
1819
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1820
+ break;
1821
+ case 1:
1822
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeFront;
1823
+ break;
1824
+ case 2:
1825
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeBack;
1826
+ break;
1827
+ default:
1828
+ break;
1829
+ }
1830
+ } else if (cullModeValue->IsString()) {
1831
+
1832
+ auto cullMode = ConvertFromV8String(isolate, cullModeValue);
1833
+
1834
+ if (cullMode == "none") {
1835
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
1836
+ } else if (cullMode == "front") {
1837
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeFront;
1838
+ } else if (cullMode == "back") {
1839
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeBack;
1840
+ }
1841
+ }
1842
+
1843
+ }
1844
+
1845
+ v8::Local<v8::Value> frontFaceValue;
1846
+
1847
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "frontFace")).ToLocal(
1848
+ &frontFaceValue)) {
1849
+ if (frontFaceValue->IsUint32()) {
1850
+ auto frontFace = frontFaceValue.As<v8::Uint32>()->Value();
1851
+ switch (frontFace) {
1852
+ case 0:
1853
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCcw;
1854
+ break;
1855
+ case 1:
1856
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCw;
1857
+ break;
1858
+ default:
1859
+ break;
1860
+ }
1861
+ } else if (frontFaceValue->IsString()) {
1862
+ auto frontFace = ConvertFromV8String(isolate, frontFaceValue);
1863
+ if (frontFace == "ccw") {
1864
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCcw;
1865
+ } else if (frontFace == "cw") {
1866
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCw;
1867
+ }
1868
+ }
1869
+ }
1870
+
1871
+
1872
+ v8::Local<v8::Value> stripIndexFormatValue;
1873
+
1874
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "stripIndexFormat")).ToLocal(
1875
+ &stripIndexFormatValue)) {
1876
+ if (stripIndexFormatValue->IsUint32()) {
1877
+ auto stripIndexFormat = stripIndexFormatValue.As<v8::Uint32>()->Value();
1878
+ switch (stripIndexFormat) {
1879
+ case 0:
1880
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1881
+ CanvasOptionalIndexFormatSome,
1882
+ CanvasIndexFormat::CanvasIndexFormatUint16
1883
+ };
1884
+ break;
1885
+ case 1:
1886
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1887
+ CanvasOptionalIndexFormatSome,
1888
+ CanvasIndexFormat::CanvasIndexFormatUint32
1889
+ };
1890
+ break;
1891
+ default:
1892
+ break;
1893
+ }
1894
+ } else if (stripIndexFormatValue->IsString()) {
1895
+ auto stripIndexFormat = ConvertFromV8String(isolate, stripIndexFormatValue);
1896
+
1897
+
1898
+ if (stripIndexFormat == "uint16") {
1899
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1900
+ CanvasOptionalIndexFormatSome,
1901
+ CanvasIndexFormat::CanvasIndexFormatUint16
1902
+ };
1903
+ } else if (stripIndexFormat == "uint32") {
1904
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
1905
+ CanvasOptionalIndexFormatSome,
1906
+ CanvasIndexFormat::CanvasIndexFormatUint32
1907
+ };
1908
+ }
1909
+ }
1910
+ }
1911
+
1912
+
1913
+ v8::Local<v8::Value> topologyValue;
1914
+
1915
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "topology")).ToLocal(
1916
+ &topologyValue)) {
1917
+
1918
+ if (topologyValue->IsUint32()) {
1919
+ auto topology = topologyValue.As<v8::Uint32>()->Value();
1920
+ switch (topology) {
1921
+ case 0:
1922
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyPointList;
1923
+ break;
1924
+ case 1:
1925
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineList;
1926
+ break;
1927
+ case 2:
1928
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineStrip;
1929
+ break;
1930
+ case 3:
1931
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleList;
1932
+ break;
1933
+ case 4:
1934
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleStrip;
1935
+ break;
1936
+ default:
1937
+ break;
1938
+ }
1939
+ } else if (topologyValue->IsString()) {
1940
+ auto topology = ConvertFromV8String(isolate, topologyValue);
1941
+ if (topology == "line-list") {
1942
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineList;
1943
+ } else if (topology == "line-strip") {
1944
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineStrip;
1945
+ } else if (topology == "point-list") {
1946
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyPointList;
1947
+ } else if (topology == "triangle-list") {
1948
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleList;
1949
+ } else if (topology == "triangle-strip") {
1950
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleStrip;
1951
+ }
1952
+ }
1953
+
1954
+ }
1955
+
1956
+
1957
+ v8::Local<v8::Value> unclippedDepthValue;
1958
+ primitiveObj->Get(context, ConvertToV8String(isolate, "unclippedDepth")).ToLocal(
1959
+ &unclippedDepthValue);
1960
+
1961
+ if (!unclippedDepthValue.IsEmpty() && unclippedDepthValue->IsBoolean()) {
1962
+ primitive->unclipped_depth = unclippedDepthValue->BooleanValue(isolate);
1963
+ }
1964
+
1965
+ descriptor.primitive = primitive;
1966
+
1967
+ }
1968
+
1969
+
1970
+ v8::Local<v8::Value> vertexValue;
1971
+ auto hasVertex = options->Get(context, ConvertToV8String(isolate, "vertex")).ToLocal(
1972
+ &vertexValue);
1973
+
1974
+
1975
+ CanvasVertexState *vertex = nullptr;
1976
+
1977
+ std::vector<CanvasVertexBufferLayout> bufferLayout;
1978
+
1979
+ std::vector<std::vector<CanvasVertexAttribute>> attributes;
1980
+
1981
+ if (hasVertex && vertexValue->IsObject()) {
1982
+ auto vertexObj = vertexValue.As<v8::Object>();
1983
+ vertex = new CanvasVertexState{};
1984
+
1985
+ v8::Local<v8::Value> moduleVal;
1986
+ vertexObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
1987
+
1988
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
1989
+
1990
+ vertex->module = module->GetShaderModule();
1991
+
1992
+ v8::Local<v8::Value> constantsVal;
1993
+ auto hasConstants = vertexObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(&constantsVal);
1994
+
1995
+ if (hasConstants && constantsVal->IsMap()) {
1996
+ auto constants = constantsVal.As<v8::Map>();
1997
+ auto keyValues = constants->AsArray();
1998
+ auto len = keyValues->Length();
1999
+ CanvasConstants *store = nullptr;
2000
+
2001
+ if (len > 0) {
2002
+ store = canvas_native_webgpu_constants_create();
2003
+ for (int i = 0; i < len; i += 2) {
2004
+ auto k = i;
2005
+ auto v = k + 1;
2006
+
2007
+ v8::Local<v8::Value> keyVal;
2008
+ keyValues->Get(context, k).ToLocal(&keyVal);
2009
+ v8::Local<v8::Value> valueVal;
2010
+ keyValues->Get(context, v).ToLocal(&valueVal);
2011
+
2012
+
2013
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
2014
+ valueVal->IsNumber()) {
2015
+ canvas_native_webgpu_constants_insert(
2016
+ store,
2017
+ *v8::String::Utf8Value(isolate, keyVal),
2018
+ valueVal.As<v8::Number>()->Value()
2019
+ );
2020
+ }
2021
+
2022
+ }
2023
+ }
2024
+
2025
+ vertex->constants = store;
2026
+
2027
+ }
2028
+
2029
+ v8::Local<v8::Value> buffersVal;
2030
+ auto hasBuffers = vertexObj->Get(context, ConvertToV8String(isolate, "buffers")).ToLocal(&buffersVal);
2031
+
2032
+ uint64_t stride = 0;
2033
+ if (hasBuffers && buffersVal->IsArray()) {
2034
+ auto buffers = buffersVal.As<v8::Array>();
2035
+ auto len = buffers->Length();
2036
+
2037
+ for (int i = 0; i < len; i++) {
2038
+ auto buffer = buffers->Get(context, i).ToLocalChecked().As<v8::Object>();
2039
+
2040
+ v8::Local<v8::Value> arrayStride;
2041
+
2042
+ auto hasArrayStride = buffer->Get(context, ConvertToV8String(isolate, "arrayStride")).ToLocal(
2043
+ &arrayStride);
2044
+
2045
+ if (hasArrayStride && arrayStride->IsNumber()) {
2046
+ stride = (uint64_t) arrayStride.As<v8::Number>()->Value();
2047
+ }
2048
+
2049
+ std::vector<CanvasVertexAttribute> attributes_;
2050
+
2051
+ v8::Local<v8::Value> attributesValue;
2052
+
2053
+ auto hasAttributes = buffer->Get(context, ConvertToV8String(isolate, "attributes")).ToLocal(
2054
+ &attributesValue);
2055
+
2056
+ if (hasAttributes && attributesValue->IsArray()) {
2057
+ auto attributes_array = attributesValue.As<v8::Array>();
2058
+ auto attributes_len = attributes_array->Length();
2059
+
2060
+ for (int j = 0; j < attributes_len; j++) {
2061
+ auto attr = attributes_array->Get(context,
2062
+ j).ToLocalChecked().As<v8::Object>();
2063
+ auto format = attr->Get(context, ConvertToV8String(isolate,
2064
+ "format")).ToLocalChecked()->Uint32Value(
2065
+ context).ToChecked();
2066
+
2067
+ auto offset = (uint64_t) attr->Get(context, ConvertToV8String(isolate,
2068
+ "offset")).ToLocalChecked()->NumberValue(
2069
+ context).ToChecked();
2070
+ auto shaderLocation = attr->Get(context, ConvertToV8String(isolate,
2071
+ "shaderLocation")).ToLocalChecked()->Uint32Value(
2072
+ context).ToChecked();
2073
+
2074
+ auto attribute = CanvasVertexAttribute{
2075
+ (CanvasVertexFormat) format,
2076
+ offset,
2077
+ shaderLocation
2078
+ };
2079
+
2080
+ attributes_.push_back(attribute);
2081
+ }
2082
+
2083
+ attributes.push_back(attributes_);
2084
+ }
2085
+
2086
+
2087
+ CanvasVertexStepMode stepMode = CanvasVertexStepModeVertex;
2088
+
2089
+ v8::Local<v8::Value> stepModeVal;
2090
+
2091
+ buffer->Get(context, ConvertToV8String(isolate, "stepMode")).ToLocal(
2092
+ &stepModeVal);
2093
+
2094
+
2095
+ if (!stepModeVal.IsEmpty()) {
2096
+ if (stepModeVal->IsUint32()) {
2097
+ switch (stepModeVal.As<v8::Uint32>()->Value()) {
2098
+ case 0:
2099
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeVertex;
2100
+ break;
2101
+ case 1:
2102
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeInstance;
2103
+ break;
2104
+ }
2105
+ } else if (stepModeVal->IsString()) {
2106
+ auto stepModeStr = ConvertFromV8String(isolate, stepModeVal);
2107
+ if (stepModeStr == "vertex") {
2108
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeVertex;
2109
+ } else if (stepModeStr == "instance") {
2110
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeInstance;
2111
+ }
2112
+ }
2113
+ }
2114
+
2115
+ auto vertexBufferLayout = CanvasVertexBufferLayout{
2116
+ stride,
2117
+ stepMode,
2118
+ attributes[i].data(),
2119
+ attributes[i].size()
2120
+ };
2121
+
2122
+ bufferLayout.push_back(vertexBufferLayout);
2123
+ }
2124
+
2125
+ vertex->buffers = bufferLayout.data();
2126
+ vertex->buffers_size = bufferLayout.size();
2127
+
2128
+ }
2129
+
2130
+
2131
+ v8::Local<v8::Value> entryPoint;
2132
+ vertexObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(&entryPoint);
2133
+
2134
+
2135
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
2136
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
2137
+ char *entry_point = (char *) malloc(ep.length());
2138
+ std::strcpy(entry_point, *ep);
2139
+ vertex->entry_point = entry_point;
2140
+ }
2141
+
2142
+ descriptor.vertex = vertex;
2143
+
2144
+ }
2145
+
2146
+
2147
+ auto pipeline = canvas_native_webgpu_device_create_render_pipeline(ptr->GetGPUDevice(),
2148
+ &descriptor);
2149
+
2150
+
2151
+ if (descriptor.fragment != nullptr) {
2152
+ if (descriptor.fragment->entry_point != nullptr) {
2153
+ free((void *) descriptor.fragment->entry_point);
2154
+ }
2155
+ }
2156
+
2157
+ if (descriptor.primitive != nullptr) {
2158
+ delete descriptor.primitive;
2159
+ descriptor.primitive = nullptr;
2160
+ }
2161
+
2162
+ if (descriptor.multisample != nullptr) {
2163
+ delete descriptor.multisample;
2164
+ descriptor.multisample = nullptr;
2165
+ }
2166
+
2167
+
2168
+ if (descriptor.vertex != nullptr) {
2169
+ if (descriptor.vertex->constants != nullptr) {
2170
+ canvas_native_webgpu_constants_destroy(
2171
+ (CanvasConstants *) descriptor.vertex->constants);
2172
+ }
2173
+
2174
+ if (descriptor.vertex->entry_point != nullptr) {
2175
+ free((void *) descriptor.vertex->entry_point);
2176
+ }
2177
+
2178
+ }
2179
+
2180
+ if (descriptor.depth_stencil != nullptr) {
2181
+ delete descriptor.depth_stencil;
2182
+ descriptor.depth_stencil = nullptr;
2183
+ }
2184
+
2185
+
2186
+ if (pipeline != nullptr) {
2187
+ auto ret = GPURenderPipelineImpl::NewInstance(isolate, new GPURenderPipelineImpl(pipeline));
2188
+ args.GetReturnValue().Set(ret);
2189
+ return;
2190
+ }
2191
+
2192
+ args.GetReturnValue().SetUndefined();
2193
+ }
2194
+
2195
+ void GPUDeviceImpl::CreateRenderPipelineAsync(const v8::FunctionCallbackInfo<v8::Value> &args) {
2196
+ GPUDeviceImpl *ptr = GetPointer(args.This());
2197
+ if (ptr == nullptr) {
2198
+ return;
2199
+ }
2200
+ auto isolate = args.GetIsolate();
2201
+ auto context = isolate->GetCurrentContext();
2202
+
2203
+ CanvasCreateRenderPipelineDescriptor descriptor{};
2204
+ descriptor.label = nullptr;
2205
+
2206
+ auto optionsVal = args[0];
2207
+ auto callback = args[1];
2208
+
2209
+ if (!optionsVal->IsObject()) {
2210
+ // should error at this point
2211
+ return;
2212
+ }
2213
+ auto options = optionsVal.As<v8::Object>();
2214
+ GPULabel label;
2215
+
2216
+ v8::Local<v8::Value> stencilValue;
2217
+ options->Get(context, ConvertToV8String(isolate, "depthStencil")).ToLocal(
2218
+ &stencilValue);
2219
+
2220
+ CanvasDepthStencilState *stencil = nullptr;
2221
+
2222
+ if (!stencilValue.IsEmpty() && stencilValue->IsObject()) {
2223
+ auto stencilObj = stencilValue.As<v8::Object>();
2224
+ stencil = new CanvasDepthStencilState{};
2225
+ stencil->depth_bias = 0;
2226
+ stencil->depth_bias_clamp = 0;
2227
+ stencil->depth_bias_slope_scale = 0;
2228
+ stencil->stencil_read_mask = 0xFFFFFFFF;
2229
+ stencil->stencil_write_mask = 0xFFFFFFFF;
2230
+ stencil->stencil_front = CanvasStencilFaceState{
2231
+ CanvasCompareFunctionAlways,
2232
+ CanvasStencilOperationKeep,
2233
+ CanvasStencilOperationKeep,
2234
+ CanvasStencilOperationKeep
2235
+ };
2236
+
2237
+ stencil->stencil_back = CanvasStencilFaceState{
2238
+ CanvasCompareFunctionAlways,
2239
+ CanvasStencilOperationKeep,
2240
+ CanvasStencilOperationKeep,
2241
+ CanvasStencilOperationKeep
2242
+ };
2243
+ // todo throw if failed
2244
+ v8::Local<v8::Value> formatValue;
2245
+
2246
+ stencilObj->Get(context, ConvertToV8String(isolate, "format")).ToLocal(&formatValue);
2247
+ if (!formatValue.IsEmpty() && formatValue->IsString()) {
2248
+ auto val = ConvertFromV8String(isolate, formatValue);
2249
+ auto format = canvas_native_webgpu_enum_string_to_gpu_texture(
2250
+ val.c_str());
2251
+ if (format.tag ==
2252
+ CanvasOptionalGPUTextureFormat_Tag::CanvasOptionalGPUTextureFormatSome) {
2253
+ stencil->format = format.some;
2254
+ }
2255
+ } else {
2256
+ // todo throw
2257
+ }
2258
+
2259
+ v8::Local<v8::Value> depthBiasVal;
2260
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBias")).ToLocal(&depthBiasVal);
2261
+
2262
+ if (!depthBiasVal.IsEmpty() && depthBiasVal->IsInt32()) {
2263
+ stencil->depth_bias = depthBiasVal->Int32Value(context).FromJust();
2264
+ }
2265
+
2266
+ v8::Local<v8::Value> depthBiasClampVal;
2267
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBiasClamp")).ToLocal(
2268
+ &depthBiasClampVal);
2269
+
2270
+ if (!depthBiasClampVal.IsEmpty() && depthBiasClampVal->IsNumber()) {
2271
+ stencil->depth_bias_clamp = (float) depthBiasClampVal->NumberValue(context).FromJust();
2272
+ }
2273
+
2274
+
2275
+ v8::Local<v8::Value> depthBiasSlopeScaleVal;
2276
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthBiasSlopeScale")).ToLocal(
2277
+ &depthBiasSlopeScaleVal);
2278
+
2279
+ if (!depthBiasSlopeScaleVal.IsEmpty() && depthBiasSlopeScaleVal->IsNumber()) {
2280
+ stencil->depth_bias_slope_scale = (float) depthBiasSlopeScaleVal->NumberValue(
2281
+ context).FromJust();
2282
+ }
2283
+
2284
+ v8::Local<v8::Value> depthCompareVal;
2285
+ stencilObj->Get(context, ConvertToV8String(isolate, "depthCompare")).ToLocal(
2286
+ &depthCompareVal);
2287
+
2288
+ auto depthCompareStr = ConvertFromV8String(isolate, depthCompareVal);
2289
+
2290
+ if (depthCompareStr == "never") {
2291
+ stencil->depth_compare = CanvasCompareFunctionNever;
2292
+ } else if (depthCompareStr == "less") {
2293
+ stencil->depth_compare = CanvasCompareFunctionLess;
2294
+ } else if (depthCompareStr == "equal") {
2295
+ stencil->depth_compare = CanvasCompareFunctionEqual;
2296
+ } else if (depthCompareStr == "less-equal") {
2297
+ stencil->depth_compare = CanvasCompareFunctionLessEqual;
2298
+ } else if (depthCompareStr == "greater") {
2299
+ stencil->depth_compare = CanvasCompareFunctionGreater;
2300
+ } else if (depthCompareStr == "not-equal") {
2301
+ stencil->depth_compare = CanvasCompareFunctionNotEqual;
2302
+ } else if (depthCompareStr == "greater-equal") {
2303
+ stencil->depth_compare = CanvasCompareFunctionGreaterEqual;
2304
+ } else if (depthCompareStr == "always") {
2305
+ stencil->depth_compare = CanvasCompareFunctionAlways;
2306
+ }
2307
+
2308
+ stencil->depth_write_enabled = stencilObj->Get(context, ConvertToV8String(isolate,
2309
+ "depthWriteEnabled")).ToLocalChecked()->BooleanValue(
2310
+ isolate);
2311
+
2312
+
2313
+ v8::Local<v8::Value> stencilBackVal;
2314
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilBack")).ToLocal(
2315
+ &stencilBackVal);
2316
+
2317
+ if (!stencilBackVal.IsEmpty() && stencilBackVal->IsObject()) {
2318
+ auto stencilBackObj = stencilBackVal.As<v8::Object>();
2319
+
2320
+ v8::Local<v8::Value> compareVal;
2321
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(
2322
+ &compareVal);
2323
+
2324
+ stencil->stencil_back.compare = ParseCompareFunction(isolate, compareVal,
2325
+ stencil->stencil_back.compare);
2326
+
2327
+ v8::Local<v8::Value> depthFailOpVal;
2328
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "depthFailOp")).ToLocal(
2329
+ &depthFailOpVal);
2330
+
2331
+ stencil->stencil_back.depth_fail_op = ParseStencilOperation(isolate, depthFailOpVal,
2332
+ stencil->stencil_back.depth_fail_op);
2333
+
2334
+
2335
+ v8::Local<v8::Value> failOpVal;
2336
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "failOp")).ToLocal(
2337
+ &failOpVal);
2338
+
2339
+ stencil->stencil_back.fail_op = ParseStencilOperation(isolate, failOpVal,
2340
+ stencil->stencil_back.fail_op);
2341
+
2342
+ v8::Local<v8::Value> passOpVal;
2343
+ stencilBackObj->Get(context, ConvertToV8String(isolate, "passOp")).ToLocal(
2344
+ &passOpVal);
2345
+
2346
+ stencil->stencil_back.pass_op = ParseStencilOperation(isolate, passOpVal,
2347
+ stencil->stencil_back.pass_op);
2348
+
2349
+ }
2350
+
2351
+
2352
+ v8::Local<v8::Value> stencilFrontVal;
2353
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilFront")).ToLocal(
2354
+ &stencilFrontVal);
2355
+
2356
+ if (!stencilFrontVal.IsEmpty() && stencilFrontVal->IsObject()) {
2357
+ auto stencilFrontObj = stencilFrontVal.As<v8::Object>();
2358
+
2359
+ v8::Local<v8::Value> compareVal;
2360
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(
2361
+ &compareVal);
2362
+
2363
+ stencil->stencil_front.compare = ParseCompareFunction(isolate, compareVal,
2364
+ stencil->stencil_front.compare);
2365
+
2366
+ v8::Local<v8::Value> depthFailOpVal;
2367
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "depthFailOp")).ToLocal(
2368
+ &depthFailOpVal);
2369
+
2370
+ stencil->stencil_front.depth_fail_op = ParseStencilOperation(isolate, depthFailOpVal,
2371
+ stencil->stencil_front.depth_fail_op);
2372
+
2373
+
2374
+ v8::Local<v8::Value> failOpVal;
2375
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "failOp")).ToLocal(
2376
+ &failOpVal);
2377
+
2378
+ stencil->stencil_front.fail_op = ParseStencilOperation(isolate, failOpVal,
2379
+ stencil->stencil_front.fail_op);
2380
+
2381
+ v8::Local<v8::Value> passOpVal;
2382
+ stencilFrontObj->Get(context, ConvertToV8String(isolate, "passOp")).ToLocal(
2383
+ &passOpVal);
2384
+
2385
+ stencil->stencil_front.pass_op = ParseStencilOperation(isolate, passOpVal,
2386
+ stencil->stencil_front.pass_op);
2387
+
2388
+ }
2389
+
2390
+ v8::Local<v8::Value> stencilReadMaskVal;
2391
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilReadMask")).ToLocal(
2392
+ &stencilReadMaskVal);
2393
+
2394
+ if (!stencilReadMaskVal.IsEmpty() && stencilReadMaskVal->IsUint32()) {
2395
+ stencil->stencil_read_mask = stencilReadMaskVal->Uint32Value(context).FromJust();
2396
+ }
2397
+
2398
+
2399
+ v8::Local<v8::Value> stencilWriteMaskVal;
2400
+ stencilObj->Get(context, ConvertToV8String(isolate, "stencilWriteMask")).ToLocal(
2401
+ &stencilWriteMaskVal);
2402
+
2403
+ if (!stencilWriteMaskVal.IsEmpty() && stencilWriteMaskVal->IsUint32()) {
2404
+ stencil->stencil_write_mask = stencilWriteMaskVal->Uint32Value(context).FromJust();
2405
+ }
2406
+
2407
+ descriptor.depth_stencil = stencil;
2408
+
2409
+ }
2410
+
2411
+
2412
+ v8::Local<v8::Value> fragmentValue;
2413
+ options->Get(context, ConvertToV8String(isolate, "fragment")).ToLocal(
2414
+ &fragmentValue);
2415
+
2416
+ CanvasFragmentState *fragment = nullptr;
2417
+
2418
+ std::vector<CanvasColorTargetState> targets;
2419
+
2420
+ if (!fragmentValue.IsEmpty() && fragmentValue->IsObject()) {
2421
+ auto fragmentValueObj = fragmentValue.As<v8::Object>();
2422
+ fragment = new CanvasFragmentState{};
2423
+ fragment->entry_point = nullptr;
2424
+
2425
+ v8::Local<v8::Value> targetsVal;
2426
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "targets")).ToLocal(&targetsVal);
2427
+
2428
+
2429
+ auto targetsArray = targetsVal.As<v8::Array>();
2430
+ auto len = targetsArray->Length();
2431
+
2432
+ for (int i = 0; i < len; i++) {
2433
+ auto state = targetsArray->Get(context, i).ToLocalChecked().As<v8::Object>();
2434
+
2435
+ auto formatVal = state->Get(context,
2436
+ ConvertToV8String(isolate, "format")).ToLocalChecked();
2437
+ auto formatStr = ConvertFromV8String(isolate, formatVal);
2438
+ auto formatResult = canvas_native_webgpu_enum_string_to_gpu_texture(formatStr.c_str());
2439
+
2440
+
2441
+ if (formatResult.tag == CanvasOptionalGPUTextureFormatNone) {
2442
+ // todo throw
2443
+ args.GetReturnValue().SetUndefined();
2444
+ return;
2445
+ } else {}
2446
+
2447
+ auto format = CanvasGPUTextureFormat{
2448
+ formatResult.some.tag
2449
+ };
2450
+
2451
+ uint32_t writeMask = 0xF;
2452
+
2453
+ v8::Local<v8::Value> writeMaskVal;
2454
+
2455
+ state->Get(context, ConvertToV8String(isolate, "writeMask")).ToLocal(&writeMaskVal);
2456
+
2457
+ if (!writeMaskVal.IsEmpty() && writeMaskVal->IsUint32()) {
2458
+ writeMask = writeMaskVal->Uint32Value(context).FromJust();
2459
+ }
2460
+
2461
+ CanvasOptionalBlendState blend{
2462
+ CanvasOptionalBlendStateNone
2463
+ };
2464
+
2465
+ v8::Local<v8::Value> blendVal;
2466
+
2467
+ state->Get(context, ConvertToV8String(isolate, "blend")).ToLocal(&blendVal);
2468
+
2469
+ if (!blendVal.IsEmpty() && blendVal->IsObject()) {
2470
+ auto blendObj = blendVal.As<v8::Object>();
2471
+ auto alpha = blendObj->Get(context, ConvertToV8String(isolate,
2472
+ "alpha")).ToLocalChecked().As<v8::Object>();
2473
+
2474
+ v8::Local<v8::Value> alphaSrcFactorVal;
2475
+
2476
+ alpha->Get(context,
2477
+ ConvertToV8String(isolate,
2478
+ "srcFactor")).ToLocal(&alphaSrcFactorVal);
2479
+
2480
+ auto alphaSrcFactor = ParseBlendFactor(isolate, alphaSrcFactorVal,
2481
+ CanvasBlendFactorZero);
2482
+
2483
+ v8::Local<v8::Value> alphaDstFactorVal;
2484
+ alpha->Get(context,
2485
+ ConvertToV8String(isolate,
2486
+ "dstFactor")).ToLocal(&alphaDstFactorVal);
2487
+
2488
+ auto alphaDstFactor = ParseBlendFactor(isolate, alphaDstFactorVal,
2489
+ CanvasBlendFactorZero);
2490
+
2491
+ v8::Local<v8::Value> alphaOperationVal;
2492
+
2493
+ alpha->Get(context,
2494
+ ConvertToV8String(isolate,
2495
+ "operation")).ToLocal(&alphaOperationVal);
2496
+
2497
+ auto alphaOperation = ParseBlendOperation(isolate, alphaOperationVal,
2498
+ CanvasBlendOperationAdd);
2499
+
2500
+ auto alpha_val = CanvasBlendComponent{alphaSrcFactor, alphaDstFactor,
2501
+ alphaOperation};
2502
+
2503
+ auto color = blendObj->Get(context, ConvertToV8String(isolate,
2504
+ "color")).ToLocalChecked().As<v8::Object>();
2505
+
2506
+
2507
+ v8::Local<v8::Value> colorSrcFactorVal;
2508
+
2509
+ color->Get(context,
2510
+ ConvertToV8String(isolate,
2511
+ "srcFactor")).ToLocal(&colorSrcFactorVal);
2512
+
2513
+ auto colorSrcFactor = ParseBlendFactor(isolate, colorSrcFactorVal,
2514
+ CanvasBlendFactorZero);
2515
+
2516
+ v8::Local<v8::Value> colorDstFactorVal;
2517
+ color->Get(context,
2518
+ ConvertToV8String(isolate,
2519
+ "dstFactor")).ToLocal(&colorDstFactorVal);
2520
+
2521
+ auto colorDstFactor = ParseBlendFactor(isolate, colorDstFactorVal,
2522
+ CanvasBlendFactorZero);
2523
+
2524
+ v8::Local<v8::Value> colorOperationVal;
2525
+
2526
+ color->Get(context,
2527
+ ConvertToV8String(isolate,
2528
+ "operation")).ToLocal(&colorOperationVal);
2529
+
2530
+ auto colorOperation = ParseBlendOperation(isolate, colorOperationVal,
2531
+ CanvasBlendOperationAdd);
2532
+
2533
+
2534
+ auto color_val = CanvasBlendComponent{colorSrcFactor, colorDstFactor,
2535
+ colorOperation};
2536
+
2537
+
2538
+ blend = CanvasOptionalBlendState{
2539
+ CanvasOptionalBlendStateSome,
2540
+ CanvasBlendState{
2541
+ color_val, alpha_val
2542
+ }
2543
+ };
2544
+ }
2545
+
2546
+ auto targetState = CanvasColorTargetState{
2547
+ format,
2548
+ blend,
2549
+ writeMask
2550
+ };
2551
+
2552
+ targets.push_back(targetState);
2553
+ }
2554
+
2555
+ if (!targets.empty()) {
2556
+ fragment->targets = targets.data();
2557
+ fragment->targets_size = targets.size();
2558
+ }
2559
+
2560
+ v8::Local<v8::Value> constantsVal;
2561
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(
2562
+ &constantsVal);
2563
+
2564
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
2565
+ auto constants = constantsVal.As<v8::Map>();
2566
+ auto keyValues = constants->AsArray();
2567
+ auto length = keyValues->Length();
2568
+ CanvasConstants *store = nullptr;
2569
+
2570
+ if (length > 0) {
2571
+ store = canvas_native_webgpu_constants_create();
2572
+ for (int i = 0; i < length; i += 2) {
2573
+ auto k = i;
2574
+ auto v = k + 1;
2575
+
2576
+ v8::Local<v8::Value> keyVal;
2577
+ keyValues->Get(context, k).ToLocal(&keyVal);
2578
+ v8::Local<v8::Value> valueVal;
2579
+ keyValues->Get(context, v).ToLocal(&valueVal);
2580
+
2581
+
2582
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
2583
+ valueVal->IsNumber()) {
2584
+ canvas_native_webgpu_constants_insert(
2585
+ store,
2586
+ *v8::String::Utf8Value(isolate, keyVal),
2587
+ valueVal.As<v8::Number>()->Value()
2588
+ );
2589
+ }
2590
+
2591
+ }
2592
+ }
2593
+ fragment->constants = store;
2594
+ }
2595
+
2596
+
2597
+ v8::Local<v8::Value> entryPoint;
2598
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(
2599
+ &entryPoint);
2600
+
2601
+
2602
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
2603
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
2604
+ char *entry_point = (char *) malloc(ep.length());
2605
+ std::strcpy(entry_point, *ep);
2606
+
2607
+ fragment->entry_point = entry_point;
2608
+ }
2609
+
2610
+
2611
+ v8::Local<v8::Value> moduleVal;
2612
+ fragmentValueObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
2613
+
2614
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
2615
+
2616
+ fragment->module = module->GetShaderModule();
2617
+
2618
+ descriptor.fragment = fragment;
2619
+
2620
+ }
2621
+
2622
+
2623
+ v8::Local<v8::Value> labelVal;
2624
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(
2625
+ &labelVal);
2626
+
2627
+ label = GPULabel(isolate, labelVal);
2628
+
2629
+ descriptor.label = *label;
2630
+
2631
+
2632
+
2633
+ v8::Local<v8::Value> layoutVal;
2634
+ options->Get(context, ConvertToV8String(isolate, "layout")).ToLocal(
2635
+ &layoutVal);
2636
+
2637
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutMode layout;
2638
+
2639
+ if (layoutVal->IsString()) {
2640
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
2641
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
2642
+ };
2643
+ } else if (!layoutVal->IsNullOrUndefined() && layoutVal->IsObject()) {
2644
+ auto pipeline = GPUPipelineLayoutImpl::GetPointer(layoutVal.As<v8::Object>());
2645
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
2646
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeLayout,
2647
+ layout.layout = pipeline->GetPipeline()
2648
+ };
2649
+ } else {
2650
+ // todo throw ?
2651
+ layout = CanvasGPUPipelineLayoutOrGPUAutoLayoutMode{
2652
+ CanvasGPUPipelineLayoutOrGPUAutoLayoutModeAuto
2653
+ };
2654
+ }
2655
+
2656
+ descriptor.layout = layout;
2657
+
2658
+
2659
+ v8::Local<v8::Value> multisampleValue;
2660
+ options->Get(context, ConvertToV8String(isolate, "multisample")).ToLocal(
2661
+ &multisampleValue);
2662
+
2663
+
2664
+ CanvasMultisampleState *multisample = nullptr;
2665
+
2666
+ if (!multisampleValue.IsEmpty() && multisampleValue->IsObject()) {
2667
+ auto multisampleObj = multisampleValue.As<v8::Object>();
2668
+ multisample = new CanvasMultisampleState{};
2669
+ multisample->alpha_to_coverage_enabled = true;
2670
+ multisample->count = 1;
2671
+ multisample->mask = 0xFFFFFFFF;
2672
+
2673
+ v8::Local<v8::Value> alphaToCoverageEnabled;
2674
+ v8::Local<v8::Value> count;
2675
+ v8::Local<v8::Value> mask;
2676
+
2677
+ multisampleObj->Get(context, ConvertToV8String(isolate, "alphaToCoverageEnabled")).
2678
+ ToLocal(&alphaToCoverageEnabled);
2679
+
2680
+ if (!alphaToCoverageEnabled.IsEmpty() && alphaToCoverageEnabled->IsBoolean()) {
2681
+ multisample->alpha_to_coverage_enabled = alphaToCoverageEnabled->BooleanValue(
2682
+ isolate);
2683
+ }
2684
+
2685
+ multisampleObj->Get(context, ConvertToV8String(isolate, "count")).
2686
+ ToLocal(&count);
2687
+
2688
+ if (!count.IsEmpty() && count->IsUint32()) {
2689
+ multisample->count = count.As<v8::Uint32>()->Value();
2690
+ }
2691
+
2692
+ multisampleObj->Get(context, ConvertToV8String(isolate, "mask")).
2693
+ ToLocal(&mask);
2694
+
2695
+ if (!mask.IsEmpty() && mask->IsNumber()) {
2696
+ // todo verify mask
2697
+ auto maskValue = mask.As<v8::Number>()->Value();
2698
+ multisample->mask = (uint64_t) maskValue;
2699
+ }
2700
+
2701
+
2702
+ descriptor.multisample = multisample;
2703
+
2704
+ }
2705
+
2706
+
2707
+ v8::Local<v8::Value> primitiveValue;
2708
+ options->Get(context, ConvertToV8String(isolate, "primitive")).ToLocal(
2709
+ &primitiveValue);
2710
+
2711
+
2712
+ CanvasPrimitiveState *primitive = nullptr;
2713
+
2714
+ if (!primitiveValue.IsEmpty() && primitiveValue->IsObject()) {
2715
+ auto primitiveObj = primitiveValue.As<v8::Object>();
2716
+ primitive = new CanvasPrimitiveState{};
2717
+
2718
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
2719
+ primitive->front_face = CanvasFrontFaceCcw;
2720
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
2721
+ CanvasOptionalIndexFormatNone
2722
+ };
2723
+
2724
+ primitive->topology = CanvasPrimitiveTopologyTriangleList;
2725
+
2726
+ primitive->unclipped_depth = false;
2727
+
2728
+
2729
+ v8::Local<v8::Value> cullModeValue;
2730
+
2731
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "cullMode")).ToLocal(
2732
+ &cullModeValue)) {
2733
+ if (cullModeValue->IsUint32()) {
2734
+ auto cullMode = cullModeValue.As<v8::Uint32>()->Value();
2735
+
2736
+ switch (cullMode) {
2737
+ case 0:
2738
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
2739
+ break;
2740
+ case 1:
2741
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeFront;
2742
+ break;
2743
+ case 2:
2744
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeBack;
2745
+ break;
2746
+ default:
2747
+ break;
2748
+ }
2749
+ } else if (cullModeValue->IsString()) {
2750
+
2751
+ auto cullMode = ConvertFromV8String(isolate, cullModeValue);
2752
+
2753
+ if (cullMode == "none") {
2754
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeNone;
2755
+ } else if (cullMode == "front") {
2756
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeFront;
2757
+ } else if (cullMode == "back") {
2758
+ primitive->cull_mode = CanvasCullMode::CanvasCullModeBack;
2759
+ }
2760
+ }
2761
+
2762
+ }
2763
+
2764
+ v8::Local<v8::Value> frontFaceValue;
2765
+
2766
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "frontFace")).ToLocal(
2767
+ &frontFaceValue)) {
2768
+ if (frontFaceValue->IsUint32()) {
2769
+ auto frontFace = frontFaceValue.As<v8::Uint32>()->Value();
2770
+ switch (frontFace) {
2771
+ case 0:
2772
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCcw;
2773
+ break;
2774
+ case 1:
2775
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCw;
2776
+ break;
2777
+ default:
2778
+ break;
2779
+ }
2780
+ } else if (frontFaceValue->IsString()) {
2781
+ auto frontFace = ConvertFromV8String(isolate, frontFaceValue);
2782
+ if (frontFace == "ccw") {
2783
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCcw;
2784
+ } else if (frontFace == "cw") {
2785
+ primitive->front_face = CanvasFrontFace::CanvasFrontFaceCw;
2786
+ }
2787
+ }
2788
+ }
2789
+
2790
+
2791
+ v8::Local<v8::Value> stripIndexFormatValue;
2792
+
2793
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "stripIndexFormat")).ToLocal(
2794
+ &stripIndexFormatValue)) {
2795
+ if (stripIndexFormatValue->IsUint32()) {
2796
+ auto stripIndexFormat = stripIndexFormatValue.As<v8::Uint32>()->Value();
2797
+ switch (stripIndexFormat) {
2798
+ case 0:
2799
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
2800
+ CanvasOptionalIndexFormatSome,
2801
+ CanvasIndexFormat::CanvasIndexFormatUint16
2802
+ };
2803
+ break;
2804
+ case 1:
2805
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
2806
+ CanvasOptionalIndexFormatSome,
2807
+ CanvasIndexFormat::CanvasIndexFormatUint32
2808
+ };
2809
+ break;
2810
+ default:
2811
+ break;
2812
+ }
2813
+ } else if (stripIndexFormatValue->IsString()) {
2814
+ auto stripIndexFormat = ConvertFromV8String(isolate, stripIndexFormatValue);
2815
+
2816
+
2817
+ if (stripIndexFormat == "uint16") {
2818
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
2819
+ CanvasOptionalIndexFormatSome,
2820
+ CanvasIndexFormat::CanvasIndexFormatUint16
2821
+ };
2822
+ } else if (stripIndexFormat == "uint32") {
2823
+ primitive->strip_index_format = CanvasOptionalIndexFormat{
2824
+ CanvasOptionalIndexFormatSome,
2825
+ CanvasIndexFormat::CanvasIndexFormatUint32
2826
+ };
2827
+ }
2828
+ }
2829
+ }
2830
+
2831
+
2832
+ v8::Local<v8::Value> topologyValue;
2833
+
2834
+ if (primitiveObj->Get(context, ConvertToV8String(isolate, "topology")).ToLocal(
2835
+ &topologyValue)) {
2836
+
2837
+ if (topologyValue->IsUint32()) {
2838
+ auto topology = topologyValue.As<v8::Uint32>()->Value();
2839
+ switch (topology) {
2840
+ case 0:
2841
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyPointList;
2842
+ break;
2843
+ case 1:
2844
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineList;
2845
+ break;
2846
+ case 2:
2847
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineStrip;
2848
+ break;
2849
+ case 3:
2850
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleList;
2851
+ break;
2852
+ case 4:
2853
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleStrip;
2854
+ break;
2855
+ default:
2856
+ break;
2857
+ }
2858
+ } else if (topologyValue->IsString()) {
2859
+ auto topology = ConvertFromV8String(isolate, topologyValue);
2860
+ if (topology == "line-list") {
2861
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineList;
2862
+ } else if (topology == "line-strip") {
2863
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyLineStrip;
2864
+ } else if (topology == "point-list") {
2865
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyPointList;
2866
+ } else if (topology == "triangle-list") {
2867
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleList;
2868
+ } else if (topology == "triangle-strip") {
2869
+ primitive->topology = CanvasPrimitiveTopology::CanvasPrimitiveTopologyTriangleStrip;
2870
+ }
2871
+ }
2872
+
2873
+ }
2874
+
2875
+
2876
+ v8::Local<v8::Value> unclippedDepthValue;
2877
+ primitiveObj->Get(context, ConvertToV8String(isolate, "unclippedDepth")).ToLocal(
2878
+ &unclippedDepthValue);
2879
+
2880
+ if (!unclippedDepthValue.IsEmpty() && unclippedDepthValue->IsBoolean()) {
2881
+ primitive->unclipped_depth = unclippedDepthValue->BooleanValue(isolate);
2882
+ }
2883
+
2884
+ descriptor.primitive = primitive;
2885
+
2886
+ }
2887
+
2888
+
2889
+ v8::Local<v8::Value> vertexValue;
2890
+ options->Get(context, ConvertToV8String(isolate, "vertex")).ToLocal(
2891
+ &vertexValue);
2892
+
2893
+
2894
+ CanvasVertexState *vertex = nullptr;
2895
+
2896
+ std::vector<CanvasVertexBufferLayout> bufferLayout;
2897
+
2898
+ std::vector<std::vector<CanvasVertexAttribute>> attributes;
2899
+
2900
+ if (!vertexValue.IsEmpty() && vertexValue->IsObject()) {
2901
+ auto vertexObj = vertexValue.As<v8::Object>();
2902
+ vertex = new CanvasVertexState{};
2903
+ vertex->entry_point = nullptr;
2904
+
2905
+ v8::Local<v8::Value> moduleVal;
2906
+ vertexObj->Get(context, ConvertToV8String(isolate, "module")).ToLocal(&moduleVal);
2907
+
2908
+ auto module = GPUShaderModuleImpl::GetPointer(moduleVal.As<v8::Object>());
2909
+
2910
+ vertex->module = module->GetShaderModule();
2911
+
2912
+ v8::Local<v8::Value> constantsVal;
2913
+ vertexObj->Get(context, ConvertToV8String(isolate, "constants")).ToLocal(&constantsVal);
2914
+
2915
+ if (!constantsVal.IsEmpty() && constantsVal->IsMap()) {
2916
+ auto constants = constantsVal.As<v8::Map>();
2917
+ auto keyValues = constants->AsArray();
2918
+ auto len = keyValues->Length();
2919
+ CanvasConstants *store = nullptr;
2920
+
2921
+ if (len > 0) {
2922
+ store = canvas_native_webgpu_constants_create();
2923
+ for (int i = 0; i < len; i += 2) {
2924
+ auto k = i;
2925
+ auto v = k + 1;
2926
+
2927
+ v8::Local<v8::Value> keyVal;
2928
+ keyValues->Get(context, k).ToLocal(&keyVal);
2929
+ v8::Local<v8::Value> valueVal;
2930
+ keyValues->Get(context, v).ToLocal(&valueVal);
2931
+
2932
+
2933
+ if (!keyVal.IsEmpty() && keyVal->IsString() && !valueVal.IsEmpty() &&
2934
+ valueVal->IsNumber()) {
2935
+ canvas_native_webgpu_constants_insert(
2936
+ store,
2937
+ *v8::String::Utf8Value(isolate, keyVal),
2938
+ valueVal.As<v8::Number>()->Value()
2939
+ );
2940
+ }
2941
+
2942
+ }
2943
+ }
2944
+
2945
+ vertex->constants = store;
2946
+
2947
+ }
2948
+
2949
+ v8::Local<v8::Value> buffersVal;
2950
+ vertexObj->Get(context, ConvertToV8String(isolate, "buffers")).ToLocal(&buffersVal);
2951
+
2952
+ uint64_t stride = 0;
2953
+ if (!buffersVal.IsEmpty() && buffersVal->IsArray()) {
2954
+ auto buffers = buffersVal.As<v8::Array>();
2955
+ auto len = buffers->Length();
2956
+
2957
+ for (int i = 0; i < len; i++) {
2958
+ auto buffer = buffers->Get(context, i).ToLocalChecked().As<v8::Object>();
2959
+
2960
+ v8::Local<v8::Value> arrayStride;
2961
+
2962
+ buffer->Get(context, ConvertToV8String(isolate, "arrayStride")).ToLocal(
2963
+ &arrayStride);
2964
+
2965
+ if (!arrayStride.IsEmpty() && arrayStride->IsNumber()) {
2966
+ stride = (uint64_t) arrayStride.As<v8::Number>()->Value();
2967
+ }
2968
+
2969
+ std::vector<CanvasVertexAttribute> attributes_;
2970
+
2971
+ v8::Local<v8::Value> attributesValue;
2972
+
2973
+ buffer->Get(context, ConvertToV8String(isolate, "attributes")).ToLocal(
2974
+ &attributesValue);
2975
+
2976
+ if (!attributesValue.IsEmpty() && attributesValue->IsArray()) {
2977
+ auto attributes_array = attributesValue.As<v8::Array>();
2978
+ auto attributes_len = attributes_array->Length();
2979
+
2980
+ for (int j = 0; j < attributes_len; j++) {
2981
+ auto attr = attributes_array->Get(context,
2982
+ j).ToLocalChecked().As<v8::Object>();
2983
+ auto format = attr->Get(context, ConvertToV8String(isolate,
2984
+ "format")).ToLocalChecked()->Uint32Value(
2985
+ context).ToChecked();
2986
+
2987
+ auto offset = (uint64_t) attr->Get(context, ConvertToV8String(isolate,
2988
+ "offset")).ToLocalChecked()->NumberValue(
2989
+ context).ToChecked();
2990
+ auto shaderLocation = attr->Get(context, ConvertToV8String(isolate,
2991
+ "shaderLocation")).ToLocalChecked()->Uint32Value(
2992
+ context).ToChecked();
2993
+
2994
+ auto attribute = CanvasVertexAttribute{
2995
+ (CanvasVertexFormat) format,
2996
+ offset,
2997
+ shaderLocation
2998
+ };
2999
+
3000
+ attributes_.push_back(attribute);
3001
+ }
3002
+
3003
+ attributes.push_back(attributes_);
3004
+ }
3005
+
3006
+
3007
+ CanvasVertexStepMode stepMode = CanvasVertexStepModeVertex;
3008
+
3009
+ v8::Local<v8::Value> stepModeVal;
3010
+
3011
+ buffer->Get(context, ConvertToV8String(isolate, "stepMode")).ToLocal(
3012
+ &stepModeVal);
3013
+
3014
+
3015
+ if (!stepModeVal.IsEmpty()) {
3016
+ if (stepModeVal->IsUint32()) {
3017
+ switch (stepModeVal.As<v8::Uint32>()->Value()) {
3018
+ case 0:
3019
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeVertex;
3020
+ break;
3021
+ case 1:
3022
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeInstance;
3023
+ break;
3024
+ }
3025
+ } else if (stepModeVal->IsString()) {
3026
+ auto stepModeStr = ConvertFromV8String(isolate, stepModeVal);
3027
+ if (stepModeStr == "vertex") {
3028
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeVertex;
3029
+ } else if (stepModeStr == "instance") {
3030
+ stepMode = CanvasVertexStepMode::CanvasVertexStepModeInstance;
3031
+ }
3032
+ }
3033
+ }
3034
+
3035
+ auto vertexBufferLayout = CanvasVertexBufferLayout{
3036
+ stride,
3037
+ stepMode,
3038
+ attributes[i].data(),
3039
+ attributes[i].size()
3040
+ };
3041
+
3042
+ bufferLayout.push_back(vertexBufferLayout);
3043
+ }
3044
+
3045
+ vertex->buffers = bufferLayout.data();
3046
+ vertex->buffers_size = bufferLayout.size();
3047
+
3048
+ }
3049
+
3050
+
3051
+ v8::Local<v8::Value> entryPoint;
3052
+ vertexObj->Get(context, ConvertToV8String(isolate, "entryPoint")).ToLocal(&entryPoint);
3053
+
3054
+
3055
+ if (!entryPoint.IsEmpty() && entryPoint->IsString()) {
3056
+ auto ep = v8::String::Utf8Value(isolate, entryPoint);
3057
+ char *entry_point = (char *) malloc(ep.length());
3058
+ std::strcpy(entry_point, *ep);
3059
+ vertex->entry_point = entry_point;
3060
+ }
3061
+
3062
+ descriptor.vertex = vertex;
3063
+
3064
+ }
3065
+
3066
+ auto async_callback = new AsyncCallback(isolate, callback.As<v8::Function>(),
3067
+ [](bool success, void *data) {
3068
+ if (data != nullptr) {
3069
+ auto async_data = static_cast<AsyncCallback *>(data);
3070
+ auto func = async_data->inner_.get();
3071
+ if (func != nullptr &&
3072
+ func->isolate_ != nullptr) {
3073
+ v8::Isolate *isolate = func->isolate_;
3074
+ v8::Locker locker(isolate);
3075
+ v8::Isolate::Scope isolate_scope(
3076
+ isolate);
3077
+ v8::HandleScope handle_scope(isolate);
3078
+ v8::Local<v8::Function> callback = func->callback_.Get(
3079
+ isolate);
3080
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
3081
+ v8::Context::Scope context_scope(
3082
+ context);
3083
+
3084
+ RenderPipeLineAsyncData *pipelineData = nullptr;
3085
+ if (func->data != nullptr) {
3086
+ pipelineData = static_cast<RenderPipeLineAsyncData *>(func->data);
3087
+ }
3088
+
3089
+ if (pipelineData == nullptr) {
3090
+ // Should never happen
3091
+ auto error = v8::Object::New(isolate);
3092
+ error->Set(context,
3093
+ ConvertToV8String(isolate,
3094
+ "error"),
3095
+ v8::Exception::Error(
3096
+ ConvertToV8String(
3097
+ isolate,
3098
+ "Internal Error")));
3099
+ error->Set(context, ConvertToV8String(
3100
+ isolate,
3101
+ "type"),
3102
+ v8::Uint32::NewFromUnsigned(
3103
+ isolate,
3104
+ (uint32_t) CanvasGPUErrorType::CanvasGPUErrorTypeInternal));
3105
+
3106
+ v8::Local<v8::Value> args[1] = {error};
3107
+
3108
+ callback->Call(context,
3109
+ context->Global(),
3110
+ 1,
3111
+ args); // ignore JS return value
3112
+ delete static_cast<AsyncCallback *>(data);
3113
+
3114
+ return;
3115
+ }
3116
+
3117
+ if (pipelineData->type !=
3118
+ CanvasGPUErrorType::CanvasGPUErrorTypeNone) {
3119
+
3120
+
3121
+ auto error = v8::Object::New(isolate);
3122
+ error->Set(context,
3123
+ ConvertToV8String(isolate,
3124
+ "error"),
3125
+ v8::Exception::Error(
3126
+ ConvertToV8String(
3127
+ isolate,
3128
+ pipelineData->errorMessage)));
3129
+ error->Set(context, ConvertToV8String(
3130
+ isolate,
3131
+ "type"),
3132
+ v8::Uint32::NewFromUnsigned(
3133
+ isolate,
3134
+ (uint32_t) pipelineData->type));
3135
+
3136
+ v8::Local<v8::Value> args[1] = {error};
3137
+
3138
+ callback->Call(context,
3139
+ context->Global(),
3140
+ 1,
3141
+ args); // ignore JS return value
3142
+ } else {
3143
+
3144
+ auto ret = GPURenderPipelineImpl::NewInstance(
3145
+ isolate,
3146
+ new GPURenderPipelineImpl(
3147
+ pipelineData->pipeline));
3148
+
3149
+ v8::Local<v8::Value> args[2] = {
3150
+ v8::Null(isolate), ret};
3151
+
3152
+
3153
+ callback->Call(context,
3154
+ context->Global(),
3155
+ 2,
3156
+ args); // ignore JS return value
3157
+ }
3158
+
3159
+ if (pipelineData != nullptr) {
3160
+ delete pipelineData;
3161
+ pipelineData = nullptr;
3162
+ }
3163
+
3164
+ delete static_cast<AsyncCallback *>(data);
3165
+ }
3166
+ }
3167
+ });
3168
+
3169
+ auto data = new RenderPipeLineAsyncData{
3170
+ nullptr,
3171
+ nullptr,
3172
+ nullptr,
3173
+ nullptr,
3174
+ CanvasGPUErrorType::CanvasGPUErrorTypeNone,
3175
+ nullptr,
3176
+ nullptr,
3177
+ nullptr,
3178
+ nullptr,
3179
+ nullptr,
3180
+ nullptr
3181
+ };
3182
+
3183
+ if (fragment != nullptr) {
3184
+ if (fragment->entry_point != nullptr) {
3185
+ data->fragment_entry_point = (char *) fragment->entry_point;
3186
+ }
3187
+ }
3188
+
3189
+ if (primitive != nullptr) {
3190
+ data->primitive = primitive;
3191
+ }
3192
+
3193
+ if (multisample != nullptr) {
3194
+ data->multisample = multisample;
3195
+ }
3196
+
3197
+ if (vertex != nullptr) {
3198
+ if (vertex->constants != nullptr) {
3199
+ data->vertex_constants = (CanvasConstants *) vertex->constants;
3200
+ }
3201
+
3202
+ if (vertex->entry_point != nullptr) {
3203
+ data->vertex_entry_point = (char *) descriptor.vertex->entry_point;
3204
+ }
3205
+
3206
+ }
3207
+
3208
+ if (stencil != nullptr) {
3209
+ delete descriptor.depth_stencil;
3210
+ data->depth_stencil = stencil;
3211
+ }
3212
+
3213
+ async_callback->inner_->data = data;
3214
+
3215
+ async_callback->prepare();
3216
+
3217
+ canvas_native_webgpu_device_create_render_pipeline_async(ptr->GetGPUDevice(),
3218
+ &descriptor, [](
3219
+ const struct CanvasGPURenderPipeline *pipeline,
3220
+ enum CanvasGPUErrorType type,
3221
+ char *message,
3222
+ void *data) {
3223
+ if (data != nullptr) {
3224
+ auto async_data = static_cast<AsyncCallback *>(data);
3225
+ auto inner = async_data->inner_.get();
3226
+ if (inner != nullptr) {
3227
+ auto pipeline_data = static_cast<RenderPipeLineAsyncData *>(inner->data);
3228
+ pipeline_data->errorMessage = message;
3229
+ pipeline_data->type = type;
3230
+ pipeline_data->pipeline = pipeline;
3231
+ async_data->execute(
3232
+ true);
3233
+ }
3234
+ }
3235
+ }, async_callback);
3236
+ }
3237
+
3238
+ void GPUDeviceImpl::CreateSampler(const v8::FunctionCallbackInfo<v8::Value> &args) {
3239
+ GPUDeviceImpl *ptr = GetPointer(args.This());
3240
+ if (ptr == nullptr) {
3241
+ return;
3242
+ }
3243
+ auto isolate = args.GetIsolate();
3244
+ auto context = isolate->GetCurrentContext();
3245
+
3246
+
3247
+ auto optionsVal = args[0];
3248
+
3249
+ if (!optionsVal->IsNullOrUndefined() && optionsVal->IsObject()) {
3250
+ auto options = optionsVal.As<v8::Object>();
3251
+
3252
+ v8::Local<v8::Value> labelVal;
3253
+ options->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
3254
+
3255
+ GPULabel label(isolate, labelVal);
3256
+
3257
+ auto addressModeU = CanvasAddressModeClampToEdge;
3258
+
3259
+ v8::Local<v8::Value> addressModeUVal;
3260
+ options->Get(context, ConvertToV8String(isolate, "addressModeU")).ToLocal(&addressModeUVal);
3261
+ auto addressModeUStr = ConvertFromV8String(isolate, addressModeUVal);
3262
+ if (addressModeUStr == "repeat") {
3263
+ addressModeU = CanvasAddressModeRepeat;
3264
+ } else if (addressModeUStr == "mirror-repeat") {
3265
+ addressModeU = CanvasAddressModeMirrorRepeat;
3266
+ }
3267
+
3268
+
3269
+ auto addressModeV = CanvasAddressModeClampToEdge;
3270
+
3271
+ v8::Local<v8::Value> addressModeVVal;
3272
+ options->Get(context, ConvertToV8String(isolate, "addressModeV")).ToLocal(&addressModeVVal);
3273
+ auto addressModeVStr = ConvertFromV8String(isolate, addressModeVVal);
3274
+ if (addressModeVStr == "repeat") {
3275
+ addressModeV = CanvasAddressModeRepeat;
3276
+ } else if (addressModeVStr == "mirror-repeat") {
3277
+ addressModeV = CanvasAddressModeMirrorRepeat;
3278
+ }
3279
+
3280
+
3281
+ auto addressModeW = CanvasAddressModeClampToEdge;
3282
+
3283
+ v8::Local<v8::Value> addressModeWVal;
3284
+ options->Get(context, ConvertToV8String(isolate, "addressModeW")).ToLocal(&addressModeWVal);
3285
+ auto addressModeWStr = ConvertFromV8String(isolate, addressModeWVal);
3286
+ if (addressModeWStr == "repeat") {
3287
+ addressModeW = CanvasAddressModeRepeat;
3288
+ } else if (addressModeWStr == "mirror-repeat") {
3289
+ addressModeW = CanvasAddressModeMirrorRepeat;
3290
+ }
3291
+
3292
+
3293
+ auto magFilter = CanvasFilterModeNearest;
3294
+
3295
+ v8::Local<v8::Value> magFilterVal;
3296
+ options->Get(context, ConvertToV8String(isolate, "magFilter")).ToLocal(&magFilterVal);
3297
+ auto magFilterStr = ConvertFromV8String(isolate, magFilterVal);
3298
+ if (magFilterStr == "linear") {
3299
+ magFilter = CanvasFilterModeLinear;
3300
+ }
3301
+
3302
+ auto minFilter = CanvasFilterModeNearest;
3303
+
3304
+ v8::Local<v8::Value> minFilterVal;
3305
+ options->Get(context, ConvertToV8String(isolate, "minFilter")).ToLocal(&minFilterVal);
3306
+ auto minFilterStr = ConvertFromV8String(isolate, minFilterVal);
3307
+ if (minFilterStr == "linear") {
3308
+ minFilter = CanvasFilterModeLinear;
3309
+ }
3310
+
3311
+
3312
+ auto mipmapFilter = CanvasFilterModeNearest;
3313
+
3314
+ v8::Local<v8::Value> mipmapFilterVal;
3315
+ options->Get(context, ConvertToV8String(isolate, "mipmapFilter")).ToLocal(&mipmapFilterVal);
3316
+ auto mipmapFilterStr = ConvertFromV8String(isolate, mipmapFilterVal);
3317
+ if (mipmapFilterStr == "linear") {
3318
+ mipmapFilter = CanvasFilterModeLinear;
3319
+ }
3320
+
3321
+
3322
+ float lodMinClamp = 0;
3323
+
3324
+ v8::Local<v8::Value> lodMinClampVal;
3325
+ options->Get(context, ConvertToV8String(isolate, "lodMinClamp")).ToLocal(&lodMinClampVal);
3326
+
3327
+ if (!lodMinClampVal.IsEmpty() && lodMinClampVal->IsNumber()) {
3328
+ lodMinClamp = (float) lodMinClampVal->NumberValue(context).FromJust();
3329
+ }
3330
+
3331
+
3332
+ float lodMaxClamp = 32;
3333
+
3334
+ v8::Local<v8::Value> lodMaxClampVal;
3335
+ options->Get(context, ConvertToV8String(isolate, "lodMaxClamp")).ToLocal(&lodMaxClampVal);
3336
+
3337
+ if (!lodMaxClampVal.IsEmpty() && lodMaxClampVal->IsNumber()) {
3338
+ lodMaxClamp = (float) lodMaxClampVal->NumberValue(context).FromJust();
3339
+ }
3340
+
3341
+
3342
+ CanvasOptionalCompareFunction compare{
3343
+ CanvasOptionalCompareFunctionNone
3344
+ };
3345
+
3346
+
3347
+ v8::Local<v8::Value> compareVal;
3348
+ options->Get(context, ConvertToV8String(isolate, "compare")).ToLocal(&compareVal);
3349
+
3350
+ auto compareStr = ConvertFromV8String(isolate, compareVal);
3351
+
3352
+ if (compareStr == "never") {
3353
+ compare.tag = CanvasOptionalCompareFunctionSome;
3354
+ compare.some = CanvasCompareFunctionNever;
3355
+ } else if (compareStr == "less") {
3356
+ compare.tag = CanvasOptionalCompareFunctionSome;
3357
+ compare.some = CanvasCompareFunctionLess;
3358
+ } else if (compareStr == "equal") {
3359
+ compare.tag = CanvasOptionalCompareFunctionSome;
3360
+ compare.some = CanvasCompareFunctionEqual;
3361
+ } else if (compareStr == "less-equal") {
3362
+ compare.tag = CanvasOptionalCompareFunctionSome;
3363
+ compare.some = CanvasCompareFunctionLessEqual;
3364
+ } else if (compareStr == "greater") {
3365
+ compare.tag = CanvasOptionalCompareFunctionSome;
3366
+ compare.some = CanvasCompareFunctionGreater;
3367
+ } else if (compareStr == "not-equal") {
3368
+ compare.tag = CanvasOptionalCompareFunctionSome;
3369
+ compare.some = CanvasCompareFunctionNotEqual;
3370
+ } else if (compareStr == "greater-equal") {
3371
+ compare.tag = CanvasOptionalCompareFunctionSome;
3372
+ compare.some = CanvasCompareFunctionGreaterEqual;
3373
+ } else if (compareStr == "always") {
3374
+ compare.tag = CanvasOptionalCompareFunctionSome;
3375
+ compare.some = CanvasCompareFunctionAlways;
3376
+ }
3377
+
3378
+ uint16_t maxAnisotropy = 1;
3379
+
3380
+ v8::Local<v8::Value> maxAnisotropyVal;
3381
+ options->Get(context, ConvertToV8String(isolate, "maxAnisotropy")).ToLocal(
3382
+ &maxAnisotropyVal);
3383
+
3384
+ if (!maxAnisotropyVal.IsEmpty() && maxAnisotropyVal->IsNumber()) {
3385
+ maxAnisotropy = (uint16_t) maxAnisotropyVal->NumberValue(context).FromJust();
3386
+ }
3387
+
3388
+
3389
+ CanvasCreateSamplerDescriptor descriptor{
3390
+ *label,
3391
+ addressModeU,
3392
+ addressModeV,
3393
+ addressModeW,
3394
+ magFilter,
3395
+ minFilter,
3396
+ mipmapFilter,
3397
+ lodMinClamp,
3398
+ lodMaxClamp,
3399
+ compare,
3400
+ maxAnisotropy
3401
+ };
3402
+
3403
+ auto sampler = canvas_native_webgpu_device_create_sampler(ptr->GetGPUDevice(), &descriptor);
3404
+ if (sampler != nullptr) {
3405
+ auto ret = GPUSamplerImpl::NewInstance(isolate, new GPUSamplerImpl(sampler));
3406
+ args.GetReturnValue().Set(ret);
3407
+ return;
3408
+ }
3409
+
3410
+ } else {
3411
+ auto sampler = canvas_native_webgpu_device_create_sampler(ptr->GetGPUDevice(), nullptr);
3412
+ if (sampler != nullptr) {
3413
+ auto ret = GPUSamplerImpl::NewInstance(isolate, new GPUSamplerImpl(sampler));
3414
+ args.GetReturnValue().Set(ret);
3415
+ return;
3416
+ }
3417
+ }
3418
+
3419
+ args.GetReturnValue().SetUndefined();
3420
+
3421
+ }
3422
+
3423
+ void GPUDeviceImpl::CreateShaderModule(const v8::FunctionCallbackInfo<v8::Value> &args) {
3424
+ GPUDeviceImpl *ptr = GetPointer(args.This());
3425
+ if (ptr == nullptr) {
3426
+ return;
3427
+ }
3428
+ auto isolate = args.GetIsolate();
3429
+ auto context = isolate->GetCurrentContext();
3430
+
3431
+ auto descVal = args[0];
3432
+
3433
+
3434
+ if (!descVal->IsNullOrUndefined() && descVal->IsObject()) {
3435
+ auto desc = descVal.As<v8::Object>();
3436
+
3437
+
3438
+ v8::Local<v8::Value> labelVal;
3439
+ desc->Get(context, ConvertToV8String(isolate, "label")).ToLocal(&labelVal);
3440
+
3441
+ GPULabel label(isolate, labelVal);
3442
+
3443
+ v8::Local<v8::Value> codeVal;
3444
+
3445
+ std::string code;
3446
+ if (desc->Get(context, ConvertToV8String(isolate, "code")).ToLocal(&codeVal) &&
3447
+ codeVal->IsString()) {
3448
+ code = ConvertFromV8String(isolate, codeVal);
3449
+ }
3450
+
3451
+ auto module = canvas_native_webgpu_device_create_shader_module(ptr->GetGPUDevice(),
3452
+ *label,
3453
+ code.c_str());
3454
+
3455
+ if (module != nullptr) {
3456
+ auto instance = new GPUShaderModuleImpl(module);
3457
+ auto ret = GPUShaderModuleImpl::NewInstance(isolate, instance);
3458
+ args.GetReturnValue().Set(ret);
3459
+ return;
3460
+ }
3461
+
3462
+ }
3463
+
3464
+ args.GetReturnValue().SetUndefined();
3465
+
3466
+
3467
+ }
3468
+
3469
+ void GPUDeviceImpl::CreateTexture(const v8::FunctionCallbackInfo<v8::Value> &args) {
3470
+ GPUDeviceImpl *ptr = GetPointer(args.This());
3471
+ if (ptr == nullptr) {
3472
+ return;
3473
+ }
3474
+ auto isolate = args.GetIsolate();
3475
+ auto context = isolate->GetCurrentContext();
3476
+
3477
+ CanvasCreateTextureDescriptor descriptor{};
3478
+ descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD2;
3479
+ descriptor.depthOrArrayLayers = 1;
3480
+ descriptor.sampleCount = 1;
3481
+ descriptor.mipLevelCount = 1;
3482
+ descriptor.view_formats = nullptr;
3483
+ descriptor.view_formats_size = 0;
3484
+
3485
+
3486
+ char *error = nullptr;
3487
+
3488
+
3489
+ auto optionsVal = args[0];
3490
+
3491
+
3492
+ if (optionsVal->IsObject()) {
3493
+ auto options = optionsVal.As<v8::Object>();
3494
+ v8::Local<v8::Value> depthOrArrayLayersVal;
3495
+
3496
+ if (options->Get(context, ConvertToV8String(isolate, "depthOrArrayLayers")).ToLocal(
3497
+ &depthOrArrayLayersVal) && depthOrArrayLayersVal->IsUint32()) {
3498
+ descriptor.depthOrArrayLayers = depthOrArrayLayersVal.As<v8::Uint32>()->Value();
3499
+ }
3500
+
3501
+
3502
+ v8::Local<v8::Value> widthVal;
3503
+
3504
+ if (options->Get(context, ConvertToV8String(isolate, "width")).ToLocal(
3505
+ &widthVal) && widthVal->IsUint32()) {
3506
+ descriptor.width = widthVal.As<v8::Uint32>()->Value();
3507
+ }
3508
+
3509
+
3510
+ v8::Local<v8::Value> heightVal;
3511
+
3512
+ if (options->Get(context, ConvertToV8String(isolate, "height")).ToLocal(
3513
+ &heightVal) && heightVal->IsUint32()) {
3514
+ descriptor.height = heightVal.As<v8::Uint32>()->Value();
3515
+ }
3516
+
3517
+
3518
+ v8::Local<v8::Value> usageVal;
3519
+
3520
+ if (options->Get(context, ConvertToV8String(isolate, "usage")).ToLocal(
3521
+ &usageVal) && usageVal->IsUint32()) {
3522
+ descriptor.usage = usageVal.As<v8::Uint32>()->Value();
3523
+ }
3524
+
3525
+
3526
+ v8::Local<v8::Value> sampleCountVal;
3527
+ options->Get(context, ConvertToV8String(isolate, "sampleCount")).ToLocal(
3528
+ &sampleCountVal);
3529
+
3530
+ if (sampleCountVal->IsUint32()) {
3531
+ descriptor.sampleCount = sampleCountVal.As<v8::Uint32>()->Value();
3532
+ }
3533
+
3534
+
3535
+ v8::Local<v8::Value> mipLevelCountVal;
3536
+ options->Get(context, ConvertToV8String(isolate, "mipLevelCount")).ToLocal(
3537
+ &mipLevelCountVal);
3538
+
3539
+ if (mipLevelCountVal->IsUint32()) {
3540
+ descriptor.mipLevelCount = mipLevelCountVal.As<v8::Uint32>()->Value();
3541
+ }
3542
+
3543
+
3544
+ v8::Local<v8::Value> dimensionVal;
3545
+ options->Get(context, ConvertToV8String(isolate, "dimension")).ToLocal(
3546
+ &dimensionVal);
3547
+
3548
+ if (dimensionVal->IsString()) {
3549
+ auto dimension = ConvertFromV8String(isolate, dimensionVal);
3550
+ // todo use enum
3551
+ if (dimension == "1d") {
3552
+ descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD1;
3553
+ } else if (dimension == "2d") {
3554
+ descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD2;
3555
+ } else if (dimension == "3d") {
3556
+ descriptor.dimension = CanvasTextureDimension::CanvasTextureDimensionD3;
3557
+ }
3558
+
3559
+ }
3560
+
3561
+
3562
+ v8::Local<v8::Value> formatVal;
3563
+
3564
+ if (options->Get(context, ConvertToV8String(isolate, "format")).ToLocal(
3565
+ &formatVal) && formatVal->IsString()) {
3566
+ auto format = ConvertFromV8String(isolate, formatVal);
3567
+
3568
+ // todo use enum
3569
+ //CanvasGPUTextureFormat fmt{};
3570
+
3571
+ auto fmtOpt = canvas_native_webgpu_enum_string_to_gpu_texture(format.c_str());
3572
+ if (fmtOpt.tag == CanvasOptionalGPUTextureFormatSome) {
3573
+ descriptor.format = fmtOpt.some;
3574
+ }
3575
+ // if (strcmp(format.c_str(), "bgra8unorm") == 0) {
3576
+ // fmt.tag = CanvasGPUTextureFormat_Tag::CanvasGPUTextureFormatBgra8Unorm;
3577
+ // descriptor.format = fmt;
3578
+ // } else if (strcmp(format.c_str(), "rgba8unorm") == 0) {
3579
+ // fmt.tag = CanvasGPUTextureFormat_Tag::CanvasGPUTextureFormatRgba8Unorm;
3580
+ // descriptor.format = fmt;
3581
+ // }
3582
+
3583
+ }
3584
+
3585
+ }
3586
+
3587
+ auto texture = canvas_native_webgpu_device_create_texture(ptr->GetGPUDevice(), &descriptor);
3588
+
3589
+ if (texture != nullptr) {
3590
+ auto textureImpl = new GPUTextureImpl(texture);
3591
+ auto ret = GPUTextureImpl::NewInstance(isolate, textureImpl);
3592
+ args.GetReturnValue().Set(ret);
3593
+
3594
+ } else {
3595
+ if (error != nullptr) {
3596
+ isolate->ThrowError(ConvertToV8String(isolate, error));
3597
+ }
3598
+
3599
+ args.GetReturnValue().SetUndefined();
3600
+ }
3601
+ }
3602
+
3603
+ void GPUDeviceImpl::Destroy(const v8::FunctionCallbackInfo<v8::Value> &args) {
3604
+ GPUDeviceImpl *ptr = GetPointer(args.This());
3605
+ if (ptr == nullptr) {
3606
+ return;
3607
+ }
3608
+ canvas_native_webgpu_device_destroy(ptr->GetGPUDevice());
3609
+ }
3610
+
3611
+ void GPUDeviceImpl::PopErrorScope(const v8::FunctionCallbackInfo<v8::Value> &args) {
3612
+ GPUDeviceImpl *ptr = GetPointer(args.This());
3613
+ if (ptr == nullptr) {
3614
+ return;
3615
+ }
3616
+ auto isolate = args.GetIsolate();
3617
+ auto cb = args[0];
3618
+ auto callback = new JSICallback(isolate, cb.As<v8::Function>());
3619
+
3620
+ canvas_native_webgpu_device_pop_error_scope(ptr->GetGPUDevice(), [](CanvasGPUErrorType type,
3621
+ char *msg,
3622
+ void *data) {
3623
+ auto cb = static_cast<JSICallback *>(data);
3624
+
3625
+ v8::Isolate *isolate = cb->isolate_;
3626
+ v8::Locker locker(isolate);
3627
+ v8::Isolate::Scope isolate_scope(
3628
+ isolate);
3629
+ v8::HandleScope handle_scope(
3630
+ isolate);
3631
+ v8::Local<v8::Function> callback = cb->callback_->Get(
3632
+ isolate);
3633
+ v8::Local<v8::Context> context = callback->GetCreationContextChecked();
3634
+ v8::Context::Scope context_scope(
3635
+ context);
3636
+ v8::Local<v8::Value> typ;
3637
+ v8::Local<v8::Value> message;
3638
+ switch (type) {
3639
+ case CanvasGPUErrorType::CanvasGPUErrorTypeNone:
3640
+ typ = v8::Number::New(
3641
+ isolate, 0);
3642
+ message = v8::Null(
3643
+ isolate);
3644
+ break;
3645
+ case CanvasGPUErrorType::CanvasGPUErrorTypeLost:
3646
+ typ = v8::Number::New(
3647
+ isolate, 1);
3648
+ message = v8::Null(
3649
+ isolate);
3650
+ break;
3651
+ case CanvasGPUErrorType::CanvasGPUErrorTypeOutOfMemory:
3652
+ typ = v8::Number::New(
3653
+ isolate, 2);
3654
+ message = v8::Null(
3655
+ isolate);
3656
+ break;
3657
+ case CanvasGPUErrorType::CanvasGPUErrorTypeValidation:
3658
+ typ = v8::Number::New(
3659
+ isolate, 3);
3660
+ message = ConvertToV8String(
3661
+ isolate, msg);
3662
+ break;
3663
+ case CanvasGPUErrorType::CanvasGPUErrorTypeInternal:
3664
+ typ = v8::Number::New(
3665
+ isolate, 4);
3666
+ message = v8::Null(
3667
+ isolate);
3668
+ break;
3669
+ }
3670
+ v8::Local<v8::Value> args[2] = {
3671
+ typ, message
3672
+ };
3673
+
3674
+ callback->Call(context,
3675
+ context->Global(),
3676
+ 2, args);
3677
+
3678
+ delete static_cast<JSICallback *>(data);
3679
+ }, callback);
3680
+ }
3681
+
3682
+ void GPUDeviceImpl::PushErrorScope(const v8::FunctionCallbackInfo<v8::Value> &args) {
3683
+ GPUDeviceImpl *ptr = GetPointer(args.This());
3684
+ if (ptr == nullptr) {
3685
+ return;
3686
+ }
3687
+ auto scope = ConvertFromV8String(args.GetIsolate(), args[0]);
3688
+
3689
+ if (scope == "internal") {
3690
+ canvas_native_webgpu_device_push_error_scope(ptr->GetGPUDevice(),
3691
+ CanvasGPUErrorFilterInternal);
3692
+ } else if (scope == "out-of-memory") {
3693
+ canvas_native_webgpu_device_push_error_scope(ptr->GetGPUDevice(),
3694
+ CanvasGPUErrorFilterOutOfMemory);
3695
+ } else if (scope == "validation") {
3696
+ canvas_native_webgpu_device_push_error_scope(ptr->GetGPUDevice(),
3697
+ CanvasGPUErrorFilterValidation);
3698
+ }
3699
+
3700
+
3701
+ }