@shopify/react-native-skia 2.3.8 → 2.3.10

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 (102) hide show
  1. package/cpp/api/JsiNativeBuffer.h +4 -0
  2. package/cpp/api/JsiSkAnimatedImage.h +70 -1
  3. package/cpp/api/JsiSkAnimatedImageFactory.h +4 -0
  4. package/cpp/api/JsiSkApi.h +2 -0
  5. package/cpp/api/JsiSkCanvas.h +2 -0
  6. package/cpp/api/JsiSkColorFilter.h +2 -0
  7. package/cpp/api/JsiSkColorFilterFactory.h +4 -0
  8. package/cpp/api/JsiSkContourMeasure.h +2 -0
  9. package/cpp/api/JsiSkContourMeasureIter.h +4 -0
  10. package/cpp/api/JsiSkData.h +2 -0
  11. package/cpp/api/JsiSkDataFactory.h +2 -0
  12. package/cpp/api/JsiSkFont.h +2 -0
  13. package/cpp/api/JsiSkFontMgr.h +2 -0
  14. package/cpp/api/JsiSkFontMgrFactory.h +2 -0
  15. package/cpp/api/JsiSkFontStyle.h +2 -0
  16. package/cpp/api/JsiSkHostObjects.h +50 -0
  17. package/cpp/api/JsiSkImage.h +3 -1
  18. package/cpp/api/JsiSkImageFactory.h +2 -0
  19. package/cpp/api/JsiSkImageFilter.h +3 -1
  20. package/cpp/api/JsiSkImageFilterFactory.h +4 -0
  21. package/cpp/api/JsiSkImageInfo.h +2 -0
  22. package/cpp/api/JsiSkMaskFilter.h +2 -0
  23. package/cpp/api/JsiSkMaskFilterFactory.h +4 -0
  24. package/cpp/api/JsiSkMatrix.h +2 -0
  25. package/cpp/api/JsiSkPaint.h +2 -0
  26. package/cpp/api/JsiSkParagraph.h +3 -1
  27. package/cpp/api/JsiSkParagraphBuilder.h +3 -1
  28. package/cpp/api/JsiSkParagraphBuilderFactory.h +5 -1
  29. package/cpp/api/JsiSkPath.h +2 -0
  30. package/cpp/api/JsiSkPathEffect.h +2 -0
  31. package/cpp/api/JsiSkPathEffectFactory.h +4 -0
  32. package/cpp/api/JsiSkPathFactory.h +2 -0
  33. package/cpp/api/JsiSkPicture.h +2 -0
  34. package/cpp/api/JsiSkPictureFactory.h +10 -0
  35. package/cpp/api/JsiSkPictureRecorder.h +3 -3
  36. package/cpp/api/JsiSkPoint.h +2 -0
  37. package/cpp/api/JsiSkRRect.h +2 -0
  38. package/cpp/api/JsiSkRSXform.h +2 -0
  39. package/cpp/api/JsiSkRect.h +2 -0
  40. package/cpp/api/JsiSkRuntimeEffect.h +2 -0
  41. package/cpp/api/JsiSkRuntimeEffectFactory.h +4 -0
  42. package/cpp/api/JsiSkRuntimeShaderBuilder.h +4 -0
  43. package/cpp/api/JsiSkSVG.h +2 -0
  44. package/cpp/api/JsiSkSVGFactory.h +2 -0
  45. package/cpp/api/JsiSkShader.h +3 -1
  46. package/cpp/api/JsiSkShaderFactory.h +2 -0
  47. package/cpp/api/JsiSkSkottie.h +2 -0
  48. package/cpp/api/JsiSkSurface.h +51 -7
  49. package/cpp/api/JsiSkSurfaceFactory.h +2 -0
  50. package/cpp/api/JsiSkTextBlob.h +2 -0
  51. package/cpp/api/JsiSkTextBlobFactory.h +2 -0
  52. package/cpp/api/JsiSkTypeface.h +2 -0
  53. package/cpp/api/JsiSkTypefaceFactory.h +2 -0
  54. package/cpp/api/JsiSkTypefaceFontProvider.h +4 -0
  55. package/cpp/api/JsiSkTypefaceFontProviderFactory.h +4 -0
  56. package/cpp/api/JsiSkVertices.h +2 -0
  57. package/cpp/api/JsiSkiaContext.h +3 -1
  58. package/cpp/api/JsiSkottieFactory.h +2 -0
  59. package/cpp/api/JsiVideo.h +2 -0
  60. package/cpp/api/recorder/JsiRecorder.h +42 -7
  61. package/cpp/jsi/ViewProperty.h +3 -39
  62. package/cpp/rnskia/RNSkJsiViewApi.h +0 -5
  63. package/cpp/rnskia/RNSkPictureView.h +1 -24
  64. package/cpp/rnskia/RNSkView.h +0 -7
  65. package/lib/commonjs/renderer/Canvas.js +19 -14
  66. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  67. package/lib/commonjs/skia/types/Picture/PictureFactory.d.ts +1 -1
  68. package/lib/commonjs/skia/types/Picture/PictureFactory.js.map +1 -1
  69. package/lib/commonjs/skia/types/Recorder.d.ts +2 -1
  70. package/lib/commonjs/skia/types/Recorder.js.map +1 -1
  71. package/lib/commonjs/sksg/Container.native.d.ts +4 -0
  72. package/lib/commonjs/sksg/Container.native.js +18 -6
  73. package/lib/commonjs/sksg/Container.native.js.map +1 -1
  74. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.d.ts +1 -0
  75. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.js +4 -0
  76. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.js.map +1 -1
  77. package/lib/module/renderer/Canvas.js +19 -14
  78. package/lib/module/renderer/Canvas.js.map +1 -1
  79. package/lib/module/skia/types/Picture/PictureFactory.d.ts +1 -1
  80. package/lib/module/skia/types/Picture/PictureFactory.js.map +1 -1
  81. package/lib/module/skia/types/Recorder.d.ts +2 -1
  82. package/lib/module/skia/types/Recorder.js.map +1 -1
  83. package/lib/module/sksg/Container.native.d.ts +4 -0
  84. package/lib/module/sksg/Container.native.js +18 -6
  85. package/lib/module/sksg/Container.native.js.map +1 -1
  86. package/lib/module/sksg/Recorder/ReanimatedRecorder.d.ts +1 -0
  87. package/lib/module/sksg/Recorder/ReanimatedRecorder.js +4 -0
  88. package/lib/module/sksg/Recorder/ReanimatedRecorder.js.map +1 -1
  89. package/lib/typescript/lib/commonjs/sksg/Container.native.d.ts +5 -0
  90. package/lib/typescript/lib/commonjs/sksg/Recorder/ReanimatedRecorder.d.ts +1 -0
  91. package/lib/typescript/lib/module/sksg/Container.native.d.ts +5 -0
  92. package/lib/typescript/lib/module/sksg/Recorder/ReanimatedRecorder.d.ts +1 -0
  93. package/lib/typescript/src/skia/types/Picture/PictureFactory.d.ts +1 -1
  94. package/lib/typescript/src/skia/types/Recorder.d.ts +2 -1
  95. package/lib/typescript/src/sksg/Container.native.d.ts +4 -0
  96. package/lib/typescript/src/sksg/Recorder/ReanimatedRecorder.d.ts +1 -0
  97. package/package.json +1 -1
  98. package/src/renderer/Canvas.tsx +16 -15
  99. package/src/skia/types/Picture/PictureFactory.ts +1 -1
  100. package/src/skia/types/Recorder.ts +2 -1
  101. package/src/sksg/Container.native.ts +25 -7
  102. package/src/sksg/Recorder/ReanimatedRecorder.ts +5 -0
@@ -48,6 +48,7 @@ export interface BaseRecorder {
48
48
  drawAtlas(props: AnimatedProps<AtlasProps>): void;
49
49
  }
50
50
  export interface JsiRecorder extends BaseRecorder {
51
- play(): SkPicture;
51
+ play(picture: SkPicture): void;
52
52
  applyUpdates(variables: SharedValue<unknown>[]): void;
53
+ reset(): void;
53
54
  }
@@ -5,6 +5,10 @@ import "../views/api";
5
5
  declare class NativeReanimatedContainer extends Container {
6
6
  private nativeId;
7
7
  private mapperId;
8
+ private picture;
9
+ private recorderA;
10
+ private recorderB;
11
+ private currentRecorder;
8
12
  constructor(Skia: Skia, nativeId: number);
9
13
  redraw(): void;
10
14
  }
@@ -10,6 +10,7 @@ export declare class ReanimatedRecorder implements BaseRecorder {
10
10
  private values;
11
11
  private recorder;
12
12
  constructor(Skia: Skia);
13
+ reset(): void;
13
14
  private processAnimationValues;
14
15
  getRecorder(): JsiRecorder;
15
16
  getSharedValues(): SharedValue<unknown>[];
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "setup-skia-web": "scripts/setup-canvaskit.js"
9
9
  },
10
10
  "title": "React Native Skia",
11
- "version": "2.3.8",
11
+ "version": "2.3.10",
12
12
  "skia": {
13
13
  "version": "m142",
14
14
  "checksums": {
@@ -15,7 +15,7 @@ import type {
15
15
  View,
16
16
  ViewProps,
17
17
  } from "react-native";
18
- import type { SharedValue } from "react-native-reanimated";
18
+ import type { AnimatedRef, SharedValue } from "react-native-reanimated";
19
19
 
20
20
  import Rea from "../external/reanimated/ReanimatedProxy";
21
21
  import { SkiaViewNativeId } from "../views/SkiaViewNativeId";
@@ -38,6 +38,11 @@ export interface CanvasRef extends FC<CanvasProps> {
38
38
  export const useCanvasRef = () => useRef<CanvasRef>(null);
39
39
 
40
40
  const useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;
41
+ const measure = !HAS_REANIMATED_3 ? null : Rea.measure;
42
+
43
+ const useCanvasRefPriv: typeof useRef<View> = !HAS_REANIMATED_3
44
+ ? useRef
45
+ : Rea.useAnimatedRef;
41
46
 
42
47
  export const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {
43
48
  const ourRef = useCanvasRef();
@@ -84,7 +89,7 @@ export const Canvas = ({
84
89
  "<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size"
85
90
  );
86
91
  }
87
- const viewRef = useRef<View>(null);
92
+ const viewRef = useCanvasRefPriv(null);
88
93
  // Native ID
89
94
  const nativeId = useMemo(() => {
90
95
  return SkiaViewNativeId.current++;
@@ -95,20 +100,16 @@ export const Canvas = ({
95
100
 
96
101
  useReanimatedFrame(() => {
97
102
  "worklet";
98
- }, !!onSize);
99
- useEffect(() => {
100
- if (onSize) {
101
- Rea.runOnUI(() => {
102
- (global as Record<string, unknown>)[`__onSize_${nativeId}`] = onSize;
103
- })();
104
- return () => {
105
- Rea.runOnUI(() => {
106
- delete (global as Record<string, unknown>)[`__onSize_${nativeId}`];
107
- })();
108
- };
103
+ if (onSize && measure) {
104
+ const result = measure(viewRef as AnimatedRef<View>);
105
+ if (result) {
106
+ const { width, height } = result;
107
+ if (onSize.value.width !== width || onSize.value.height !== height) {
108
+ onSize.value = { width, height };
109
+ }
110
+ }
109
111
  }
110
- return undefined;
111
- }, [onSize, nativeId]);
112
+ }, !!onSize);
112
113
 
113
114
  // Render effects
114
115
  useLayoutEffect(() => {
@@ -5,5 +5,5 @@ export interface PictureFactory {
5
5
  * Returns an SkPicture which has been serialized previously to the given bytes.
6
6
  * @param bytes
7
7
  */
8
- MakePicture(bytes: Uint8Array | ArrayBuffer): SkPicture | null;
8
+ MakePicture(bytes: Uint8Array | ArrayBuffer | null): SkPicture | null;
9
9
  }
@@ -92,6 +92,7 @@ export interface BaseRecorder {
92
92
  }
93
93
 
94
94
  export interface JsiRecorder extends BaseRecorder {
95
- play(): SkPicture;
95
+ play(picture: SkPicture): void;
96
96
  applyUpdates(variables: SharedValue<unknown>[]): void;
97
+ reset(): void;
97
98
  }
@@ -1,5 +1,5 @@
1
1
  import Rea from "../external/reanimated/ReanimatedProxy";
2
- import type { Skia } from "../skia/types";
2
+ import type { Skia, SkPicture } from "../skia/types";
3
3
  import { HAS_REANIMATED_3 } from "../external/reanimated/renderHelpers";
4
4
  import type { JsiRecorder } from "../skia/types/Recorder";
5
5
 
@@ -10,11 +10,15 @@ import { visit } from "./Recorder/Visitor";
10
10
  import "../skia/NativeSetup";
11
11
  import "../views/api";
12
12
 
13
- const nativeDrawOnscreen = (nativeId: number, recorder: JsiRecorder) => {
13
+ const nativeDrawOnscreen = (
14
+ nativeId: number,
15
+ recorder: JsiRecorder,
16
+ picture: SkPicture
17
+ ) => {
14
18
  "worklet";
15
19
 
16
20
  //const start = performance.now();
17
- const picture = recorder.play();
21
+ recorder.play(picture);
18
22
  //const end = performance.now();
19
23
  //console.log("Recording time: ", end - start);
20
24
  SkiaViewApi.setJsiProperty(nativeId, "picture", picture);
@@ -22,12 +26,20 @@ const nativeDrawOnscreen = (nativeId: number, recorder: JsiRecorder) => {
22
26
 
23
27
  class NativeReanimatedContainer extends Container {
24
28
  private mapperId: number | null = null;
29
+ private picture: SkPicture;
30
+ private recorderA: ReanimatedRecorder;
31
+ private recorderB: ReanimatedRecorder;
32
+ private currentRecorder: ReanimatedRecorder;
25
33
 
26
34
  constructor(
27
35
  Skia: Skia,
28
36
  private nativeId: number
29
37
  ) {
30
38
  super(Skia);
39
+ this.recorderA = new ReanimatedRecorder(Skia);
40
+ this.recorderB = new ReanimatedRecorder(Skia);
41
+ this.currentRecorder = this.recorderA;
42
+ this.picture = Skia.Picture.MakePicture(null)!;
31
43
  }
32
44
 
33
45
  redraw() {
@@ -37,20 +49,26 @@ class NativeReanimatedContainer extends Container {
37
49
  if (this.unmounted) {
38
50
  return;
39
51
  }
40
- const { nativeId, Skia } = this;
41
- const recorder = new ReanimatedRecorder(Skia);
52
+
53
+ // Swap to the next recorder (double buffering)
54
+ const recorder = this.currentRecorder;
55
+ this.currentRecorder =
56
+ this.currentRecorder === this.recorderA ? this.recorderB : this.recorderA;
57
+
58
+ const { nativeId, picture } = this;
59
+ recorder.reset();
42
60
  visit(recorder, this.root);
43
61
  const sharedValues = recorder.getSharedValues();
44
62
  const sharedRecorder = recorder.getRecorder();
45
63
  Rea.runOnUI(() => {
46
64
  "worklet";
47
- nativeDrawOnscreen(nativeId, sharedRecorder);
65
+ nativeDrawOnscreen(nativeId, sharedRecorder, picture);
48
66
  })();
49
67
  if (sharedValues.length > 0) {
50
68
  this.mapperId = Rea.startMapper(() => {
51
69
  "worklet";
52
70
  sharedRecorder.applyUpdates(sharedValues);
53
- nativeDrawOnscreen(nativeId, sharedRecorder);
71
+ nativeDrawOnscreen(nativeId, sharedRecorder, picture);
54
72
  }, sharedValues);
55
73
  }
56
74
  }
@@ -44,6 +44,11 @@ export class ReanimatedRecorder implements BaseRecorder {
44
44
  this.recorder = Skia.Recorder();
45
45
  }
46
46
 
47
+ reset() {
48
+ this.values.clear();
49
+ this.recorder.reset();
50
+ }
51
+
47
52
  private processAnimationValues(props?: Record<string, unknown>) {
48
53
  if (!props) {
49
54
  return;