react-native-skia-webgpu-video 0.0.0-stage → 0.1.0-beta.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 (236) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +303 -2
  3. package/android/BUILD_VALIDATION.md +62 -0
  4. package/android/CMakeLists.txt +99 -0
  5. package/android/build-validation.json +262 -0
  6. package/android/build.gradle +185 -0
  7. package/android/cpp/EncoderTargets.cpp +226 -0
  8. package/android/cpp/EncoderTargets.h +70 -0
  9. package/android/cpp/JNIHelpers.cpp +15 -0
  10. package/android/cpp/JNIHelpers.h +20 -0
  11. package/android/cpp/NativeEventDispatcher.cpp +59 -0
  12. package/android/cpp/NativeEventDispatcher.h +31 -0
  13. package/android/cpp/NativeHardwareBuffer.cpp +397 -0
  14. package/android/cpp/NativeHardwareBuffer.h +34 -0
  15. package/android/cpp/NativeRgbaBuffer.cpp +45 -0
  16. package/android/cpp/NativeRgbaBuffer.h +9 -0
  17. package/android/cpp/ReturnedVideoFrames.h +37 -0
  18. package/android/cpp/RgbaFrameLease.h +53 -0
  19. package/android/cpp/VideoCapabilities.cpp +87 -0
  20. package/android/cpp/VideoCapabilities.h +44 -0
  21. package/android/cpp/VideoComposition.cpp +170 -0
  22. package/android/cpp/VideoComposition.h +36 -0
  23. package/android/cpp/VideoCompositionFramesExtractor.cpp +82 -0
  24. package/android/cpp/VideoCompositionFramesExtractor.h +48 -0
  25. package/android/cpp/VideoCompositionFramesExtractorHostObject.cpp +230 -0
  26. package/android/cpp/VideoCompositionFramesExtractorHostObject.h +42 -0
  27. package/android/cpp/VideoCompositionFramesExtractorSyncHostObject.cpp +133 -0
  28. package/android/cpp/VideoCompositionFramesExtractorSyncHostObject.h +46 -0
  29. package/android/cpp/VideoEncoderHostObject.cpp +318 -0
  30. package/android/cpp/VideoEncoderHostObject.h +76 -0
  31. package/android/cpp/VideoFrame.cpp +293 -0
  32. package/android/cpp/VideoFrame.h +27 -0
  33. package/android/cpp/VideoPlayer.cpp +96 -0
  34. package/android/cpp/VideoPlayer.h +52 -0
  35. package/android/cpp/VideoPlayerHostObject.cpp +225 -0
  36. package/android/cpp/VideoPlayerHostObject.h +43 -0
  37. package/android/cpp/cpp-adapter.cpp +316 -0
  38. package/android/gradle.properties +5 -0
  39. package/android/instrumentation-inventory.json +178 -0
  40. package/android/proguard-rules.pro +4 -0
  41. package/android/src/main/AndroidManifest.xml +2 -0
  42. package/android/src/main/java/com/azzapp/rnskv/AudioCompositionExporter.java +537 -0
  43. package/android/src/main/java/com/azzapp/rnskv/AudioCompositionPlayer.java +321 -0
  44. package/android/src/main/java/com/azzapp/rnskv/BufferLifetime.java +55 -0
  45. package/android/src/main/java/com/azzapp/rnskv/DecodeRequests.java +100 -0
  46. package/android/src/main/java/com/azzapp/rnskv/DecoderWindow.java +55 -0
  47. package/android/src/main/java/com/azzapp/rnskv/EGLResourcesHolder.java +132 -0
  48. package/android/src/main/java/com/azzapp/rnskv/EGLUtils.java +225 -0
  49. package/android/src/main/java/com/azzapp/rnskv/FrameSize.java +50 -0
  50. package/android/src/main/java/com/azzapp/rnskv/GLFrameExtractor.java +510 -0
  51. package/android/src/main/java/com/azzapp/rnskv/JNIHelpers.java +12 -0
  52. package/android/src/main/java/com/azzapp/rnskv/NativeEventDispatcher.java +25 -0
  53. package/android/src/main/java/com/azzapp/rnskv/NativeHardwareBuffer.java +62 -0
  54. package/android/src/main/java/com/azzapp/rnskv/NativeRgbaBuffer.java +35 -0
  55. package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoModule.java +45 -0
  56. package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoPackage.java +43 -0
  57. package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoSpec.java +9 -0
  58. package/android/src/main/java/com/azzapp/rnskv/RgbaBufferAllocator.java +83 -0
  59. package/android/src/main/java/com/azzapp/rnskv/RgbaLayout.java +33 -0
  60. package/android/src/main/java/com/azzapp/rnskv/SurfaceOutputPolicy.java +13 -0
  61. package/android/src/main/java/com/azzapp/rnskv/TextureRenderer.java +150 -0
  62. package/android/src/main/java/com/azzapp/rnskv/TimeHelpers.java +11 -0
  63. package/android/src/main/java/com/azzapp/rnskv/VideoCapabilities.java +354 -0
  64. package/android/src/main/java/com/azzapp/rnskv/VideoComposition.java +147 -0
  65. package/android/src/main/java/com/azzapp/rnskv/VideoCompositionDecoder.java +772 -0
  66. package/android/src/main/java/com/azzapp/rnskv/VideoCompositionFramesExtractor.java +354 -0
  67. package/android/src/main/java/com/azzapp/rnskv/VideoCompositionFramesExtractorSync.java +241 -0
  68. package/android/src/main/java/com/azzapp/rnskv/VideoCompositionItemDecoder.java +492 -0
  69. package/android/src/main/java/com/azzapp/rnskv/VideoEncoder.java +639 -0
  70. package/android/src/main/java/com/azzapp/rnskv/VideoFrame.java +74 -0
  71. package/android/src/main/java/com/azzapp/rnskv/VideoPlayer.java +361 -0
  72. package/cpp/RNSVCheckedSizes.h +54 -0
  73. package/cpp/RNSVEventEmitter.cpp +199 -0
  74. package/cpp/RNSVEventEmitter.h +31 -0
  75. package/cpp/RNSVHostObject.cpp +79 -0
  76. package/cpp/RNSVHostObject.h +67 -0
  77. package/cpp/RNSVMemoryBudget.cpp +68 -0
  78. package/cpp/RNSVMemoryBudget.h +100 -0
  79. package/cpp/RNSVRuntimeLifecycleMonitor.cpp +88 -0
  80. package/cpp/RNSVRuntimeLifecycleMonitor.h +33 -0
  81. package/docs/ANDROID_DEVICE_306.md +95 -0
  82. package/docs/ANDROID_EXPORT_CACHE_306.md +48 -0
  83. package/docs/ANDROID_MEMORY_RETENTION_306.md +67 -0
  84. package/docs/BENCHMARKS.md +368 -0
  85. package/docs/IOS_DEVICE_TESTS.md +115 -0
  86. package/docs/IOS_SIMULATOR_TESTS.md +74 -0
  87. package/docs/MIGRATION.md +82 -0
  88. package/docs/NATIVE_MEMORY_INVESTIGATION_306.md +88 -0
  89. package/docs/PERFORMANCE_AB_IPHONE_303.md +196 -0
  90. package/docs/PERFORMANCE_AB_SIMULATOR.md +135 -0
  91. package/docs/PERFORMANCE_AB_SOAK_SIMULATOR.md +84 -0
  92. package/docs/PERFORMANCE_IPHONE_306_OPTIMIZATION.md +76 -0
  93. package/docs/PERFORMANCE_SIMULATOR.md +89 -0
  94. package/docs/PERFORMANCE_SIMULATOR_INITIAL.md +96 -0
  95. package/docs/PERFORMANCE_SOAK_IPHONE_303.md +41 -0
  96. package/docs/UPSTREAM_NOTES.md +188 -0
  97. package/docs/assets/banner.svg +26 -0
  98. package/examples/webgpu-overlay.ts +147 -0
  99. package/ios/AVAssetTrackUtils.h +24 -0
  100. package/ios/AudioCompositionUtils.h +27 -0
  101. package/ios/AudioCompositionUtils.mm +113 -0
  102. package/ios/DecoderWindow.h +52 -0
  103. package/ios/NativeResourceStats.h +32 -0
  104. package/ios/RNSVColorSpace.h +50 -0
  105. package/ios/RNSVJSIUtils.h +46 -0
  106. package/ios/RNSVScopedPixelBuffer.h +17 -0
  107. package/ios/RNSVVideoPlayer.h +46 -0
  108. package/ios/RNSVVideoPlayer.mm +410 -0
  109. package/ios/ReactNativeSkiaVideo.h +8 -0
  110. package/ios/ReactNativeSkiaVideo.mm +310 -0
  111. package/ios/SeekPolicy.h +27 -0
  112. package/ios/VideoComposition.h +148 -0
  113. package/ios/VideoCompositionFramesExtractorHostObject.h +105 -0
  114. package/ios/VideoCompositionFramesExtractorHostObject.mm +686 -0
  115. package/ios/VideoCompositionFramesExtractorSyncHostObject.h +37 -0
  116. package/ios/VideoCompositionFramesExtractorSyncHostObject.mm +168 -0
  117. package/ios/VideoCompositionItemDecoder.h +60 -0
  118. package/ios/VideoCompositionItemDecoder.mm +480 -0
  119. package/ios/VideoEncoderHostObject.h +83 -0
  120. package/ios/VideoEncoderHostObject.mm +706 -0
  121. package/ios/VideoFrame.h +66 -0
  122. package/ios/VideoFrame.mm +108 -0
  123. package/ios/VideoPlayerHostObject.h +52 -0
  124. package/ios/VideoPlayerHostObject.mm +332 -0
  125. package/lib/module/NativeReactNativeSkiaVideo.js +5 -0
  126. package/lib/module/NativeReactNativeSkiaVideo.js.map +1 -0
  127. package/lib/module/RNSkiaVideoModule.js +20 -0
  128. package/lib/module/RNSkiaVideoModule.js.map +1 -0
  129. package/lib/module/canvas.js +18 -0
  130. package/lib/module/canvas.js.map +1 -0
  131. package/lib/module/exportCache.js +22 -0
  132. package/lib/module/exportCache.js.map +1 -0
  133. package/lib/module/exportFrames.js +338 -0
  134. package/lib/module/exportFrames.js.map +1 -0
  135. package/lib/module/exportQueue.js +52 -0
  136. package/lib/module/exportQueue.js.map +1 -0
  137. package/lib/module/exportTarget.js +137 -0
  138. package/lib/module/exportTarget.js.map +1 -0
  139. package/lib/module/exportVideoComposition.js +492 -0
  140. package/lib/module/exportVideoComposition.js.map +1 -0
  141. package/lib/module/frameInterop.js +532 -0
  142. package/lib/module/frameInterop.js.map +1 -0
  143. package/lib/module/gpu.js +222 -0
  144. package/lib/module/gpu.js.map +1 -0
  145. package/lib/module/gpuDevice.js +54 -0
  146. package/lib/module/gpuDevice.js.map +1 -0
  147. package/lib/module/index.js +36 -0
  148. package/lib/module/index.js.map +1 -0
  149. package/lib/module/memory.js +38 -0
  150. package/lib/module/memory.js.map +1 -0
  151. package/lib/module/package.json +1 -0
  152. package/lib/module/previewLifecycle.js +52 -0
  153. package/lib/module/previewLifecycle.js.map +1 -0
  154. package/lib/module/runtimeYield.js +10 -0
  155. package/lib/module/runtimeYield.js.map +1 -0
  156. package/lib/module/types.js +4 -0
  157. package/lib/module/types.js.map +1 -0
  158. package/lib/module/utils/useEventListener.js +18 -0
  159. package/lib/module/utils/useEventListener.js.map +1 -0
  160. package/lib/module/videoCompositionPlayer.js +348 -0
  161. package/lib/module/videoCompositionPlayer.js.map +1 -0
  162. package/lib/module/videoFrameImage.js +185 -0
  163. package/lib/module/videoFrameImage.js.map +1 -0
  164. package/lib/module/videoPlayer.js +172 -0
  165. package/lib/module/videoPlayer.js.map +1 -0
  166. package/lib/module/yuvBlit.js +299 -0
  167. package/lib/module/yuvBlit.js.map +1 -0
  168. package/lib/typescript/package.json +1 -0
  169. package/lib/typescript/src/NativeReactNativeSkiaVideo.d.ts +7 -0
  170. package/lib/typescript/src/NativeReactNativeSkiaVideo.d.ts.map +1 -0
  171. package/lib/typescript/src/RNSkiaVideoModule.d.ts +4 -0
  172. package/lib/typescript/src/RNSkiaVideoModule.d.ts.map +1 -0
  173. package/lib/typescript/src/canvas.d.ts +4 -0
  174. package/lib/typescript/src/canvas.d.ts.map +1 -0
  175. package/lib/typescript/src/exportCache.d.ts +6 -0
  176. package/lib/typescript/src/exportCache.d.ts.map +1 -0
  177. package/lib/typescript/src/exportFrames.d.ts +57 -0
  178. package/lib/typescript/src/exportFrames.d.ts.map +1 -0
  179. package/lib/typescript/src/exportQueue.d.ts +5 -0
  180. package/lib/typescript/src/exportQueue.d.ts.map +1 -0
  181. package/lib/typescript/src/exportTarget.d.ts +28 -0
  182. package/lib/typescript/src/exportTarget.d.ts.map +1 -0
  183. package/lib/typescript/src/exportVideoComposition.d.ts +68 -0
  184. package/lib/typescript/src/exportVideoComposition.d.ts.map +1 -0
  185. package/lib/typescript/src/frameInterop.d.ts +17 -0
  186. package/lib/typescript/src/frameInterop.d.ts.map +1 -0
  187. package/lib/typescript/src/gpu.d.ts +39 -0
  188. package/lib/typescript/src/gpu.d.ts.map +1 -0
  189. package/lib/typescript/src/gpuDevice.d.ts +11 -0
  190. package/lib/typescript/src/gpuDevice.d.ts.map +1 -0
  191. package/lib/typescript/src/index.d.ts +21 -0
  192. package/lib/typescript/src/index.d.ts.map +1 -0
  193. package/lib/typescript/src/memory.d.ts +25 -0
  194. package/lib/typescript/src/memory.d.ts.map +1 -0
  195. package/lib/typescript/src/previewLifecycle.d.ts +22 -0
  196. package/lib/typescript/src/previewLifecycle.d.ts.map +1 -0
  197. package/lib/typescript/src/runtimeYield.d.ts +4 -0
  198. package/lib/typescript/src/runtimeYield.d.ts.map +1 -0
  199. package/lib/typescript/src/types.d.ts +631 -0
  200. package/lib/typescript/src/types.d.ts.map +1 -0
  201. package/lib/typescript/src/utils/useEventListener.d.ts +5 -0
  202. package/lib/typescript/src/utils/useEventListener.d.ts.map +1 -0
  203. package/lib/typescript/src/videoCompositionPlayer.d.ts +85 -0
  204. package/lib/typescript/src/videoCompositionPlayer.d.ts.map +1 -0
  205. package/lib/typescript/src/videoFrameImage.d.ts +60 -0
  206. package/lib/typescript/src/videoFrameImage.d.ts.map +1 -0
  207. package/lib/typescript/src/videoPlayer.d.ts +99 -0
  208. package/lib/typescript/src/videoPlayer.d.ts.map +1 -0
  209. package/lib/typescript/src/yuvBlit.d.ts +50 -0
  210. package/lib/typescript/src/yuvBlit.d.ts.map +1 -0
  211. package/package.json +154 -4
  212. package/patches/react-native-skia+3.7.0.patch +502 -0
  213. package/react-native-skia-webgpu-video.podspec +35 -0
  214. package/scripts/apply-skia-canvas-patch.mjs +48 -0
  215. package/scripts/skia-canvas-patch.json +291 -0
  216. package/src/NativeReactNativeSkiaVideo.ts +8 -0
  217. package/src/RNSkiaVideoModule.ts +27 -0
  218. package/src/canvas.ts +22 -0
  219. package/src/exportCache.ts +27 -0
  220. package/src/exportFrames.ts +421 -0
  221. package/src/exportQueue.ts +65 -0
  222. package/src/exportTarget.ts +179 -0
  223. package/src/exportVideoComposition.ts +718 -0
  224. package/src/frameInterop.ts +684 -0
  225. package/src/gpu.ts +290 -0
  226. package/src/gpuDevice.ts +80 -0
  227. package/src/index.tsx +45 -0
  228. package/src/memory.ts +48 -0
  229. package/src/previewLifecycle.ts +60 -0
  230. package/src/runtimeYield.ts +6 -0
  231. package/src/types.ts +661 -0
  232. package/src/utils/useEventListener.ts +22 -0
  233. package/src/videoCompositionPlayer.ts +520 -0
  234. package/src/videoFrameImage.ts +205 -0
  235. package/src/videoPlayer.ts +318 -0
  236. package/src/yuvBlit.ts +331 -0
@@ -0,0 +1,291 @@
1
+ {
2
+ "version": "3.7.0",
3
+ "files": {
4
+ "cpp/api/JsiSkCanvas.h": {
5
+ "before": "91e6f97f34bef620740fabf7a6bb516c462a18daa72afb46ef5a84d1cd4f3158",
6
+ "after": "3198bed18bbdad6e61b0ef0d42fbc01c4f1792955af33eb14080a5329de2ff4d",
7
+ "edits": [
8
+ {
9
+ "before": "#include <memory>\n#include <string>\n",
10
+ "after": "#include <memory>\n#include <stdexcept>\n#include <string>\n"
11
+ },
12
+ {
13
+ "before": " void drawPaint(std::shared_ptr<SkPaint> paint) { _canvas->drawPaint(*paint); }\n",
14
+ "after": " void drawPaint(std::shared_ptr<SkPaint> paint) { getCanvas()->drawPaint(*paint); }\n"
15
+ },
16
+ {
17
+ "before": " _canvas->drawLine(x1, y1, x2, y2, *paint);\n",
18
+ "after": " getCanvas()->drawLine(x1, y1, x2, y2, *paint);\n"
19
+ },
20
+ {
21
+ "before": " _canvas->drawRect(*rect, *paint);\n",
22
+ "after": " getCanvas()->drawRect(*rect, *paint);\n"
23
+ },
24
+ {
25
+ "before": " _canvas->drawImage(image, x, y, SkSamplingOptions(), paint.get());\n",
26
+ "after": " getCanvas()->drawImage(image, x, y, SkSamplingOptions(), paint.get());\n"
27
+ },
28
+ {
29
+ "before": " _canvas->drawImageRect(image, *src, *dest, SkSamplingOptions(), paint.get(),\n",
30
+ "after": " getCanvas()->drawImageRect(image, *src, *dest, SkSamplingOptions(), paint.get(),\n"
31
+ },
32
+ {
33
+ "before": " _canvas->drawImage(image, x, y, SkSamplingOptions({B, C}), paint.get());\n",
34
+ "after": " getCanvas()->drawImage(image, x, y, SkSamplingOptions({B, C}), paint.get());\n"
35
+ },
36
+ {
37
+ "before": " _canvas->drawImage(image, x, y, SkSamplingOptions(fm, mm), paint.get());\n",
38
+ "after": " getCanvas()->drawImage(image, x, y, SkSamplingOptions(fm, mm), paint.get());\n"
39
+ },
40
+ {
41
+ "before": " _canvas->drawImageNine(image.get(), center->round(), *dest, fm,\n",
42
+ "after": " getCanvas()->drawImageNine(image.get(), center->round(), *dest, fm,\n"
43
+ },
44
+ {
45
+ "before": " _canvas->drawImageRect(image.get(), *src, *dest, SkSamplingOptions({B, C}),\n",
46
+ "after": " getCanvas()->drawImageRect(image.get(), *src, *dest, SkSamplingOptions({B, C}),\n"
47
+ },
48
+ {
49
+ "before": " _canvas->drawImageRect(image.get(), *src, *dest, {filter, mipmap},\n",
50
+ "after": " getCanvas()->drawImageRect(image.get(), *src, *dest, {filter, mipmap},\n"
51
+ },
52
+ {
53
+ "before": " _canvas->drawCircle(cx, cy, radius, *paint);\n",
54
+ "after": " getCanvas()->drawCircle(cx, cy, radius, *paint);\n"
55
+ },
56
+ {
57
+ "before": " _canvas->drawArc(*oval, startAngle, sweepAngle, useCenter, *paint);\n",
58
+ "after": " getCanvas()->drawArc(*oval, startAngle, sweepAngle, useCenter, *paint);\n"
59
+ },
60
+ {
61
+ "before": " _canvas->drawRRect(*rect, *paint);\n",
62
+ "after": " getCanvas()->drawRRect(*rect, *paint);\n"
63
+ },
64
+ {
65
+ "before": " _canvas->drawDRRect(*outer, *inner, *paint);\n",
66
+ "after": " getCanvas()->drawDRRect(*outer, *inner, *paint);\n"
67
+ },
68
+ {
69
+ "before": " _canvas->drawOval(*rect, *paint);\n",
70
+ "after": " getCanvas()->drawOval(*rect, *paint);\n"
71
+ },
72
+ {
73
+ "before": " void restoreToCount(double c) { _canvas->restoreToCount(c); }\n",
74
+ "after": " void restoreToCount(double c) { getCanvas()->restoreToCount(c); }\n"
75
+ },
76
+ {
77
+ "before": " int getSaveCount() { return static_cast<int>(_canvas->getSaveCount()); }\n",
78
+ "after": " int getSaveCount() { return static_cast<int>(getCanvas()->getSaveCount()); }\n"
79
+ },
80
+ {
81
+ "before": " _canvas->getTotalMatrix());\n",
82
+ "after": " getCanvas()->getTotalMatrix());\n"
83
+ },
84
+ {
85
+ "before": " _canvas->drawPoints(static_cast<SkCanvas::PointMode>(pointMode), p, *paint);\n",
86
+ "after": " getCanvas()->drawPoints(static_cast<SkCanvas::PointMode>(pointMode), p, *paint);\n"
87
+ },
88
+ {
89
+ "before": " _canvas->drawVertices(vertices, toBlendMode(blendMode), *paint);\n",
90
+ "after": " getCanvas()->drawVertices(vertices, toBlendMode(blendMode), *paint);\n"
91
+ },
92
+ {
93
+ "before": " _canvas->drawPatch(cubics.data(), colors.empty() ? nullptr : colors.data(),\n",
94
+ "after": " getCanvas()->drawPatch(cubics.data(), colors.empty() ? nullptr : colors.data(),\n"
95
+ },
96
+ {
97
+ "before": " _canvas->drawPath(path->snapshot(), *paint);\n",
98
+ "after": " getCanvas()->drawPath(path->snapshot(), *paint);\n"
99
+ },
100
+ {
101
+ "before": " _canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, x, y,\n",
102
+ "after": " getCanvas()->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, x, y,\n"
103
+ },
104
+ {
105
+ "before": " _canvas->drawTextBlob(blob, x, y, *paint);\n",
106
+ "after": " getCanvas()->drawTextBlob(blob, x, y, *paint);\n"
107
+ },
108
+ {
109
+ "before": " _canvas->drawGlyphs(g, p, origin, *font, *paint);\n",
110
+ "after": " getCanvas()->drawGlyphs(g, p, origin, *font, *paint);\n"
111
+ },
112
+ {
113
+ "before": " auto canvasSize = _canvas->getBaseLayerSize();\n",
114
+ "after": " auto canvasSize = getCanvas()->getBaseLayerSize();\n"
115
+ },
116
+ {
117
+ "before": " svgdom->render(_canvas);\n",
118
+ "after": " svgdom->render(getCanvas());\n"
119
+ },
120
+ {
121
+ "before": " _canvas->clipPath(path->snapshot(), static_cast<SkClipOp>(op), doAntiAlias);\n",
122
+ "after": " getCanvas()->clipPath(path->snapshot(), static_cast<SkClipOp>(op), doAntiAlias);\n"
123
+ },
124
+ {
125
+ "before": " _canvas->clipRect(*rect, static_cast<SkClipOp>(op), doAntiAlias);\n",
126
+ "after": " getCanvas()->clipRect(*rect, static_cast<SkClipOp>(op), doAntiAlias);\n"
127
+ },
128
+ {
129
+ "before": " _canvas->clipRRect(*rrect, static_cast<SkClipOp>(op), doAntiAlias);\n",
130
+ "after": " getCanvas()->clipRRect(*rrect, static_cast<SkClipOp>(op), doAntiAlias);\n"
131
+ },
132
+ {
133
+ "before": " int save() { return _canvas->save(); }\n",
134
+ "after": " int save() { return getCanvas()->save(); }\n"
135
+ },
136
+ {
137
+ "before": " return jsi::Value(_canvas->saveLayer(SkCanvas::SaveLayerRec(\n",
138
+ "after": " return jsi::Value(getCanvas()->saveLayer(SkCanvas::SaveLayerRec(\n"
139
+ },
140
+ {
141
+ "before": " void restore() { _canvas->restore(); }\n",
142
+ "after": " void restore() { getCanvas()->restore(); }\n"
143
+ },
144
+ {
145
+ "before": " _canvas->rotate(degrees, rx, ry);\n",
146
+ "after": " getCanvas()->rotate(degrees, rx, ry);\n"
147
+ },
148
+ {
149
+ "before": " void translate(double dx, double dy) { _canvas->translate(dx, dy); }\n",
150
+ "after": " void translate(double dx, double dy) { getCanvas()->translate(dx, dy); }\n"
151
+ },
152
+ {
153
+ "before": " void scale(double sx, double sy) { _canvas->scale(sx, sy); }\n",
154
+ "after": " void scale(double sx, double sy) { getCanvas()->scale(sx, sy); }\n"
155
+ },
156
+ {
157
+ "before": " void skew(double sx, double sy) { _canvas->skew(sx, sy); }\n",
158
+ "after": " void skew(double sx, double sy) { getCanvas()->skew(sx, sy); }\n"
159
+ },
160
+ {
161
+ "before": " _canvas->drawColor(cl, toBlendMode(*mode));\n",
162
+ "after": " getCanvas()->drawColor(cl, toBlendMode(*mode));\n"
163
+ },
164
+ {
165
+ "before": " _canvas->drawColor(cl);\n",
166
+ "after": " getCanvas()->drawColor(cl);\n"
167
+ },
168
+ {
169
+ "before": " void clear(JsiColor cl) { _canvas->clear(cl); }\n",
170
+ "after": " void clear(JsiColor cl) { getCanvas()->clear(cl); }\n"
171
+ },
172
+ {
173
+ "before": " void concat(std::shared_ptr<SkMatrix> matrix) { _canvas->concat(*matrix); }\n",
174
+ "after": " void concat(std::shared_ptr<SkMatrix> matrix) { getCanvas()->concat(*matrix); }\n"
175
+ },
176
+ {
177
+ "before": " void drawPicture(sk_sp<SkPicture> picture) { _canvas->drawPicture(picture); }\n",
178
+ "after": " void drawPicture(sk_sp<SkPicture> picture) { getCanvas()->drawPicture(picture); }\n"
179
+ },
180
+ {
181
+ "before": " _canvas->drawAtlas(atlas.get(), x, t, c, blendMode, sampling, nullptr,\n",
182
+ "after": " getCanvas()->drawAtlas(atlas.get(), x, t, c, blendMode, sampling, nullptr,\n"
183
+ },
184
+ {
185
+ "before": " JSI_HOST_FUNCTION(readPixels) {\n auto srcX = static_cast<int>(arguments[0].asNumber());\n",
186
+ "after": " JSI_HOST_FUNCTION(readPixels) {\n getCanvas(); // Validate before allocating a readback buffer.\n auto srcX = static_cast<int>(arguments[0].asNumber());\n"
187
+ },
188
+ {
189
+ "before": " if (!_canvas->readPixels(*info, bfrPtr, bytesPerRow, srcX, srcY)) {\n",
190
+ "after": " if (!getCanvas()->readPixels(*info, bfrPtr, bytesPerRow, srcX, srcY)) {\n"
191
+ },
192
+ {
193
+ "before": " static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {\n installMethod(runtime, prototype, \"drawPaint\", &JsiSkCanvas::drawPaint);\n",
194
+ "after": " static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {\n installMethod(runtime, prototype, \"dispose\", &JsiSkCanvas::dispose);\n installMethod(runtime, prototype, \"drawPaint\", &JsiSkCanvas::drawPaint);\n"
195
+ },
196
+ {
197
+ "before": " SkCanvas *getCanvas() { return _canvas; }\n",
198
+ "after": " SkCanvas *getCanvas() {\n if (!_canvas) throw std::runtime_error(\"Canvas has been disposed\");\n return _canvas;\n }\n // Release the owning surface deterministically. The caller must\n // submit/wait for its recording before disposal. Off the creating\n // thread, the surface is handed to that thread's dispatcher.\n void dispose() {\n _canvas = nullptr;\n if (_dispatcher) {\n _dispatcher->release(std::move(_surface));\n } else {\n _surface.reset();\n }\n }\n"
199
+ },
200
+ {
201
+ "before": " SkCanvas *_canvas;\n",
202
+ "after": " SkCanvas *_canvas = nullptr;\n"
203
+ }
204
+ ]
205
+ },
206
+ "src/skia/types/Canvas.ts": {
207
+ "before": "224e207ad4e9e5bee1efd2e1fb07b61a2261b14f498314cb5657f3201bd99791",
208
+ "after": "e0ca74f4c4ab9d3647a48751f3243d38f64d55fcb95af725be1b88eace052027",
209
+ "edits": [
210
+ {
211
+ "before": "export interface SkCanvas {\n /**\n",
212
+ "after": "export interface SkCanvas {\n /** Release the owning surface after flushing; idempotent. */\n dispose(): void;\n /**\n"
213
+ }
214
+ ]
215
+ },
216
+ "lib/typescript/src/skia/types/Canvas.d.ts": {
217
+ "before": "7cc41d6183212cfd4f3d7d0065a7b360aabf98fae20565428e876f5da8c1bb15",
218
+ "after": "972901e64599c40d54db73a49881323bca457e5b87c07c30a0016a5a89339d99",
219
+ "edits": [
220
+ {
221
+ "before": "export interface SkCanvas {\n /**\n",
222
+ "after": "export interface SkCanvas {\n /** Release the owning surface after flushing; idempotent. */\n dispose(): void;\n /**\n"
223
+ }
224
+ ]
225
+ },
226
+ "cpp/api/JsiSkSurface.h": {
227
+ "before": "de3226499673a8d731167a0feb299257628999ce5d4810217e962062f625302a",
228
+ "after": "d78ce02da437cd1b8df03ecf8ac659b9d25c30018ff74733fb2e5185fc078bf2",
229
+ "edits": [
230
+ {
231
+ "before": "\n ~JsiSkSurface() override {\n",
232
+ "after": "\n // Opt-in for consumers that release native buffers after GPU completion.\n // Other Skia surfaces preserve their existing flush/snapshot behavior.\n void enableCheckedSubmissions() {\n if (!getObject()->recorder()) {\n throw std::runtime_error(\"Checked GPU submissions require a Graphite surface\");\n }\n _checkedSubmissions = true;\n }\n\n void submitRecording(skgpu::graphite::Recording *recording,\n skgpu::graphite::SyncToCpu syncToCpu =\n skgpu::graphite::SyncToCpu::kNo) {\n if (_checkedSubmissions) {\n DawnContext::getInstance().submitRecordingChecked(recording, syncToCpu);\n } else {\n DawnContext::getInstance().submitRecording(recording, syncToCpu);\n }\n }\n\n ~JsiSkSurface() override {\n"
233
+ },
234
+ {
235
+ "before": " DawnContext::getInstance().submitRecording(\n",
236
+ "after": " submitRecording(\n"
237
+ },
238
+ {
239
+ "before": " }\n // A raster surface (e.g. Skia.Surface.Make) has no Graphite recorder; its\n",
240
+ "after": " }\n // Preserve the previously published image if snapshot allocation failed.\n if (!image) {\n throw jsi::JSError(runtime, \"Cannot allocate Skia surface snapshot\");\n }\n // A raster surface (e.g. Skia.Surface.Make) has no Graphite recorder; its\n"
241
+ },
242
+ {
243
+ "before": " DawnContext::getInstance().submitRecording(recording.get());\n",
244
+ "after": " submitRecording(recording.get());\n"
245
+ },
246
+ {
247
+ "before": " installMethod(runtime, prototype, \"flush\", &JsiSkSurface::flush);\n }\n",
248
+ "after": " installMethod(runtime, prototype, \"flush\", &JsiSkSurface::flush);\n installMethod(runtime, prototype, \"enableCheckedSubmissions\",\n &JsiSkSurface::enableCheckedSubmissions);\n }\n"
249
+ },
250
+ {
251
+ "before": " std::shared_ptr<Dispatcher> _dispatcher;\n};\n",
252
+ "after": " std::shared_ptr<Dispatcher> _dispatcher;\n bool _checkedSubmissions = false;\n};\n"
253
+ }
254
+ ]
255
+ },
256
+ "cpp/rnskia/RNDawnContext.h": {
257
+ "before": "f1be623839d9716d1ae7ce9bc66a02055989c9b69acbfec49d607338f711d0e7",
258
+ "after": "c0de4e4b37271a77a429c78e646c2e8a7172b6a46e713ff01f31e0782d05738a",
259
+ "edits": [
260
+ {
261
+ "before": " fGraphiteContext->submit(syncToCpu);\n }\n",
262
+ "after": " fGraphiteContext->submit(syncToCpu);\n }\n\n // Checked only for surfaces that explicitly opt into this contract. A valid\n // empty Recording is accepted; Recorder::snap() returns nullptr on failure.\n void submitRecordingChecked(\n skgpu::graphite::Recording *recording,\n skgpu::graphite::SyncToCpu syncToCpu = skgpu::graphite::SyncToCpu::kNo) {\n std::lock_guard<std::mutex> lock(_mutex);\n if (!recording) {\n throw std::runtime_error(\"Cannot create checked Graphite recording\");\n }\n skgpu::graphite::InsertRecordingInfo info;\n info.fRecording = recording;\n auto status = fGraphiteContext->insertRecording(info);\n if (!static_cast<bool>(status)) {\n throw std::runtime_error(\"Graphite rejected a checked recording: \" +\n status.message());\n }\n if (!fGraphiteContext->submit(syncToCpu)) {\n throw std::runtime_error(\"Graphite checked submission failed\");\n }\n }\n"
263
+ }
264
+ ]
265
+ },
266
+ "cpp/rnskia/RNImageProvider.h": {
267
+ "before": "8b9a552bfcf088058eb06366ba78984b7e54d6ae0442633ecbc0cdd726205fc2",
268
+ "after": "f6c329e5d43fcecfcecc95c8516df159e1bfb68582d27ce92b67facfcd84b4eb",
269
+ "edits": [
270
+ {
271
+ "before": " static sk_sp<ImageProvider> Make() { return sk_ref_sp(new ImageProvider); }",
272
+ "after": " static sk_sp<ImageProvider> Make() { return sk_make_sp<ImageProvider>(); }"
273
+ }
274
+ ]
275
+ },
276
+ "cpp/api/JsiSkApi.h": {
277
+ "before": "9abd4dbaa14c13f3ce80a5c475b8ad51f08400fe6b2c119781032486ae72f7eb",
278
+ "after": "e3e8358e0ecf91b4a0547cdd4467400b14d5d0963402692648d6d0635864a769",
279
+ "edits": [
280
+ {
281
+ "before": " JSI_HOST_FUNCTION(getNativeDevice) {",
282
+ "after": " // Private video-export cleanup. Only the calling thread's Recorder cache\n // is trimmed; the shared Context cache and other Recorders are untouched.\n JSI_HOST_FUNCTION(__rnskvTrimRecorderCache) {\n auto &context = DawnContext::getInstance();\n auto *recorder = context.getRecorder();\n {\n auto recording = recorder->snap();\n context.submitRecordingChecked(recording.get(),\n skgpu::graphite::SyncToCpu::kYes);\n }\n recorder->freeGpuResources();\n return jsi::Value::undefined();\n }\n JSI_HOST_FUNCTION(getNativeDevice) {"
283
+ },
284
+ {
285
+ "before": " static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {",
286
+ "after": " static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {\n installHostMethod(runtime, prototype, \"__rnskvTrimRecorderCache\",\n &JsiSkApi::__rnskvTrimRecorderCache);"
287
+ }
288
+ ]
289
+ }
290
+ }
291
+ }
@@ -0,0 +1,8 @@
1
+ import type { TurboModule } from 'react-native';
2
+ import { TurboModuleRegistry } from 'react-native';
3
+
4
+ export interface Spec extends TurboModule {
5
+ install(): boolean;
6
+ }
7
+
8
+ export default TurboModuleRegistry.get<Spec>('ReactNativeSkiaVideo');
@@ -0,0 +1,27 @@
1
+ import { Platform } from "react-native";
2
+ import type { RNSkiaVideoModule } from "./types";
3
+ import NativeReactNativeSkiaVideo from "./NativeReactNativeSkiaVideo";
4
+
5
+ if (!NativeReactNativeSkiaVideo) {
6
+ throw new Error(
7
+ `The package 'react-native-skia-webgpu-video' doesn't seem to be linked. Make sure: \n\n` +
8
+ Platform.select({ ios: "- You have run 'pod install'\n", default: "" }) +
9
+ "- You rebuilt the app after installing the package\n" +
10
+ "- You are not using Expo Go\n",
11
+ );
12
+ }
13
+
14
+ const installed = NativeReactNativeSkiaVideo.install();
15
+ if (!installed || (global as any).RNSkiaVideo == null) {
16
+ throw new Error(
17
+ "The package 'react-native-skia-webgpu-video' failed to install its JSI bindings.",
18
+ );
19
+ }
20
+
21
+ const module = (global as any).RNSkiaVideo as RNSkiaVideoModule;
22
+ if (module.frameProtocolVersion !== 1) {
23
+ throw new Error(
24
+ "Skia 3 video native bindings are outdated. Rebuild the native app and remove the legacy Skia Video package.",
25
+ );
26
+ }
27
+ export default module;
package/src/canvas.ts ADDED
@@ -0,0 +1,22 @@
1
+ import type { SkCanvas, SkSurface } from "react-native-skia";
2
+
3
+ /** Fail early when JS was patched but the installed native binary was not rebuilt. */
4
+ export const getVideoCanvas = (surface: SkSurface): SkCanvas => {
5
+ "worklet";
6
+ const checked = surface as SkSurface & {
7
+ enableCheckedSubmissions?: () => void;
8
+ };
9
+ if (typeof checked.enableCheckedSubmissions !== "function") {
10
+ throw new Error(
11
+ "Skia checked submission patch is missing from the native binary. Apply the patch and rebuild the native app.",
12
+ );
13
+ }
14
+ checked.enableCheckedSubmissions();
15
+ const canvas = surface.getCanvas();
16
+ if (typeof canvas.dispose !== "function") {
17
+ throw new Error(
18
+ "Skia canvas lifecycle patch is missing from the native binary. Apply the patch and rebuild the native app.",
19
+ );
20
+ }
21
+ return canvas;
22
+ };
@@ -0,0 +1,27 @@
1
+ import { Skia } from "react-native-skia";
2
+
3
+ /** Private contract, used only on this library's dedicated export runtime. */
4
+ export const assertExportRecorderCacheSupport = () => {
5
+ "worklet";
6
+ if (
7
+ typeof (
8
+ Skia as typeof Skia & {
9
+ __rnskvTrimRecorderCache?: () => void;
10
+ }
11
+ ).__rnskvTrimRecorderCache !== "function"
12
+ ) {
13
+ throw new Error(
14
+ "Skia export cache patch is missing from the native binary. Apply the patch and rebuild the native app.",
15
+ );
16
+ }
17
+ };
18
+
19
+ /** Close all export consumers first. Never call this from preview/UI cleanup:
20
+ * that recorder can also cache resources for unrelated application views. */
21
+ export const trimExportRecorderCache = () => {
22
+ "worklet";
23
+ assertExportRecorderCacheSupport();
24
+ (
25
+ Skia as typeof Skia & { __rnskvTrimRecorderCache: () => void }
26
+ ).__rnskvTrimRecorderCache();
27
+ };