react-native-skia 3.0.1 → 3.0.3

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 (269) hide show
  1. package/Package.swift +14 -13
  2. package/README.md +19 -2
  3. package/android/CMakeLists.txt +13 -42
  4. package/android/build.gradle +54 -63
  5. package/android/cpp/jni/JniLoad.cpp +2 -4
  6. package/android/cpp/jni/include/JniSkiaView.h +123 -0
  7. package/android/cpp/rnskia-android/{RNSkOpenGLCanvasProvider.cpp → RNSkAndroidCanvasProvider.cpp} +45 -100
  8. package/android/cpp/rnskia-android/{RNSkOpenGLCanvasProvider.h → RNSkAndroidCanvasProvider.h} +24 -22
  9. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +0 -83
  10. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +0 -8
  11. package/android/src/main/java/com/reactnative/skia/RNSkiaPackage.java +1 -2
  12. package/android/src/main/java/com/reactnative/skia/SkiaSurfaceView.java +1 -3
  13. package/android/src/main/java/com/reactnative/skia/SkiaTextureView.java +1 -17
  14. package/android/src/main/java/com/reactnative/skia/{SkiaBaseView.java → SkiaView.java} +78 -16
  15. package/android/src/main/java/com/reactnative/skia/SkiaViewManager.java +85 -0
  16. package/apple/MetalLayerColorSpace.mm +10 -12
  17. package/apple/RNSkApplePlatformContext.h +12 -14
  18. package/apple/RNSkApplePlatformContext.mm +19 -112
  19. package/apple/RNSkMetalCanvasProvider.h +14 -19
  20. package/apple/RNSkMetalCanvasProvider.mm +39 -70
  21. package/apple/RNSkiaModule.mm +10 -0
  22. package/apple/SkiaView.h +20 -0
  23. package/apple/SkiaView.mm +210 -0
  24. package/cpp/api/JsiSkApi.h +2 -13
  25. package/cpp/api/JsiSkCanvas.h +4 -18
  26. package/cpp/api/JsiSkGraphiteContext.h +1 -5
  27. package/cpp/api/JsiSkGraphiteRecording.h +1 -5
  28. package/cpp/api/JsiSkImage.h +7 -41
  29. package/cpp/api/JsiSkImageFactory.h +0 -14
  30. package/cpp/api/JsiSkSurface.h +2 -16
  31. package/cpp/api/JsiSkSurfaceFactory.h +0 -8
  32. package/cpp/rnskia/RNDawnContext.h +3 -2
  33. package/cpp/rnskia/RNDawnInterop.cpp +0 -4
  34. package/cpp/rnskia/RNDawnUtils.h +12 -1
  35. package/cpp/rnskia/RNDawnWindowContext.cpp +12 -1
  36. package/cpp/rnskia/RNDawnWindowContext.h +19 -7
  37. package/cpp/rnskia/RNMetalLayerColorSpace.h +4 -2
  38. package/cpp/rnskia/RNSkCanvasProvider.h +231 -0
  39. package/cpp/rnskia/RNSkGraphiteProducer.cpp +36 -14
  40. package/cpp/rnskia/RNSkGraphiteProducer.h +23 -8
  41. package/cpp/rnskia/RNSkGraphiteTarget.h +396 -0
  42. package/cpp/rnskia/RNSkJsiViewApi.h +9 -18
  43. package/cpp/rnskia/RNSkPlatformContext.h +17 -15
  44. package/cpp/rnskia/RNSkView.h +362 -246
  45. package/jestSetup.js +1 -3
  46. package/lib/commonjs/Platform/Platform.web.js +1 -1
  47. package/lib/commonjs/Platform/Platform.web.js.map +1 -1
  48. package/lib/commonjs/external/reanimated/interpolators.js +1 -1
  49. package/lib/commonjs/external/reanimated/interpolators.js.map +1 -1
  50. package/lib/commonjs/index.d.ts +1 -3
  51. package/lib/commonjs/index.js +3 -12
  52. package/lib/commonjs/index.js.map +1 -1
  53. package/lib/commonjs/mock/index.js +0 -1
  54. package/lib/commonjs/mock/index.js.map +1 -1
  55. package/lib/commonjs/renderer/Canvas.d.ts +15 -12
  56. package/lib/commonjs/renderer/Canvas.js +25 -21
  57. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  58. package/lib/commonjs/skia/types/Graphite.d.ts +3 -3
  59. package/lib/commonjs/skia/types/Graphite.js.map +1 -1
  60. package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +2 -2
  61. package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
  62. package/lib/commonjs/skia/types/Skia.d.ts +1 -2
  63. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  64. package/lib/commonjs/skia/types/Surface/SurfaceFactory.d.ts +1 -1
  65. package/lib/commonjs/skia/types/Surface/SurfaceFactory.js.map +1 -1
  66. package/lib/commonjs/specs/NativeSkiaModule.web.d.ts +5 -4
  67. package/lib/commonjs/specs/NativeSkiaModule.web.js +5 -9
  68. package/lib/commonjs/specs/NativeSkiaModule.web.js.map +1 -1
  69. package/lib/{typescript/src/specs/SkiaPictureViewNativeComponent.d.ts → commonjs/specs/SkiaViewNativeComponent.d.ts} +0 -3
  70. package/lib/commonjs/specs/{SkiaPictureViewNativeComponent.js → SkiaViewNativeComponent.js} +2 -2
  71. package/lib/commonjs/specs/SkiaViewNativeComponent.js.map +1 -0
  72. package/lib/commonjs/specs/SkiaViewNativeComponent.web.d.ts +10 -0
  73. package/lib/commonjs/specs/SkiaViewNativeComponent.web.js +27 -0
  74. package/lib/commonjs/specs/SkiaViewNativeComponent.web.js.map +1 -0
  75. package/lib/commonjs/views/SkiaGraphiteView.d.ts +3 -4
  76. package/lib/commonjs/views/SkiaGraphiteView.js +23 -12
  77. package/lib/commonjs/views/SkiaGraphiteView.js.map +1 -1
  78. package/lib/commonjs/views/SkiaPictureView.d.ts +4 -1
  79. package/lib/commonjs/views/SkiaPictureView.js +12 -10
  80. package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
  81. package/lib/commonjs/views/SkiaView.web.d.ts +12 -0
  82. package/lib/commonjs/views/{SkiaGraphiteView.web.js → SkiaView.web.js} +82 -38
  83. package/lib/commonjs/views/SkiaView.web.js.map +1 -0
  84. package/lib/commonjs/views/SkiaWebRenderer.js +1 -1
  85. package/lib/commonjs/views/SkiaWebRenderer.js.map +1 -1
  86. package/lib/commonjs/views/android.d.ts +6 -0
  87. package/lib/commonjs/views/android.js +17 -0
  88. package/lib/commonjs/views/android.js.map +1 -0
  89. package/lib/commonjs/views/types.d.ts +3 -12
  90. package/lib/commonjs/views/types.js.map +1 -1
  91. package/lib/module/Platform/Platform.web.js +1 -1
  92. package/lib/module/Platform/Platform.web.js.map +1 -1
  93. package/lib/module/external/reanimated/interpolators.js +1 -1
  94. package/lib/module/external/reanimated/interpolators.js.map +1 -1
  95. package/lib/module/index.d.ts +1 -3
  96. package/lib/module/index.js +1 -3
  97. package/lib/module/index.js.map +1 -1
  98. package/lib/module/mock/index.js +0 -1
  99. package/lib/module/mock/index.js.map +1 -1
  100. package/lib/module/renderer/Canvas.d.ts +15 -12
  101. package/lib/module/renderer/Canvas.js +25 -20
  102. package/lib/module/renderer/Canvas.js.map +1 -1
  103. package/lib/module/skia/types/Graphite.d.ts +3 -3
  104. package/lib/module/skia/types/Graphite.js.map +1 -1
  105. package/lib/module/skia/types/Image/ImageFactory.d.ts +2 -2
  106. package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
  107. package/lib/module/skia/types/Skia.d.ts +1 -2
  108. package/lib/module/skia/types/Skia.js.map +1 -1
  109. package/lib/module/skia/types/Surface/SurfaceFactory.d.ts +1 -1
  110. package/lib/module/skia/types/Surface/SurfaceFactory.js.map +1 -1
  111. package/lib/module/specs/NativeSkiaModule.web.d.ts +5 -4
  112. package/lib/module/specs/NativeSkiaModule.web.js +5 -9
  113. package/lib/module/specs/NativeSkiaModule.web.js.map +1 -1
  114. package/lib/{commonjs/specs/SkiaPictureViewNativeComponent.d.ts → module/specs/SkiaViewNativeComponent.d.ts} +0 -3
  115. package/lib/module/specs/{SkiaPictureViewNativeComponent.js → SkiaViewNativeComponent.js} +2 -2
  116. package/lib/module/specs/SkiaViewNativeComponent.js.map +1 -0
  117. package/lib/module/specs/SkiaViewNativeComponent.web.d.ts +10 -0
  118. package/lib/module/specs/SkiaViewNativeComponent.web.js +21 -0
  119. package/lib/module/specs/SkiaViewNativeComponent.web.js.map +1 -0
  120. package/lib/module/views/SkiaGraphiteView.d.ts +3 -4
  121. package/lib/module/views/SkiaGraphiteView.js +23 -12
  122. package/lib/module/views/SkiaGraphiteView.js.map +1 -1
  123. package/lib/module/views/SkiaPictureView.d.ts +4 -1
  124. package/lib/module/views/SkiaPictureView.js +12 -10
  125. package/lib/module/views/SkiaPictureView.js.map +1 -1
  126. package/lib/module/views/SkiaView.web.d.ts +12 -0
  127. package/lib/module/views/{SkiaGraphiteView.web.js → SkiaView.web.js} +80 -36
  128. package/lib/module/views/SkiaView.web.js.map +1 -0
  129. package/lib/module/views/SkiaWebRenderer.js +1 -1
  130. package/lib/module/views/SkiaWebRenderer.js.map +1 -1
  131. package/lib/module/views/android.d.ts +6 -0
  132. package/lib/module/views/android.js +10 -0
  133. package/lib/module/views/android.js.map +1 -0
  134. package/lib/module/views/types.d.ts +3 -12
  135. package/lib/module/views/types.js.map +1 -1
  136. package/lib/typescript/src/index.d.ts +1 -3
  137. package/lib/typescript/src/renderer/Canvas.d.ts +15 -12
  138. package/lib/typescript/src/skia/types/Graphite.d.ts +3 -3
  139. package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +2 -2
  140. package/lib/typescript/src/skia/types/Skia.d.ts +1 -2
  141. package/lib/typescript/src/skia/types/Surface/SurfaceFactory.d.ts +1 -1
  142. package/lib/typescript/src/specs/NativeSkiaModule.web.d.ts +5 -4
  143. package/lib/{module/specs/SkiaPictureViewNativeComponent.d.ts → typescript/src/specs/SkiaViewNativeComponent.d.ts} +0 -3
  144. package/lib/typescript/src/specs/SkiaViewNativeComponent.web.d.ts +10 -0
  145. package/lib/typescript/src/views/SkiaGraphiteView.d.ts +3 -4
  146. package/lib/typescript/src/views/SkiaPictureView.d.ts +4 -1
  147. package/lib/typescript/src/views/SkiaView.web.d.ts +12 -0
  148. package/lib/typescript/src/views/android.d.ts +6 -0
  149. package/lib/typescript/src/views/types.d.ts +3 -12
  150. package/package.json +5 -13
  151. package/react-native-skia.podspec +34 -58
  152. package/src/Platform/Platform.web.tsx +1 -1
  153. package/src/external/reanimated/interpolators.ts +1 -1
  154. package/src/index.ts +1 -3
  155. package/src/mock/index.ts +0 -1
  156. package/src/renderer/Canvas.tsx +24 -28
  157. package/src/skia/types/Graphite.ts +3 -3
  158. package/src/skia/types/Image/ImageFactory.ts +2 -2
  159. package/src/skia/types/Skia.ts +1 -2
  160. package/src/skia/types/Surface/SurfaceFactory.ts +1 -1
  161. package/src/specs/NativeSkiaModule.web.ts +9 -21
  162. package/src/specs/{SkiaPictureViewNativeComponent.ts → SkiaViewNativeComponent.ts} +1 -4
  163. package/src/specs/{SkiaPictureViewNativeComponent.web.ts → SkiaViewNativeComponent.web.ts} +8 -10
  164. package/src/views/SkiaGraphiteView.tsx +27 -16
  165. package/src/views/SkiaPictureView.tsx +11 -10
  166. package/src/views/{SkiaGraphiteView.web.tsx → SkiaView.web.tsx} +100 -53
  167. package/src/views/SkiaWebRenderer.ts +1 -1
  168. package/src/views/android.ts +16 -0
  169. package/src/views/types.ts +3 -14
  170. package/android/cpp/jni/include/JniSkiaBaseView.h +0 -92
  171. package/android/cpp/jni/include/JniSkiaGraphiteView.h +0 -176
  172. package/android/cpp/jni/include/JniSkiaPictureView.h +0 -172
  173. package/android/cpp/rnskia-android/GrAHardwareBufferUtils.cpp +0 -245
  174. package/android/cpp/rnskia-android/GrAHardwareBufferUtils.h +0 -33
  175. package/android/cpp/rnskia-android/OpenGLContext.h +0 -248
  176. package/android/cpp/rnskia-android/OpenGLWindowContext.cpp +0 -67
  177. package/android/cpp/rnskia-android/OpenGLWindowContext.h +0 -75
  178. package/android/cpp/rnskia-android/RNSkAndroidView.h +0 -67
  179. package/android/cpp/rnskia-android/gl/Context.h +0 -80
  180. package/android/cpp/rnskia-android/gl/Display.h +0 -123
  181. package/android/cpp/rnskia-android/gl/Error.cpp +0 -45
  182. package/android/cpp/rnskia-android/gl/Error.h +0 -8
  183. package/android/cpp/rnskia-android/gl/Surface.h +0 -43
  184. package/android/src/main/java/com/reactnative/skia/SkiaBaseViewManager.java +0 -65
  185. package/android/src/main/java/com/reactnative/skia/SkiaGraphiteView.java +0 -78
  186. package/android/src/main/java/com/reactnative/skia/SkiaGraphiteViewManager.java +0 -32
  187. package/android/src/main/java/com/reactnative/skia/SkiaPictureView.java +0 -105
  188. package/android/src/main/java/com/reactnative/skia/SkiaPictureViewManager.java +0 -44
  189. package/apple/MetalContext.h +0 -116
  190. package/apple/MetalContext.mm +0 -38
  191. package/apple/MetalWindowContext.h +0 -42
  192. package/apple/MetalWindowContext.mm +0 -95
  193. package/apple/RNSkAppleView.h +0 -49
  194. package/apple/RNSkAppleView.mm +0 -35
  195. package/apple/SkiaCVPixelBufferUtils.h +0 -122
  196. package/apple/SkiaCVPixelBufferUtils.mm +0 -535
  197. package/apple/SkiaGraphiteView.h +0 -26
  198. package/apple/SkiaGraphiteView.mm +0 -180
  199. package/apple/SkiaPictureView.h +0 -7
  200. package/apple/SkiaPictureView.mm +0 -70
  201. package/apple/SkiaUIView.h +0 -31
  202. package/apple/SkiaUIView.mm +0 -164
  203. package/cpp/rnskia/RNSkGraphiteView.h +0 -708
  204. package/cpp/rnskia/RNSkPictureView.cpp +0 -69
  205. package/cpp/rnskia/RNSkPictureView.h +0 -211
  206. package/cpp/skia/src/gpu/ganesh/gl/GrGLDefines.h +0 -1162
  207. package/lib/commonjs/renderer/DefaultCanvas.d.ts +0 -8
  208. package/lib/commonjs/renderer/DefaultCanvas.js +0 -42
  209. package/lib/commonjs/renderer/DefaultCanvas.js.map +0 -1
  210. package/lib/commonjs/renderer/GraphiteCanvas.d.ts +0 -22
  211. package/lib/commonjs/renderer/GraphiteCanvas.js +0 -64
  212. package/lib/commonjs/renderer/GraphiteCanvas.js.map +0 -1
  213. package/lib/commonjs/renderer/GraphiteCanvas.web.d.ts +0 -1
  214. package/lib/commonjs/renderer/GraphiteCanvas.web.js +0 -13
  215. package/lib/commonjs/renderer/GraphiteCanvas.web.js.map +0 -1
  216. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.d.ts +0 -10
  217. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.js +0 -12
  218. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.js.map +0 -1
  219. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.web.d.ts +0 -9
  220. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.web.js +0 -28
  221. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.web.js.map +0 -1
  222. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +0 -1
  223. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +0 -10
  224. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js +0 -29
  225. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js.map +0 -1
  226. package/lib/commonjs/views/SkiaGraphiteView.web.d.ts +0 -14
  227. package/lib/commonjs/views/SkiaGraphiteView.web.js.map +0 -1
  228. package/lib/commonjs/views/SkiaPictureView.web.d.ts +0 -11
  229. package/lib/commonjs/views/SkiaPictureView.web.js +0 -165
  230. package/lib/commonjs/views/SkiaPictureView.web.js.map +0 -1
  231. package/lib/module/renderer/DefaultCanvas.d.ts +0 -8
  232. package/lib/module/renderer/DefaultCanvas.js +0 -34
  233. package/lib/module/renderer/DefaultCanvas.js.map +0 -1
  234. package/lib/module/renderer/GraphiteCanvas.d.ts +0 -22
  235. package/lib/module/renderer/GraphiteCanvas.js +0 -57
  236. package/lib/module/renderer/GraphiteCanvas.js.map +0 -1
  237. package/lib/module/renderer/GraphiteCanvas.web.d.ts +0 -1
  238. package/lib/module/renderer/GraphiteCanvas.web.js +0 -4
  239. package/lib/module/renderer/GraphiteCanvas.web.js.map +0 -1
  240. package/lib/module/specs/SkiaGraphiteViewNativeComponent.d.ts +0 -10
  241. package/lib/module/specs/SkiaGraphiteViewNativeComponent.js +0 -8
  242. package/lib/module/specs/SkiaGraphiteViewNativeComponent.js.map +0 -1
  243. package/lib/module/specs/SkiaGraphiteViewNativeComponent.web.d.ts +0 -9
  244. package/lib/module/specs/SkiaGraphiteViewNativeComponent.web.js +0 -22
  245. package/lib/module/specs/SkiaGraphiteViewNativeComponent.web.js.map +0 -1
  246. package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +0 -1
  247. package/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +0 -10
  248. package/lib/module/specs/SkiaPictureViewNativeComponent.web.js +0 -23
  249. package/lib/module/specs/SkiaPictureViewNativeComponent.web.js.map +0 -1
  250. package/lib/module/views/SkiaGraphiteView.web.d.ts +0 -14
  251. package/lib/module/views/SkiaGraphiteView.web.js.map +0 -1
  252. package/lib/module/views/SkiaPictureView.web.d.ts +0 -11
  253. package/lib/module/views/SkiaPictureView.web.js +0 -156
  254. package/lib/module/views/SkiaPictureView.web.js.map +0 -1
  255. package/lib/typescript/src/renderer/DefaultCanvas.d.ts +0 -8
  256. package/lib/typescript/src/renderer/GraphiteCanvas.d.ts +0 -22
  257. package/lib/typescript/src/renderer/GraphiteCanvas.web.d.ts +0 -1
  258. package/lib/typescript/src/specs/SkiaGraphiteViewNativeComponent.d.ts +0 -10
  259. package/lib/typescript/src/specs/SkiaGraphiteViewNativeComponent.web.d.ts +0 -9
  260. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.web.d.ts +0 -10
  261. package/lib/typescript/src/views/SkiaGraphiteView.web.d.ts +0 -14
  262. package/lib/typescript/src/views/SkiaPictureView.web.d.ts +0 -11
  263. package/libs/.graphite +0 -1
  264. package/src/renderer/DefaultCanvas.tsx +0 -41
  265. package/src/renderer/GraphiteCanvas.tsx +0 -61
  266. package/src/renderer/GraphiteCanvas.web.tsx +0 -3
  267. package/src/specs/SkiaGraphiteViewNativeComponent.ts +0 -17
  268. package/src/specs/SkiaGraphiteViewNativeComponent.web.ts +0 -31
  269. package/src/views/SkiaPictureView.web.tsx +0 -224
@@ -1,7 +1,5 @@
1
1
  #pragma once
2
2
 
3
- #if defined(SK_GRAPHITE)
4
-
5
3
  #include <memory>
6
4
  #include <mutex>
7
5
 
@@ -20,9 +18,9 @@ class Recorder;
20
18
  class RNSkGraphiteTarget;
21
19
 
22
20
  /**
23
- * Records the declarative content of a SkiaGraphiteView (a Recorder handed
24
- * over by <GraphiteCanvas>, or a picture) into Graphite recordings, on the
25
- * render thread pool.
21
+ * Records the declarative content of a view (a Recorder handed over by
22
+ * <Canvas>, or a picture) into Graphite recordings, on the render thread
23
+ * pool.
26
24
  *
27
25
  * Three threads meet here. The JS thread hands over the content. A Reanimated
28
26
  * mapper, on the UI runtime, reads the shared values into the recorder's
@@ -50,7 +48,11 @@ public:
50
48
  /**
51
49
  Takes ownership of the recorder (or releases it with nullptr). A recording
52
50
  without shared values is played once into a picture: nothing will ever
53
- update it, and drawing a picture is cheaper than replaying commands.
51
+ update it, and drawing a picture is cheaper than replaying commands. The
52
+ recorder is owned here rather than by a JS wrapper: its commands hold
53
+ every native resource the canvas draws (images, pictures, paths), and
54
+ tying their lifetime to the garbage collector of a runtime that rarely
55
+ allocates (the UI runtime) kept them resident long after unmount.
54
56
  */
55
57
  void setRecorder(std::shared_ptr<Recorder> recorder);
56
58
 
@@ -73,6 +75,14 @@ public:
73
75
  bool applyUpdates(jsi::Runtime &runtime, double recorderId,
74
76
  const jsi::Array &values);
75
77
 
78
+ /**
79
+ Same as applyUpdates(), for a recording that no view owns yet (one queued
80
+ in the view registry until its view registers).
81
+ */
82
+ static bool applyUpdatesTo(const std::shared_ptr<Recorder> &recorder,
83
+ jsi::Runtime &runtime, double recorderId,
84
+ const jsi::Array &values);
85
+
76
86
  /**
77
87
  Marks the content dirty and schedules a frame if one can start. Returns
78
88
  whether a frame is coming at all: there is content and a target to record
@@ -90,6 +100,13 @@ public:
90
100
  void renderInto(SkCanvas *canvas, float pixelDensity);
91
101
 
92
102
  private:
103
+ /**
104
+ Replays declarative content, a recorder if there is one, else a picture,
105
+ into a canvas: clears it and applies the density.
106
+ */
107
+ static void drawContent(SkCanvas *canvas, Recorder *recorder,
108
+ const sk_sp<SkPicture> &picture, float pixelDensity);
109
+
93
110
  /**
94
111
  Swaps the content under the lock and releases the previous one outside of
95
112
  it: the recorder's destructor hands the commands to the main thread, and a
@@ -112,5 +129,3 @@ private:
112
129
  };
113
130
 
114
131
  } // namespace RNSkia
115
-
116
- #endif // SK_GRAPHITE
@@ -0,0 +1,396 @@
1
+ #pragma once
2
+
3
+ #include <cmath>
4
+ #include <deque>
5
+ #include <functional>
6
+ #include <memory>
7
+ #include <mutex>
8
+ #include <stdexcept>
9
+ #include <unordered_map>
10
+ #include <utility>
11
+ #include <vector>
12
+
13
+ #include "RNDawnContext.h"
14
+ #include "RNDawnUtils.h"
15
+ #include "RNSkCanvasProvider.h"
16
+ #include "RNSkPlatformContext.h"
17
+
18
+ #pragma clang diagnostic push
19
+ #pragma clang diagnostic ignored "-Wdocumentation"
20
+
21
+ #include "include/core/SkCanvas.h"
22
+ #include "include/core/SkColorSpace.h"
23
+ #include "include/core/SkImageInfo.h"
24
+ #include "include/gpu/graphite/Recorder.h"
25
+ #include "include/gpu/graphite/Recording.h"
26
+ #include "include/gpu/graphite/TextureInfo.h"
27
+ #include "include/gpu/graphite/dawn/DawnGraphiteTypes.h"
28
+
29
+ #pragma clang diagnostic pop
30
+
31
+ namespace RNSkia {
32
+
33
+ /**
34
+ * The Graphite recorder of one view. Shared by the view's target and by every
35
+ * recording snapped from it, so that the recorder outlives its recordings
36
+ * whichever of them is released last.
37
+ */
38
+ struct RNSkGraphiteRecorder {
39
+ std::unique_ptr<skgpu::graphite::Recorder> recorder;
40
+ };
41
+
42
+ /**
43
+ * A frame snapped from a view's recorder, with the description of the target
44
+ * it was recorded for. Immutable once snapped: it can be replayed any number
45
+ * of times, from any thread.
46
+ */
47
+ class RNSkGraphiteRecording {
48
+ public:
49
+ RNSkGraphiteRecording(std::shared_ptr<RNSkGraphiteRecorder> recorder,
50
+ std::unique_ptr<skgpu::graphite::Recording> recording,
51
+ const RNSkGraphiteTargetInfo &target)
52
+ : _recorder(std::move(recorder)), _recording(std::move(recording)),
53
+ _target(target) {}
54
+
55
+ skgpu::graphite::Recording *get() const { return _recording.get(); }
56
+
57
+ /**
58
+ Whether the recording was made for a texture of the given size. A deferred
59
+ canvas records against fixed dimensions: Graphite sizes the passes (and
60
+ their depth and stencil attachments) from them, so replaying it onto a
61
+ texture of another size is rejected by Dawn and draws nothing. A recording
62
+ of another size is replayed through a texture of its own size instead (see
63
+ RNSkView::present).
64
+ */
65
+ bool hasSizeOf(const RNSkGraphiteTargetInfo &target) const {
66
+ return _target.width == target.width && _target.height == target.height;
67
+ }
68
+
69
+ /** The target the recording was made for. */
70
+ const RNSkGraphiteTargetInfo &getTarget() const { return _target; }
71
+
72
+ /**
73
+ Whether the recording has the format of the given target, and the target
74
+ supports every usage the recording relies on.
75
+ */
76
+ bool hasFormatOf(const RNSkGraphiteTargetInfo &target) const {
77
+ return _target.colorType == target.colorType &&
78
+ _target.textureInfo.canBeFulfilledBy(target.textureInfo);
79
+ }
80
+
81
+ /**
82
+ Whether the recording was made in the color space of the given target. The
83
+ colors of a recording are converted when it is recorded: replayed onto a
84
+ target in another color space, they would be read in the wrong gamut. Such
85
+ a recording is replayed through a texture in its own color space instead,
86
+ which is then drawn, and converted, onto the target (see
87
+ RNSkView::present).
88
+ */
89
+ bool hasColorSpaceOf(const RNSkGraphiteTargetInfo &target) const {
90
+ return _target.useP3ColorSpace == target.useP3ColorSpace;
91
+ }
92
+
93
+ /** Whether the recording can be replayed straight onto the given target. */
94
+ bool isCompatibleWith(const RNSkGraphiteTargetInfo &target) const {
95
+ return hasSizeOf(target) && hasFormatOf(target) && hasColorSpaceOf(target);
96
+ }
97
+
98
+ private:
99
+ // Declared before the recording so that the recording is released first.
100
+ std::shared_ptr<RNSkGraphiteRecorder> _recorder;
101
+ std::unique_ptr<skgpu::graphite::Recording> _recording;
102
+ RNSkGraphiteTargetInfo _target;
103
+ };
104
+
105
+ /**
106
+ * What a view and the producers recording for it share: the view's recorder,
107
+ * the queue of recordings waiting to be presented and the description of the
108
+ * target texture. Created by whichever side comes first (see
109
+ * RNSkGraphiteTargetRegistry) and kept alive by both.
110
+ *
111
+ * Recording happens on the producer's thread (the JS thread, a worklet
112
+ * runtime or the render thread pool), presenting on the main thread; the
113
+ * queue is the hand-off. A recorder serves one thread at a time, which is
114
+ * enforced by allowing a single open recording.
115
+ */
116
+ class RNSkGraphiteTarget {
117
+ public:
118
+ explicit RNSkGraphiteTarget(std::shared_ptr<RNSkPlatformContext> context)
119
+ : _context(std::move(context)) {}
120
+
121
+ // Producer side ------------------------------------------------------------
122
+
123
+ /**
124
+ The layout size (points) and the props the format follows from, as known
125
+ to JS. Used until the view has a surface of its own.
126
+ */
127
+ void setLayout(float width, float height, bool opaque, bool highBitDepth) {
128
+ std::lock_guard<std::mutex> lock(_stateMutex);
129
+ _layoutWidth = width;
130
+ _layoutHeight = height;
131
+ _opaque = opaque;
132
+ _highBitDepth = highBitDepth;
133
+ }
134
+
135
+ /** Current width of the target, in points. */
136
+ float getWidth() {
137
+ return resolveTargetInfo().width / _context->getPixelDensity();
138
+ }
139
+
140
+ /** Current height of the target, in points. */
141
+ float getHeight() {
142
+ return resolveTargetInfo().height / _context->getPixelDensity();
143
+ }
144
+
145
+ /**
146
+ Returns a canvas that records the next frame, in points. The canvas is
147
+ deleted by finishRecording(). Throws while a recording is already open.
148
+ */
149
+ SkCanvas *beginRecording() {
150
+ auto target = resolveTargetInfo();
151
+ std::lock_guard<std::mutex> lock(_stateMutex);
152
+ if (_recording) {
153
+ throw std::runtime_error("SkiaGraphiteView: a recording is already open, "
154
+ "call finishRecording() first.");
155
+ }
156
+ if (target.width <= 0 || target.height <= 0) {
157
+ throw std::runtime_error("SkiaGraphiteView: the view has no size yet.");
158
+ }
159
+ if (_recorder == nullptr) {
160
+ auto recorder = std::make_shared<RNSkGraphiteRecorder>();
161
+ recorder->recorder = DawnContext::getInstance().makeRecorder();
162
+ if (recorder->recorder == nullptr) {
163
+ throw std::runtime_error(
164
+ "SkiaGraphiteView: could not create a Graphite recorder.");
165
+ }
166
+ _recorder = std::move(recorder);
167
+ }
168
+ auto imageInfo = SkImageInfo::Make(
169
+ target.width, target.height, target.colorType, kPremul_SkAlphaType,
170
+ DawnUtils::viewColorSpace(target.useP3ColorSpace));
171
+ auto *canvas =
172
+ _recorder->recorder->makeDeferredCanvas(imageInfo, target.textureInfo);
173
+ if (canvas == nullptr) {
174
+ throw std::runtime_error(
175
+ "SkiaGraphiteView: could not create a deferred canvas.");
176
+ }
177
+ // The canvas loads whatever the target holds: the producer clears.
178
+ auto pd = _context->getPixelDensity();
179
+ canvas->scale(pd, pd);
180
+ _recording = true;
181
+ _recordingTarget = target;
182
+ return canvas;
183
+ }
184
+
185
+ /** Snaps the open recording. Throws when no recording is open. */
186
+ std::shared_ptr<RNSkGraphiteRecording> finishRecording() {
187
+ std::lock_guard<std::mutex> lock(_stateMutex);
188
+ if (!_recording) {
189
+ throw std::runtime_error("SkiaGraphiteView: no recording is open, call "
190
+ "beginRecording() first.");
191
+ }
192
+ _recording = false;
193
+ auto recording = _recorder->recorder->snap();
194
+ if (recording == nullptr) {
195
+ throw std::runtime_error(
196
+ "SkiaGraphiteView: snapping the recording failed.");
197
+ }
198
+ return std::make_shared<RNSkGraphiteRecording>(
199
+ _recorder, std::move(recording), _recordingTarget);
200
+ }
201
+
202
+ /**
203
+ Queues a recording for the next frame. Recordings are never dropped: a
204
+ later frame may depend on resources an earlier one uploaded.
205
+ */
206
+ void submit(std::shared_ptr<RNSkGraphiteRecording> recording) {
207
+ std::function<void()> requestFrame;
208
+ {
209
+ std::lock_guard<std::mutex> lock(_queueMutex);
210
+ _queue.push_back(std::move(recording));
211
+ requestFrame = _requestFrame;
212
+ }
213
+ if (requestFrame) {
214
+ requestFrame();
215
+ }
216
+ }
217
+
218
+ // View side ----------------------------------------------------------------
219
+
220
+ /**
221
+ Binds the target to the view's surface: the provider describes the target
222
+ texture, requestFrame asks the view to present the queue.
223
+ */
224
+ void attach(std::weak_ptr<RNSkCanvasProvider> provider,
225
+ std::function<void()> requestFrame) {
226
+ {
227
+ std::lock_guard<std::mutex> lock(_stateMutex);
228
+ _provider = std::move(provider);
229
+ }
230
+ std::lock_guard<std::mutex> lock(_queueMutex);
231
+ _requestFrame = std::move(requestFrame);
232
+ }
233
+
234
+ /**
235
+ Undoes attach(), for the view owning the given provider only. Native view
236
+ ids are reused across reloads and an Android view is only destroyed when
237
+ its Java object is finalized, so a view going away may find its target
238
+ already bound to its successor; that binding is left alone.
239
+ */
240
+ void detach(const std::shared_ptr<RNSkCanvasProvider> &provider) {
241
+ {
242
+ std::lock_guard<std::mutex> lock(_stateMutex);
243
+ if (_provider.lock() != provider) {
244
+ return;
245
+ }
246
+ _provider.reset();
247
+ }
248
+ std::lock_guard<std::mutex> lock(_queueMutex);
249
+ _requestFrame = nullptr;
250
+ }
251
+
252
+ /** Takes every recording submitted since the last call, in order. */
253
+ std::vector<std::shared_ptr<RNSkGraphiteRecording>> takeQueued() {
254
+ std::lock_guard<std::mutex> lock(_queueMutex);
255
+ std::vector<std::shared_ptr<RNSkGraphiteRecording>> recordings(
256
+ _queue.begin(), _queue.end());
257
+ _queue.clear();
258
+ return recordings;
259
+ }
260
+
261
+ /**
262
+ Puts recordings that could not be presented back at the front of the
263
+ queue, ahead of anything submitted meanwhile, so that the order holds.
264
+ */
265
+ void requeue(
266
+ const std::vector<std::shared_ptr<RNSkGraphiteRecording>> &recordings) {
267
+ std::lock_guard<std::mutex> lock(_queueMutex);
268
+ _queue.insert(_queue.begin(), recordings.begin(), recordings.end());
269
+ }
270
+
271
+ /** The most recently submitted recording still waiting, if any. */
272
+ std::shared_ptr<RNSkGraphiteRecording> peekLatest() {
273
+ std::lock_guard<std::mutex> lock(_queueMutex);
274
+ return _queue.empty() ? nullptr : _queue.back();
275
+ }
276
+
277
+ bool hasQueued() {
278
+ std::lock_guard<std::mutex> lock(_queueMutex);
279
+ return !_queue.empty();
280
+ }
281
+
282
+ private:
283
+ /**
284
+ The target to record against: the view's surface when it has one, else
285
+ the pixel size the platform laid the view out with, else the layout size
286
+ JS measured; in the last two cases with the format and the color space
287
+ the surface will be created with, following the same rules (see
288
+ DawnWindowContext and SkiaView.java).
289
+ */
290
+ RNSkGraphiteTargetInfo resolveTargetInfo() {
291
+ std::shared_ptr<RNSkCanvasProvider> provider;
292
+ float width;
293
+ float height;
294
+ bool opaque;
295
+ bool highBitDepth;
296
+ {
297
+ std::lock_guard<std::mutex> lock(_stateMutex);
298
+ provider = _provider.lock();
299
+ width = _layoutWidth;
300
+ height = _layoutHeight;
301
+ opaque = _opaque;
302
+ highBitDepth = _highBitDepth;
303
+ }
304
+ RNSkGraphiteTargetInfo info;
305
+ if (provider && provider->getTargetInfo(&info)) {
306
+ return info;
307
+ }
308
+ #if defined(__ANDROID__)
309
+ // The 10-bit buffer format only has 2 bits of alpha: translucent views
310
+ // stay 8-bit.
311
+ if (!opaque) {
312
+ highBitDepth = false;
313
+ }
314
+ #else
315
+ (void)opaque;
316
+ #endif
317
+ if (!provider || !provider->getLayoutSize(&info.width, &info.height)) {
318
+ // Not laid out yet (JS gets its onLayout before the platform lays the
319
+ // view out): the size JS measured, in points. The layout is on the
320
+ // pixel grid, so the product is an integer up to rounding errors.
321
+ double pd = _context->getPixelDensity();
322
+ info.width = static_cast<int>(std::lround(width * pd));
323
+ info.height = static_cast<int>(std::lround(height * pd));
324
+ } else {
325
+ }
326
+ info.colorType = highBitDepth ? DawnUtils::HighBitDepthColorType
327
+ : DawnUtils::PreferedColorType;
328
+ info.useP3ColorSpace = _context->prefersP3ColorSpace();
329
+ info.textureInfo = skgpu::graphite::TextureInfos::MakeDawn(
330
+ skgpu::graphite::DawnTextureInfo(
331
+ skgpu::graphite::SampleCount::k1, skgpu::Mipmapped::kNo,
332
+ highBitDepth ? DawnUtils::HighBitDepthTextureFormat
333
+ : DawnUtils::PreferredTextureFormat,
334
+ DawnUtils::DefaultTargetUsage, wgpu::TextureAspect::All));
335
+ return info;
336
+ }
337
+
338
+ std::shared_ptr<RNSkPlatformContext> _context;
339
+
340
+ // Recorder, open recording and target description.
341
+ std::mutex _stateMutex;
342
+ std::shared_ptr<RNSkGraphiteRecorder> _recorder;
343
+ bool _recording = false;
344
+ RNSkGraphiteTargetInfo _recordingTarget;
345
+ std::weak_ptr<RNSkCanvasProvider> _provider;
346
+ float _layoutWidth = 0;
347
+ float _layoutHeight = 0;
348
+ bool _opaque = false;
349
+ bool _highBitDepth = false;
350
+
351
+ // Hand-off to the main thread.
352
+ std::mutex _queueMutex;
353
+ std::deque<std::shared_ptr<RNSkGraphiteRecording>> _queue;
354
+ std::function<void()> _requestFrame;
355
+ };
356
+
357
+ /**
358
+ * Targets by native view id. Entries are weak: a target lives as long as the
359
+ * view or a JS context object holds it.
360
+ */
361
+ class RNSkGraphiteTargetRegistry {
362
+ public:
363
+ static RNSkGraphiteTargetRegistry &getInstance() {
364
+ static RNSkGraphiteTargetRegistry instance;
365
+ return instance;
366
+ }
367
+
368
+ RNSkGraphiteTargetRegistry(const RNSkGraphiteTargetRegistry &) = delete;
369
+ RNSkGraphiteTargetRegistry &
370
+ operator=(const RNSkGraphiteTargetRegistry &) = delete;
371
+
372
+ std::shared_ptr<RNSkGraphiteTarget>
373
+ getOrCreate(size_t nativeId,
374
+ const std::shared_ptr<RNSkPlatformContext> &context) {
375
+ std::lock_guard<std::mutex> lock(_mutex);
376
+ auto it = _targets.find(nativeId);
377
+ if (it != _targets.end()) {
378
+ if (auto target = it->second.lock()) {
379
+ return target;
380
+ }
381
+ }
382
+ for (auto entry = _targets.begin(); entry != _targets.end();) {
383
+ entry = entry->second.expired() ? _targets.erase(entry) : ++entry;
384
+ }
385
+ auto target = std::make_shared<RNSkGraphiteTarget>(context);
386
+ _targets[nativeId] = target;
387
+ return target;
388
+ }
389
+
390
+ private:
391
+ RNSkGraphiteTargetRegistry() = default;
392
+ std::mutex _mutex;
393
+ std::unordered_map<size_t, std::weak_ptr<RNSkGraphiteTarget>> _targets;
394
+ };
395
+
396
+ } // namespace RNSkia
@@ -10,19 +10,16 @@
10
10
  #include <utility>
11
11
  #include <vector>
12
12
 
13
- #include "RNSkPictureView.h"
13
+ #include "RNSkGraphiteProducer.h"
14
+ #include "RNSkGraphiteTarget.h"
14
15
  #include "RNSkPlatformContext.h"
15
16
  #include "RNSkView.h"
17
+ #include "api/JsiSkGraphiteContext.h"
16
18
  #include "api/JsiSkNativeObjects.h"
17
19
  #include "jsi/JsiPromises.h"
18
20
  #include "jsi/ViewProperty.h"
19
21
  #include <jsi/jsi.h>
20
22
 
21
- #if defined(SK_GRAPHITE)
22
- #include "RNSkGraphiteView.h"
23
- #include "api/JsiSkGraphiteContext.h"
24
- #endif
25
-
26
23
  namespace RNSkia {
27
24
 
28
25
  namespace jsi = facebook::jsi;
@@ -223,8 +220,8 @@ public:
223
220
  // the values from recording time until the next change.
224
221
  auto it = info->props.find("recorder");
225
222
  if (it != info->props.end() && it->second.isRecorder()) {
226
- RNSkPictureRenderer::applyUpdatesTo(it->second.getRecorder(),
227
- runtime, recorderId, values);
223
+ RNSkGraphiteProducer::applyUpdatesTo(it->second.getRecorder(),
224
+ runtime, recorderId, values);
228
225
  }
229
226
  });
230
227
  if (view == nullptr) {
@@ -355,13 +352,12 @@ public:
355
352
  }
356
353
 
357
354
  /**
358
- Returns the recording side of a SkiaGraphiteView: (nativeId, width,
359
- height, opaque, highBitDepth), the size in points as laid out and the
360
- props the surface format follows from. The view may not exist yet; the
361
- context binds to it by id when it does.
355
+ Returns the recording side of a view: (nativeId, width, height, opaque,
356
+ highBitDepth), the size in points as laid out and the props the surface
357
+ format follows from. The view may not exist yet; the context binds to it
358
+ by id when it does.
362
359
  */
363
360
  JSI_HOST_FUNCTION(makeGraphiteContext) {
364
- #if defined(SK_GRAPHITE)
365
361
  if (count < 3 || !arguments[0].isNumber() || !arguments[1].isNumber() ||
366
362
  !arguments[2].isNumber()) {
367
363
  throw jsi::JSError(runtime, "makeGraphiteContext: expected (nativeId, "
@@ -378,11 +374,6 @@ public:
378
374
  target->setLayout(width, height, opaque, highBitDepth);
379
375
  return makeJsiObject(runtime, std::make_shared<JsiSkGraphiteContext>(
380
376
  _platformContext, std::move(target)));
381
- #else
382
- throw jsi::JSError(runtime,
383
- "SkiaGraphiteView requires the Graphite backend. "
384
- "Rebuild with SK_GRAPHITE enabled.");
385
- #endif
386
377
  }
387
378
 
388
379
  static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
@@ -105,34 +105,28 @@ public:
105
105
  */
106
106
  virtual sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) = 0;
107
107
 
108
- #if !defined(SK_GRAPHITE)
109
- virtual sk_sp<SkImage>
110
- makeImageFromNativeTexture(const TextureInfo &textureInfo, int width,
111
- int height, bool mipMapped) = 0;
112
-
113
- virtual const TextureInfo getTexture(sk_sp<SkSurface> image) = 0;
114
-
115
- virtual const TextureInfo getTexture(sk_sp<SkImage> image) = 0;
116
-
117
- virtual GrDirectContext *getDirectContext() = 0;
118
- #else
108
+ // The handle-based texture interop of the Ganesh era (Metal and OpenGL
109
+ // texture handles). Graphite textures cross the package boundary as
110
+ // WGPUTexture pointers instead (see JsiSkImageFactory).
119
111
  sk_sp<SkImage> makeImageFromNativeTexture(const TextureInfo &textureInfo,
120
112
  int width, int height,
121
113
  bool mipMapped) {
122
114
  throw std::runtime_error(
123
- "makeImageFromNativeTexture not implemented yet on Graphite");
115
+ "makeImageFromNativeTexture is not available on Graphite, use "
116
+ "Skia.Image.MakeImageFromNativeTexture(pointer)");
124
117
  }
125
118
 
126
119
  const TextureInfo getTexture(sk_sp<SkSurface> image) {
127
120
  throw std::runtime_error(
128
- "getTexture(surface) not implemented yet on Graphite");
121
+ "getTexture(surface) is not available on Graphite, use "
122
+ "Skia.Surface.MakeFromNativeTexture(pointer)");
129
123
  }
130
124
 
131
125
  const TextureInfo getTexture(sk_sp<SkImage> image) {
132
126
  throw std::runtime_error(
133
- "getTexture(image) not implemented yet on Graphite");
127
+ "getTexture(image) is not available on Graphite, use "
128
+ "Skia.Image.MakeNativeTextureFromImage(image)");
134
129
  }
135
- #endif
136
130
 
137
131
  virtual void releaseNativeBuffer(uint64_t pointer) = 0;
138
132
 
@@ -197,6 +191,14 @@ public:
197
191
  */
198
192
  float getPixelDensity() { return _pixelDensity; }
199
193
 
194
+ /**
195
+ * Whether views render in Display P3 rather than sRGB: true on Apple
196
+ * platforms when the main screen has a wide color gamut. The answer does
197
+ * not change over the lifetime of the context, so a frame can be recorded
198
+ * for a view before its surface exists.
199
+ */
200
+ virtual bool prefersP3ColorSpace() { return false; }
201
+
200
202
  private:
201
203
  float _pixelDensity;
202
204
  std::shared_ptr<react::CallInvoker> _callInvoker;