react-native-skia 3.0.0 → 3.0.2

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 (261) hide show
  1. package/Package.swift +14 -13
  2. package/android/CMakeLists.txt +13 -42
  3. package/android/build.gradle +55 -47
  4. package/android/cpp/jni/JniLoad.cpp +2 -4
  5. package/android/cpp/jni/include/JniSkiaView.h +123 -0
  6. package/android/cpp/rnskia-android/{RNSkOpenGLCanvasProvider.cpp → RNSkAndroidCanvasProvider.cpp} +45 -100
  7. package/android/cpp/rnskia-android/{RNSkOpenGLCanvasProvider.h → RNSkAndroidCanvasProvider.h} +24 -22
  8. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +0 -83
  9. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +0 -8
  10. package/android/src/main/java/com/reactnative/skia/RNSkiaPackage.java +1 -2
  11. package/android/src/main/java/com/reactnative/skia/SkiaSurfaceView.java +1 -3
  12. package/android/src/main/java/com/reactnative/skia/SkiaTextureView.java +1 -17
  13. package/android/src/main/java/com/reactnative/skia/{SkiaBaseView.java → SkiaView.java} +78 -16
  14. package/android/src/main/java/com/reactnative/skia/SkiaViewManager.java +85 -0
  15. package/apple/MetalLayerColorSpace.mm +0 -4
  16. package/apple/RNSkApplePlatformContext.h +0 -14
  17. package/apple/RNSkApplePlatformContext.mm +2 -112
  18. package/apple/RNSkMetalCanvasProvider.h +14 -19
  19. package/apple/RNSkMetalCanvasProvider.mm +35 -68
  20. package/apple/SkiaView.h +20 -0
  21. package/apple/SkiaView.mm +210 -0
  22. package/cpp/api/JsiSkApi.h +2 -13
  23. package/cpp/api/JsiSkCanvas.h +4 -18
  24. package/cpp/api/JsiSkGraphiteContext.h +1 -5
  25. package/cpp/api/JsiSkGraphiteRecording.h +1 -5
  26. package/cpp/api/JsiSkImage.h +7 -41
  27. package/cpp/api/JsiSkImageFactory.h +0 -14
  28. package/cpp/api/JsiSkSurface.h +2 -16
  29. package/cpp/api/JsiSkSurfaceFactory.h +0 -8
  30. package/cpp/rnskia/RNDawnContext.h +6 -0
  31. package/cpp/rnskia/RNDawnInterop.cpp +0 -4
  32. package/cpp/rnskia/RNDawnUtils.h +0 -1
  33. package/cpp/rnskia/RNDawnWindowContext.cpp +10 -0
  34. package/cpp/rnskia/RNDawnWindowContext.h +4 -0
  35. package/cpp/rnskia/RNSkCanvasProvider.h +221 -0
  36. package/cpp/rnskia/RNSkGraphiteProducer.cpp +36 -14
  37. package/cpp/rnskia/RNSkGraphiteProducer.h +23 -8
  38. package/cpp/rnskia/RNSkGraphiteTarget.h +383 -0
  39. package/cpp/rnskia/RNSkJsiViewApi.h +9 -18
  40. package/cpp/rnskia/RNSkPlatformContext.h +9 -15
  41. package/cpp/rnskia/RNSkView.h +340 -245
  42. package/jestSetup.js +1 -3
  43. package/lib/commonjs/Platform/Platform.web.js +1 -1
  44. package/lib/commonjs/Platform/Platform.web.js.map +1 -1
  45. package/lib/commonjs/index.d.ts +1 -3
  46. package/lib/commonjs/index.js +3 -12
  47. package/lib/commonjs/index.js.map +1 -1
  48. package/lib/commonjs/mock/index.js +0 -1
  49. package/lib/commonjs/mock/index.js.map +1 -1
  50. package/lib/commonjs/renderer/Canvas.d.ts +15 -12
  51. package/lib/commonjs/renderer/Canvas.js +24 -20
  52. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  53. package/lib/commonjs/skia/types/Graphite.d.ts +3 -3
  54. package/lib/commonjs/skia/types/Graphite.js.map +1 -1
  55. package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +2 -2
  56. package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
  57. package/lib/commonjs/skia/types/Skia.d.ts +1 -2
  58. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  59. package/lib/commonjs/skia/types/Surface/SurfaceFactory.d.ts +1 -1
  60. package/lib/commonjs/skia/types/Surface/SurfaceFactory.js.map +1 -1
  61. package/lib/commonjs/specs/NativeSkiaModule.web.d.ts +5 -4
  62. package/lib/commonjs/specs/NativeSkiaModule.web.js +5 -9
  63. package/lib/commonjs/specs/NativeSkiaModule.web.js.map +1 -1
  64. package/lib/{typescript/src/specs/SkiaPictureViewNativeComponent.d.ts → commonjs/specs/SkiaViewNativeComponent.d.ts} +0 -3
  65. package/lib/commonjs/specs/{SkiaPictureViewNativeComponent.js → SkiaViewNativeComponent.js} +2 -2
  66. package/lib/commonjs/specs/SkiaViewNativeComponent.js.map +1 -0
  67. package/lib/commonjs/specs/SkiaViewNativeComponent.web.d.ts +10 -0
  68. package/lib/commonjs/specs/SkiaViewNativeComponent.web.js +27 -0
  69. package/lib/commonjs/specs/SkiaViewNativeComponent.web.js.map +1 -0
  70. package/lib/commonjs/views/SkiaGraphiteView.d.ts +3 -4
  71. package/lib/commonjs/views/SkiaGraphiteView.js +23 -12
  72. package/lib/commonjs/views/SkiaGraphiteView.js.map +1 -1
  73. package/lib/commonjs/views/SkiaPictureView.d.ts +4 -1
  74. package/lib/commonjs/views/SkiaPictureView.js +12 -10
  75. package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
  76. package/lib/commonjs/views/SkiaView.web.d.ts +12 -0
  77. package/lib/commonjs/views/{SkiaGraphiteView.web.js → SkiaView.web.js} +82 -38
  78. package/lib/commonjs/views/SkiaView.web.js.map +1 -0
  79. package/lib/commonjs/views/SkiaWebRenderer.js +1 -1
  80. package/lib/commonjs/views/SkiaWebRenderer.js.map +1 -1
  81. package/lib/commonjs/views/android.d.ts +6 -0
  82. package/lib/commonjs/views/android.js +17 -0
  83. package/lib/commonjs/views/android.js.map +1 -0
  84. package/lib/commonjs/views/types.d.ts +3 -12
  85. package/lib/commonjs/views/types.js.map +1 -1
  86. package/lib/module/Platform/Platform.web.js +1 -1
  87. package/lib/module/Platform/Platform.web.js.map +1 -1
  88. package/lib/module/index.d.ts +1 -3
  89. package/lib/module/index.js +1 -3
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/module/mock/index.js +0 -1
  92. package/lib/module/mock/index.js.map +1 -1
  93. package/lib/module/renderer/Canvas.d.ts +15 -12
  94. package/lib/module/renderer/Canvas.js +24 -19
  95. package/lib/module/renderer/Canvas.js.map +1 -1
  96. package/lib/module/skia/types/Graphite.d.ts +3 -3
  97. package/lib/module/skia/types/Graphite.js.map +1 -1
  98. package/lib/module/skia/types/Image/ImageFactory.d.ts +2 -2
  99. package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
  100. package/lib/module/skia/types/Skia.d.ts +1 -2
  101. package/lib/module/skia/types/Skia.js.map +1 -1
  102. package/lib/module/skia/types/Surface/SurfaceFactory.d.ts +1 -1
  103. package/lib/module/skia/types/Surface/SurfaceFactory.js.map +1 -1
  104. package/lib/module/specs/NativeSkiaModule.web.d.ts +5 -4
  105. package/lib/module/specs/NativeSkiaModule.web.js +5 -9
  106. package/lib/module/specs/NativeSkiaModule.web.js.map +1 -1
  107. package/lib/{commonjs/specs/SkiaPictureViewNativeComponent.d.ts → module/specs/SkiaViewNativeComponent.d.ts} +0 -3
  108. package/lib/module/specs/{SkiaPictureViewNativeComponent.js → SkiaViewNativeComponent.js} +2 -2
  109. package/lib/module/specs/SkiaViewNativeComponent.js.map +1 -0
  110. package/lib/module/specs/SkiaViewNativeComponent.web.d.ts +10 -0
  111. package/lib/module/specs/SkiaViewNativeComponent.web.js +21 -0
  112. package/lib/module/specs/SkiaViewNativeComponent.web.js.map +1 -0
  113. package/lib/module/views/SkiaGraphiteView.d.ts +3 -4
  114. package/lib/module/views/SkiaGraphiteView.js +23 -12
  115. package/lib/module/views/SkiaGraphiteView.js.map +1 -1
  116. package/lib/module/views/SkiaPictureView.d.ts +4 -1
  117. package/lib/module/views/SkiaPictureView.js +12 -10
  118. package/lib/module/views/SkiaPictureView.js.map +1 -1
  119. package/lib/module/views/SkiaView.web.d.ts +12 -0
  120. package/lib/module/views/{SkiaGraphiteView.web.js → SkiaView.web.js} +80 -36
  121. package/lib/module/views/SkiaView.web.js.map +1 -0
  122. package/lib/module/views/SkiaWebRenderer.js +1 -1
  123. package/lib/module/views/SkiaWebRenderer.js.map +1 -1
  124. package/lib/module/views/android.d.ts +6 -0
  125. package/lib/module/views/android.js +10 -0
  126. package/lib/module/views/android.js.map +1 -0
  127. package/lib/module/views/types.d.ts +3 -12
  128. package/lib/module/views/types.js.map +1 -1
  129. package/lib/typescript/src/index.d.ts +1 -3
  130. package/lib/typescript/src/renderer/Canvas.d.ts +15 -12
  131. package/lib/typescript/src/skia/types/Graphite.d.ts +3 -3
  132. package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +2 -2
  133. package/lib/typescript/src/skia/types/Skia.d.ts +1 -2
  134. package/lib/typescript/src/skia/types/Surface/SurfaceFactory.d.ts +1 -1
  135. package/lib/typescript/src/specs/NativeSkiaModule.web.d.ts +5 -4
  136. package/lib/{module/specs/SkiaPictureViewNativeComponent.d.ts → typescript/src/specs/SkiaViewNativeComponent.d.ts} +0 -3
  137. package/lib/typescript/src/specs/SkiaViewNativeComponent.web.d.ts +10 -0
  138. package/lib/typescript/src/views/SkiaGraphiteView.d.ts +3 -4
  139. package/lib/typescript/src/views/SkiaPictureView.d.ts +4 -1
  140. package/lib/typescript/src/views/SkiaView.web.d.ts +12 -0
  141. package/lib/typescript/src/views/android.d.ts +6 -0
  142. package/lib/typescript/src/views/types.d.ts +3 -12
  143. package/package.json +8 -16
  144. package/react-native-skia.podspec +50 -57
  145. package/src/Platform/Platform.web.tsx +1 -1
  146. package/src/index.ts +1 -3
  147. package/src/mock/index.ts +0 -1
  148. package/src/renderer/Canvas.tsx +23 -27
  149. package/src/skia/types/Graphite.ts +3 -3
  150. package/src/skia/types/Image/ImageFactory.ts +2 -2
  151. package/src/skia/types/Skia.ts +1 -2
  152. package/src/skia/types/Surface/SurfaceFactory.ts +1 -1
  153. package/src/specs/NativeSkiaModule.web.ts +9 -21
  154. package/src/specs/{SkiaPictureViewNativeComponent.ts → SkiaViewNativeComponent.ts} +1 -4
  155. package/src/specs/{SkiaPictureViewNativeComponent.web.ts → SkiaViewNativeComponent.web.ts} +8 -10
  156. package/src/views/SkiaGraphiteView.tsx +27 -16
  157. package/src/views/SkiaPictureView.tsx +11 -10
  158. package/src/views/{SkiaGraphiteView.web.tsx → SkiaView.web.tsx} +100 -53
  159. package/src/views/SkiaWebRenderer.ts +1 -1
  160. package/src/views/android.ts +16 -0
  161. package/src/views/types.ts +3 -14
  162. package/android/cpp/jni/include/JniSkiaBaseView.h +0 -92
  163. package/android/cpp/jni/include/JniSkiaGraphiteView.h +0 -176
  164. package/android/cpp/jni/include/JniSkiaPictureView.h +0 -172
  165. package/android/cpp/rnskia-android/GrAHardwareBufferUtils.cpp +0 -245
  166. package/android/cpp/rnskia-android/GrAHardwareBufferUtils.h +0 -33
  167. package/android/cpp/rnskia-android/OpenGLContext.h +0 -248
  168. package/android/cpp/rnskia-android/OpenGLWindowContext.cpp +0 -67
  169. package/android/cpp/rnskia-android/OpenGLWindowContext.h +0 -75
  170. package/android/cpp/rnskia-android/RNSkAndroidView.h +0 -67
  171. package/android/cpp/rnskia-android/gl/Context.h +0 -80
  172. package/android/cpp/rnskia-android/gl/Display.h +0 -123
  173. package/android/cpp/rnskia-android/gl/Error.cpp +0 -45
  174. package/android/cpp/rnskia-android/gl/Error.h +0 -8
  175. package/android/cpp/rnskia-android/gl/Surface.h +0 -43
  176. package/android/src/main/java/com/reactnative/skia/SkiaBaseViewManager.java +0 -65
  177. package/android/src/main/java/com/reactnative/skia/SkiaGraphiteView.java +0 -78
  178. package/android/src/main/java/com/reactnative/skia/SkiaGraphiteViewManager.java +0 -32
  179. package/android/src/main/java/com/reactnative/skia/SkiaPictureView.java +0 -105
  180. package/android/src/main/java/com/reactnative/skia/SkiaPictureViewManager.java +0 -44
  181. package/apple/MetalContext.h +0 -116
  182. package/apple/MetalContext.mm +0 -38
  183. package/apple/MetalWindowContext.h +0 -42
  184. package/apple/MetalWindowContext.mm +0 -95
  185. package/apple/RNSkAppleView.h +0 -49
  186. package/apple/RNSkAppleView.mm +0 -35
  187. package/apple/SkiaCVPixelBufferUtils.h +0 -122
  188. package/apple/SkiaCVPixelBufferUtils.mm +0 -535
  189. package/apple/SkiaGraphiteView.h +0 -26
  190. package/apple/SkiaGraphiteView.mm +0 -180
  191. package/apple/SkiaPictureView.h +0 -7
  192. package/apple/SkiaPictureView.mm +0 -70
  193. package/apple/SkiaUIView.h +0 -31
  194. package/apple/SkiaUIView.mm +0 -164
  195. package/cpp/rnskia/RNSkGraphiteView.h +0 -708
  196. package/cpp/rnskia/RNSkPictureView.cpp +0 -69
  197. package/cpp/rnskia/RNSkPictureView.h +0 -211
  198. package/cpp/skia/src/gpu/ganesh/gl/GrGLDefines.h +0 -1162
  199. package/lib/commonjs/renderer/DefaultCanvas.d.ts +0 -8
  200. package/lib/commonjs/renderer/DefaultCanvas.js +0 -42
  201. package/lib/commonjs/renderer/DefaultCanvas.js.map +0 -1
  202. package/lib/commonjs/renderer/GraphiteCanvas.d.ts +0 -22
  203. package/lib/commonjs/renderer/GraphiteCanvas.js +0 -64
  204. package/lib/commonjs/renderer/GraphiteCanvas.js.map +0 -1
  205. package/lib/commonjs/renderer/GraphiteCanvas.web.d.ts +0 -1
  206. package/lib/commonjs/renderer/GraphiteCanvas.web.js +0 -13
  207. package/lib/commonjs/renderer/GraphiteCanvas.web.js.map +0 -1
  208. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.d.ts +0 -10
  209. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.js +0 -12
  210. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.js.map +0 -1
  211. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.web.d.ts +0 -9
  212. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.web.js +0 -28
  213. package/lib/commonjs/specs/SkiaGraphiteViewNativeComponent.web.js.map +0 -1
  214. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +0 -1
  215. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +0 -10
  216. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js +0 -29
  217. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js.map +0 -1
  218. package/lib/commonjs/views/SkiaGraphiteView.web.d.ts +0 -14
  219. package/lib/commonjs/views/SkiaGraphiteView.web.js.map +0 -1
  220. package/lib/commonjs/views/SkiaPictureView.web.d.ts +0 -11
  221. package/lib/commonjs/views/SkiaPictureView.web.js +0 -165
  222. package/lib/commonjs/views/SkiaPictureView.web.js.map +0 -1
  223. package/lib/module/renderer/DefaultCanvas.d.ts +0 -8
  224. package/lib/module/renderer/DefaultCanvas.js +0 -34
  225. package/lib/module/renderer/DefaultCanvas.js.map +0 -1
  226. package/lib/module/renderer/GraphiteCanvas.d.ts +0 -22
  227. package/lib/module/renderer/GraphiteCanvas.js +0 -57
  228. package/lib/module/renderer/GraphiteCanvas.js.map +0 -1
  229. package/lib/module/renderer/GraphiteCanvas.web.d.ts +0 -1
  230. package/lib/module/renderer/GraphiteCanvas.web.js +0 -4
  231. package/lib/module/renderer/GraphiteCanvas.web.js.map +0 -1
  232. package/lib/module/specs/SkiaGraphiteViewNativeComponent.d.ts +0 -10
  233. package/lib/module/specs/SkiaGraphiteViewNativeComponent.js +0 -8
  234. package/lib/module/specs/SkiaGraphiteViewNativeComponent.js.map +0 -1
  235. package/lib/module/specs/SkiaGraphiteViewNativeComponent.web.d.ts +0 -9
  236. package/lib/module/specs/SkiaGraphiteViewNativeComponent.web.js +0 -22
  237. package/lib/module/specs/SkiaGraphiteViewNativeComponent.web.js.map +0 -1
  238. package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +0 -1
  239. package/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +0 -10
  240. package/lib/module/specs/SkiaPictureViewNativeComponent.web.js +0 -23
  241. package/lib/module/specs/SkiaPictureViewNativeComponent.web.js.map +0 -1
  242. package/lib/module/views/SkiaGraphiteView.web.d.ts +0 -14
  243. package/lib/module/views/SkiaGraphiteView.web.js.map +0 -1
  244. package/lib/module/views/SkiaPictureView.web.d.ts +0 -11
  245. package/lib/module/views/SkiaPictureView.web.js +0 -156
  246. package/lib/module/views/SkiaPictureView.web.js.map +0 -1
  247. package/lib/typescript/src/renderer/DefaultCanvas.d.ts +0 -8
  248. package/lib/typescript/src/renderer/GraphiteCanvas.d.ts +0 -22
  249. package/lib/typescript/src/renderer/GraphiteCanvas.web.d.ts +0 -1
  250. package/lib/typescript/src/specs/SkiaGraphiteViewNativeComponent.d.ts +0 -10
  251. package/lib/typescript/src/specs/SkiaGraphiteViewNativeComponent.web.d.ts +0 -9
  252. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.web.d.ts +0 -10
  253. package/lib/typescript/src/views/SkiaGraphiteView.web.d.ts +0 -14
  254. package/lib/typescript/src/views/SkiaPictureView.web.d.ts +0 -11
  255. package/libs/.graphite +0 -1
  256. package/src/renderer/DefaultCanvas.tsx +0 -41
  257. package/src/renderer/GraphiteCanvas.tsx +0 -61
  258. package/src/renderer/GraphiteCanvas.web.tsx +0 -3
  259. package/src/specs/SkiaGraphiteViewNativeComponent.ts +0 -17
  260. package/src/specs/SkiaGraphiteViewNativeComponent.web.ts +0 -31
  261. package/src/views/SkiaPictureView.web.tsx +0 -224
@@ -6,6 +6,7 @@ import React, {
6
6
  useMemo,
7
7
  useRef,
8
8
  } from "react";
9
+ import type { ViewProps } from "react-native";
9
10
 
10
11
  import type {
11
12
  SkCanvas,
@@ -19,31 +20,30 @@ import { JsiSkPictureRecorder } from "../skia/web/JsiSkPictureRecorder";
19
20
  import { Platform } from "../Platform";
20
21
  import type {
21
22
  ISkiaViewApiWeb,
22
- SkiaGraphiteViewHandle,
23
+ SkiaWebViewHandle,
23
24
  } from "../specs/NativeSkiaModule.web";
24
25
 
25
- import type { SkiaGraphiteViewNativeProps } from "./types";
26
26
  import { SkiaViewNativeId } from "./SkiaViewNativeId";
27
27
  import { useSkiaWebRenderer } from "./SkiaWebRenderer";
28
- import type { Renderer } from "./SkiaWebRenderer";
29
-
30
- // The web has no Graphite: a recording is an SkPicture, replayed onto the
31
- // view's WebGL surface by the same renderer as SkiaPictureView (with its
32
- // context-loss handling and the destroy-context-after-render mode). Frames
33
- // keep their native semantics, presented in submission order and never
34
- // dropped, with one difference: the surface starts cleared on every frame,
35
- // so a recording draws the whole frame rather than a delta.
36
-
37
- export interface SkiaGraphiteViewRef {
38
- /**
39
- * The recording side of the view. Call it once the view is mounted.
40
- */
41
- getContext(): SkGraphiteContext;
42
- getNativeId(): number;
28
+ import type { Renderer, WebFrame } from "./SkiaWebRenderer";
29
+
30
+ // The web has no Graphite: the view paints pictures on a WebGL canvas (with
31
+ // context-loss recovery and the destroy-context-after-render mode). It shows
32
+ // one of two kinds of content. The picture of a <Canvas> or a
33
+ // <SkiaPictureView> is a whole frame: the latest one wins. The recordings
34
+ // submitted through the view's context (SkiaGraphiteView) keep their native
35
+ // semantics, presented in submission order and never dropped, with one
36
+ // difference: the surface starts cleared on every frame, so a recording draws
37
+ // the whole frame rather than a delta.
38
+
39
+ export interface SkiaViewHandle extends SkiaWebViewHandle {
40
+ /** The canvas element, for Reanimated's measure(). */
41
+ readonly canvasRef: () => HTMLCanvasElement | null;
43
42
  }
44
43
 
45
- export interface SkiaGraphiteViewProps extends SkiaGraphiteViewNativeProps {
46
- ref?: React.Ref<SkiaGraphiteViewRef>;
44
+ export interface SkiaViewProps extends ViewProps {
45
+ ref?: React.Ref<SkiaViewHandle>;
46
+ __destroyWebGLContextAfterRender?: boolean;
47
47
  }
48
48
 
49
49
  /**
@@ -146,9 +146,11 @@ class WebGraphiteContext implements SkGraphiteContext {
146
146
  [Symbol.dispose]() {}
147
147
  }
148
148
 
149
- export const SkiaGraphiteView = (props: SkiaGraphiteViewProps) => {
149
+ export const SkiaView = (props: SkiaViewProps) => {
150
150
  const { ref, onLayout } = props;
151
151
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
152
+ // The picture of a <Canvas> or a <SkiaPictureView>: a whole frame.
153
+ const pictureRef = useRef<SkPicture | null>(null);
152
154
  // Recordings submitted since the last frame, in order, and the frame on
153
155
  // screen, replayed when the surface is recreated.
154
156
  const queueRef = useRef<WebGraphiteRecording[]>([]);
@@ -164,9 +166,9 @@ export const SkiaGraphiteView = (props: SkiaGraphiteViewProps) => {
164
166
 
165
167
  const isStatic = props.__destroyWebGLContextAfterRender === true;
166
168
 
167
- // Presents what was submitted since the last frame. A frame that cannot be
168
- // painted yet (unmeasured canvas, lost context) stays queued for the next
169
- // opportunity.
169
+ // Presents the recordings submitted since the last frame. A frame that
170
+ // cannot be painted yet (unmeasured canvas, lost context) stays queued for
171
+ // the next opportunity.
170
172
  const present = useCallback((renderer: Renderer) => {
171
173
  const frame = queueRef.current;
172
174
  if (frame.length === 0) {
@@ -182,10 +184,14 @@ export const SkiaGraphiteView = (props: SkiaGraphiteViewProps) => {
182
184
  previous.forEach((recording) => recording.release());
183
185
  }, []);
184
186
 
187
+ // Paints what the view holds: pending recordings first, else the picture,
188
+ // else the frame on screen again (the surface was recreated).
185
189
  const paint = useCallback(
186
190
  (renderer: Renderer) => {
187
191
  if (queueRef.current.length > 0) {
188
192
  present(renderer);
193
+ } else if (pictureRef.current) {
194
+ renderer.draw([pictureRef.current]);
189
195
  } else if (shownRef.current.length > 0) {
190
196
  renderer.draw(shownRef.current.map((recording) => recording.picture));
191
197
  }
@@ -197,27 +203,44 @@ export const SkiaGraphiteView = (props: SkiaGraphiteViewProps) => {
197
203
  onLayout,
198
204
  });
199
205
 
206
+ // Draws are flushed from a microtask rather than an animation frame: the
207
+ // browser composites once per frame either way, and painting right away
208
+ // keeps a frame produced inside an animation callback (the Reanimated
209
+ // mapper, a frame loop) from slipping to the next one. Deferring to the
210
+ // next animation frame would alternate between "flush pending in this
211
+ // frame" and "flush scheduled for the next frame", halving the effective
212
+ // frame rate. Without a renderer yet (an unmeasured canvas), the content
213
+ // stays held and is painted by the renderer once it exists, so it is
214
+ // never lost.
200
215
  const flush = useCallback(() => {
201
216
  flushScheduledRef.current = false;
202
217
  if (rendererRef.current) {
203
- present(rendererRef.current);
218
+ paint(rendererRef.current);
219
+ }
220
+ }, [paint, rendererRef]);
221
+
222
+ const redraw = useCallback(() => {
223
+ if (!flushScheduledRef.current) {
224
+ flushScheduledRef.current = true;
225
+ queueMicrotask(flush);
204
226
  }
205
- }, [present, rendererRef]);
227
+ }, [flush]);
228
+
229
+ const setPicture = useCallback(
230
+ (picture: SkPicture) => {
231
+ pictureRef.current = picture;
232
+ redraw();
233
+ },
234
+ [redraw]
235
+ );
206
236
 
207
- // Frames are presented from a microtask rather than an animation frame:
208
- // the browser composites once per frame either way, and painting right
209
- // away keeps a frame recorded inside an animation callback from slipping
210
- // to the next one (see SkiaPictureView.web).
211
237
  const submit = useCallback(
212
238
  (recording: WebGraphiteRecording) => {
213
239
  recording.retain();
214
240
  queueRef.current.push(recording);
215
- if (!flushScheduledRef.current) {
216
- flushScheduledRef.current = true;
217
- queueMicrotask(flush);
218
- }
241
+ redraw();
219
242
  },
220
- [flush]
243
+ [redraw]
221
244
  );
222
245
 
223
246
  const getSize = useCallback(
@@ -233,23 +256,24 @@ export const SkiaGraphiteView = (props: SkiaGraphiteViewProps) => {
233
256
  [getSize, submit]
234
257
  );
235
258
 
236
- const redraw = useCallback(() => {
237
- if (rendererRef.current) {
238
- paint(rendererRef.current);
239
- }
240
- }, [paint, rendererRef]);
241
-
242
259
  const makeImageSnapshot = useCallback(
243
260
  (rect?: SkRect): SkImage | null => {
244
- const frame =
245
- queueRef.current.length > 0 ? queueRef.current : shownRef.current;
246
- if (!rendererRef.current || frame.length === 0) {
261
+ const renderer = rendererRef.current;
262
+ if (!renderer) {
247
263
  return null;
248
264
  }
249
- return rendererRef.current.makeImageSnapshot(
250
- frame.map((recording) => recording.picture),
251
- rect
252
- );
265
+ let frame: WebFrame;
266
+ if (queueRef.current.length > 0) {
267
+ frame = queueRef.current.map((recording) => recording.picture);
268
+ } else if (pictureRef.current) {
269
+ frame = [pictureRef.current];
270
+ } else {
271
+ frame = shownRef.current.map((recording) => recording.picture);
272
+ }
273
+ if (frame.length === 0) {
274
+ return null;
275
+ }
276
+ return renderer.makeImageSnapshot(frame, rect);
253
277
  },
254
278
  [rendererRef]
255
279
  );
@@ -273,10 +297,12 @@ export const SkiaGraphiteView = (props: SkiaGraphiteViewProps) => {
273
297
  top: 0,
274
298
  };
275
299
  callback(
300
+ // x, y are relative to the parent
276
301
  rect.left - parentRect.left,
277
302
  rect.top - parentRect.top,
278
303
  rect.width,
279
304
  rect.height,
305
+ // pageX, pageY are absolute screen coordinates
280
306
  rect.left + window.scrollX,
281
307
  rect.top + window.scrollY
282
308
  );
@@ -297,29 +323,53 @@ export const SkiaGraphiteView = (props: SkiaGraphiteViewProps) => {
297
323
  []
298
324
  );
299
325
 
326
+ // No flush cancellation is needed on unmount: a microtask queued before
327
+ // unmount runs within the same task, and flush no-ops once the
328
+ // layout-effect cleanup has nulled rendererRef.
329
+
300
330
  useImperativeHandle(
301
331
  ref,
302
332
  () => ({
333
+ setPicture,
303
334
  getContext,
304
- getNativeId: () => nativeId,
335
+ getSize,
336
+ redraw,
337
+ makeImageSnapshot,
338
+ measure,
339
+ measureInWindow,
340
+ get canvasRef() {
341
+ return () => canvasRef.current;
342
+ },
305
343
  }),
306
- [getContext, nativeId]
344
+ [
345
+ setPicture,
346
+ getContext,
347
+ getSize,
348
+ redraw,
349
+ makeImageSnapshot,
350
+ measure,
351
+ measureInWindow,
352
+ ]
307
353
  );
308
354
 
309
355
  useEffect(() => {
310
356
  const api = global.SkiaViewApi as ISkiaViewApiWeb;
311
357
  api.registerView(`${nativeId}`, {
358
+ setPicture,
312
359
  getContext,
313
360
  getSize,
314
361
  redraw,
315
362
  makeImageSnapshot,
316
363
  measure,
317
364
  measureInWindow,
318
- } as SkiaGraphiteViewHandle);
365
+ });
319
366
  return () => {
367
+ // Views must be removed on unmount: the handle's closures capture the
368
+ // canvas element, so a stale entry retains the whole detached DOM tree.
320
369
  api.unregisterView(`${nativeId}`);
321
370
  };
322
371
  }, [
372
+ setPicture,
323
373
  getContext,
324
374
  getSize,
325
375
  redraw,
@@ -341,9 +391,6 @@ export const SkiaGraphiteView = (props: SkiaGraphiteViewProps) => {
341
391
  );
342
392
 
343
393
  const {
344
- debug: _debug,
345
- opaque: _opaque,
346
- highBitDepth: _highBitDepth,
347
394
  ref: _ref,
348
395
  onLayout: _onLayout,
349
396
  nativeID: _nativeID,
@@ -7,7 +7,7 @@ import type { GrDirectContext, WebGLContextHandle } from "canvaskit-wasm";
7
7
  import type { SkRect, SkPicture, SkImage } from "../skia/types";
8
8
  import { JsiSkSurface } from "../skia/web/JsiSkSurface";
9
9
 
10
- // The WebGL renderers behind the web views (SkiaPictureView, SkiaGraphiteView):
10
+ // The WebGL renderers behind the web view (SkiaView.web):
11
11
  // a <canvas> element, its WebGL context and the CanvasKit surface built on
12
12
  // it, with the context-loss handling and the "destroy the context after each
13
13
  // draw" mode that keeps a page under the browser's live-context limit.
@@ -0,0 +1,16 @@
1
+ import type { AndroidCanvasProps, AndroidSurfaceType } from "./types";
2
+
3
+ // Anything else reaching the native component would hit the generated
4
+ // string-enum parser, which aborts on unknown values.
5
+ const resolveSurfaceType = (
6
+ surfaceType: AndroidSurfaceType | undefined
7
+ ): "auto" | AndroidSurfaceType =>
8
+ surfaceType === "SurfaceView" || surfaceType === "TextureView"
9
+ ? surfaceType
10
+ : "auto";
11
+
12
+ /** The native props the `android` prop of a view resolves to. */
13
+ export const androidNativeProps = (android?: AndroidCanvasProps) => ({
14
+ androidSurfaceType: resolveSurfaceType(android?.surfaceType),
15
+ androidZOrderOnTop: !!android?.zOrderOnTop,
16
+ });
@@ -9,11 +9,6 @@ import type {
9
9
  SkSize,
10
10
  } from "../skia/types";
11
11
 
12
- export type NativeSkiaViewProps = ViewProps & {
13
- debug?: boolean;
14
- opaque?: boolean;
15
- };
16
-
17
12
  export type AndroidSurfaceType = "SurfaceView" | "TextureView";
18
13
 
19
14
  export interface AndroidCanvasProps {
@@ -50,8 +45,8 @@ export interface ISkiaViewApi {
50
45
  makeImageSnapshotAsync: (nativeId: number, rect?: SkRect) => Promise<SkImage>;
51
46
  size: (nativeId: number) => SkSize;
52
47
  /**
53
- * The recording side of a SkiaGraphiteView: its native id, the layout size
54
- * in points, and the props its surface format follows from. Graphite only.
48
+ * The recording side of a view: its native id, the layout size in points,
49
+ * and the props its surface format follows from.
55
50
  */
56
51
  makeGraphiteContext: (
57
52
  nativeId: number,
@@ -62,13 +57,8 @@ export interface ISkiaViewApi {
62
57
  ) => SkGraphiteContext;
63
58
  }
64
59
 
60
+ /** The props every Skia view takes, whichever way it is drawn. */
65
61
  export interface SkiaBaseViewProps extends ViewProps {
66
- /**
67
- * When set to true the view will display information about the
68
- * average time it takes to render.
69
- */
70
- debug?: boolean;
71
-
72
62
  /**
73
63
  * Declares that the canvas covers every pixel of its bounds. On Android an
74
64
  * opaque canvas is backed by a `SurfaceView` by default, the cheapest path
@@ -93,7 +83,6 @@ export interface SkiaBaseViewProps extends ViewProps {
93
83
 
94
84
  export interface SkiaPictureViewNativeProps extends SkiaBaseViewProps {
95
85
  picture?: SkPicture;
96
- androidWarmup?: boolean;
97
86
  }
98
87
 
99
88
  export type SkiaGraphiteViewNativeProps = SkiaBaseViewProps;
@@ -1,92 +0,0 @@
1
- #pragma once
2
-
3
- #include <memory>
4
- #include <string>
5
- #include <vector>
6
-
7
- #include <fbjni/fbjni.h>
8
- #include <jni.h>
9
- #include <jsi/jsi.h>
10
-
11
- #include "JniSkiaManager.h"
12
- #include "RNSkAndroidView.h"
13
-
14
- #include <android/bitmap.h>
15
-
16
- namespace RNSkia {
17
-
18
- namespace jsi = facebook::jsi;
19
-
20
- class JniSkiaBaseView {
21
- public:
22
- JniSkiaBaseView(jni::alias_ref<JniSkiaManager::javaobject> skiaManager,
23
- std::shared_ptr<RNSkBaseAndroidView> skiaView)
24
- : _skiaAndroidView(std::move(skiaView)),
25
- _manager(skiaManager->cthis()->getSkiaManager()) {}
26
-
27
- ~JniSkiaBaseView() = default;
28
-
29
- // The manager is owned by the RNSkiaModule and is destroyed when the module
30
- // is invalidated (reload). Fabric drops views on the UI thread while the
31
- // module is invalidated on a background thread, so a view can outlive its
32
- // manager: holding a weak reference makes a late unregister a no-op and a
33
- // concurrent one keep the manager alive for the duration of the call.
34
- std::shared_ptr<RNSkManager> getSkiaManager() { return _manager.lock(); }
35
-
36
- protected:
37
- virtual void surfaceAvailable(jobject surface, int width, int height,
38
- bool isSurface, bool highBitDepth) {
39
- _skiaAndroidView->surfaceAvailable(surface, width, height, isSurface,
40
- highBitDepth);
41
- }
42
-
43
- virtual void surfaceSizeChanged(jobject surface, int width, int height,
44
- bool isSurface, bool highBitDepth) {
45
- _skiaAndroidView->surfaceSizeChanged(surface, width, height, isSurface,
46
- highBitDepth);
47
- }
48
-
49
- virtual void surfaceDestroyed() { _skiaAndroidView->surfaceDestroyed(); }
50
-
51
- virtual void setDebugMode(bool show) {
52
- _skiaAndroidView->setShowDebugInfo(show);
53
- }
54
-
55
- virtual void registerView(int nativeId) {
56
- auto manager = getSkiaManager();
57
- if (manager == nullptr) {
58
- return;
59
- }
60
- manager->registerSkiaView(nativeId, _skiaAndroidView->getSkiaView());
61
- }
62
-
63
- virtual void unregisterView() {
64
- if (_skiaAndroidView == nullptr) {
65
- return;
66
- }
67
- auto skiaView = _skiaAndroidView->getSkiaView();
68
- if (skiaView == nullptr) {
69
- return;
70
- }
71
- if (auto manager = getSkiaManager()) {
72
- manager->setSkiaView(skiaView->getNativeId(), nullptr);
73
- manager->unregisterSkiaView(skiaView->getNativeId());
74
- }
75
- // React drops the Java view here, but the native view behind it (and the
76
- // content it owns) is only destroyed when the Java object is finalized.
77
- // Release the content now so it does not wait for the garbage collector.
78
- skiaView->releaseContent();
79
- }
80
-
81
- virtual jni::local_ref<jni::JArrayInt> getBitmap(int width, int height) {
82
- return jni::JArrayInt::newArray(0);
83
- }
84
-
85
- protected:
86
- std::shared_ptr<RNSkBaseAndroidView> _skiaAndroidView;
87
-
88
- private:
89
- std::weak_ptr<RNSkManager> _manager;
90
- };
91
-
92
- } // namespace RNSkia
@@ -1,176 +0,0 @@
1
- #pragma once
2
-
3
- #include <memory>
4
-
5
- #include <fbjni/fbjni.h>
6
- #include <jni.h>
7
-
8
- #include "JniSkiaManager.h"
9
- #include "RNSkLog.h"
10
-
11
- #if defined(SK_GRAPHITE)
12
- #include "JniSkiaBaseView.h"
13
- #include "RNSkAndroidView.h"
14
- #include "RNSkGraphiteView.h"
15
- #endif
16
-
17
- namespace RNSkia {
18
- namespace jni = facebook::jni;
19
-
20
- #if defined(SK_GRAPHITE)
21
-
22
- /**
23
- * The Android side of SkiaGraphiteView: a SkiaBaseView whose frames are
24
- * Graphite recordings, presented on the Choreographer.
25
- */
26
- class JniSkiaGraphiteView : public jni::HybridClass<JniSkiaGraphiteView>,
27
- public JniSkiaBaseView {
28
- public:
29
- static auto constexpr kJavaDescriptor =
30
- "Lcom/reactnative/skia/SkiaGraphiteView;";
31
-
32
- static jni::local_ref<jhybriddata>
33
- initHybrid(jni::alias_ref<jhybridobject> jThis,
34
- jni::alias_ref<JniSkiaManager::javaobject> skiaManager) {
35
- return makeCxxInstance(jThis, skiaManager);
36
- }
37
-
38
- static void registerNatives() {
39
- registerHybrid(
40
- {makeNativeMethod("initHybrid", JniSkiaGraphiteView::initHybrid),
41
- makeNativeMethod("surfaceAvailable",
42
- JniSkiaGraphiteView::surfaceAvailable),
43
- makeNativeMethod("surfaceDestroyed",
44
- JniSkiaGraphiteView::surfaceDestroyed),
45
- makeNativeMethod("surfaceSizeChanged",
46
- JniSkiaGraphiteView::surfaceSizeChanged),
47
- makeNativeMethod("setDebugMode", JniSkiaGraphiteView::setDebugMode),
48
- makeNativeMethod("registerView", JniSkiaGraphiteView::registerView),
49
- makeNativeMethod("unregisterView",
50
- JniSkiaGraphiteView::unregisterView),
51
- makeNativeMethod("getBitmap", JniSkiaGraphiteView::getBitmap),
52
- makeNativeMethod("presentFrame", JniSkiaGraphiteView::presentFrame)});
53
- }
54
-
55
- protected:
56
- void surfaceAvailable(jobject surface, int width, int height, bool isSurface,
57
- bool highBitDepth) override {
58
- JniSkiaBaseView::surfaceAvailable(surface, width, height, isSurface,
59
- highBitDepth);
60
- }
61
-
62
- void surfaceSizeChanged(jobject surface, int width, int height,
63
- bool isSurface, bool highBitDepth) override {
64
- JniSkiaBaseView::surfaceSizeChanged(surface, width, height, isSurface,
65
- highBitDepth);
66
- }
67
-
68
- void surfaceDestroyed() override { JniSkiaBaseView::surfaceDestroyed(); }
69
-
70
- void setDebugMode(bool show) override { JniSkiaBaseView::setDebugMode(show); }
71
-
72
- void registerView(int nativeId) override {
73
- JniSkiaBaseView::registerView(nativeId);
74
- }
75
-
76
- void unregisterView() override { JniSkiaBaseView::unregisterView(); }
77
-
78
- jni::local_ref<jni::JArrayInt> getBitmap(int width, int height) override {
79
- return JniSkiaBaseView::getBitmap(width, height);
80
- }
81
-
82
- // Choreographer tick: presents the queued recordings, returns whether more
83
- // are already waiting.
84
- bool presentFrame() { return getGraphiteView()->presentFrame(); }
85
-
86
- private:
87
- friend HybridBase;
88
-
89
- explicit JniSkiaGraphiteView(
90
- jni::alias_ref<jhybridobject> jThis,
91
- jni::alias_ref<JniSkiaManager::javaobject> skiaManager)
92
- : JniSkiaBaseView(
93
- skiaManager,
94
- std::make_shared<RNSkAndroidView<RNSkia::RNSkGraphiteView>>(
95
- skiaManager->cthis()->getPlatformContext())) {
96
- // A submitted recording arms the Java view's frame callback. Weak: the
97
- // Java view owns this object through its hybrid data.
98
- jni::weak_ref<jhybridobject> weakJava = jni::make_weak(jThis);
99
- getGraphiteView()->setFrameScheduler([weakJava]() {
100
- auto javaPart = weakJava.lockLocal();
101
- if (!javaPart) {
102
- return;
103
- }
104
- static const auto method =
105
- javaPart->getClass()->getMethod<void()>("scheduleFrame");
106
- method(javaPart);
107
- });
108
- }
109
-
110
- std::shared_ptr<RNSkAndroidView<RNSkia::RNSkGraphiteView>> getGraphiteView() {
111
- return std::static_pointer_cast<RNSkAndroidView<RNSkia::RNSkGraphiteView>>(
112
- _skiaAndroidView);
113
- }
114
- };
115
-
116
- #else // SK_GRAPHITE
117
-
118
- /**
119
- * Placeholder for builds without the Graphite backend: the component exists
120
- * so that the app links, but it renders nothing.
121
- */
122
- class JniSkiaGraphiteView : public jni::HybridClass<JniSkiaGraphiteView> {
123
- public:
124
- static auto constexpr kJavaDescriptor =
125
- "Lcom/reactnative/skia/SkiaGraphiteView;";
126
-
127
- static jni::local_ref<jhybriddata>
128
- initHybrid(jni::alias_ref<jhybridobject> jThis,
129
- jni::alias_ref<JniSkiaManager::javaobject> skiaManager) {
130
- static bool warned = false;
131
- if (!warned) {
132
- warned = true;
133
- RNSkLogger::logToConsole(
134
- "SkiaGraphiteView requires the Graphite backend. Rebuild with "
135
- "SK_GRAPHITE enabled; the view renders nothing.");
136
- }
137
- return makeCxxInstance();
138
- }
139
-
140
- static void registerNatives() {
141
- registerHybrid(
142
- {makeNativeMethod("initHybrid", JniSkiaGraphiteView::initHybrid),
143
- makeNativeMethod("surfaceAvailable",
144
- JniSkiaGraphiteView::surfaceAvailable),
145
- makeNativeMethod("surfaceDestroyed",
146
- JniSkiaGraphiteView::surfaceDestroyed),
147
- makeNativeMethod("surfaceSizeChanged",
148
- JniSkiaGraphiteView::surfaceSizeChanged),
149
- makeNativeMethod("setDebugMode", JniSkiaGraphiteView::setDebugMode),
150
- makeNativeMethod("registerView", JniSkiaGraphiteView::registerView),
151
- makeNativeMethod("unregisterView",
152
- JniSkiaGraphiteView::unregisterView),
153
- makeNativeMethod("getBitmap", JniSkiaGraphiteView::getBitmap),
154
- makeNativeMethod("presentFrame", JniSkiaGraphiteView::presentFrame)});
155
- }
156
-
157
- protected:
158
- void surfaceAvailable(jobject, int, int, bool, bool) {}
159
- void surfaceSizeChanged(jobject, int, int, bool, bool) {}
160
- void surfaceDestroyed() {}
161
- void setDebugMode(bool) {}
162
- void registerView(int) {}
163
- void unregisterView() {}
164
- jni::local_ref<jni::JArrayInt> getBitmap(int, int) {
165
- return jni::JArrayInt::newArray(0);
166
- }
167
- bool presentFrame() { return false; }
168
-
169
- private:
170
- friend HybridBase;
171
- JniSkiaGraphiteView() = default;
172
- };
173
-
174
- #endif // SK_GRAPHITE
175
-
176
- } // namespace RNSkia