@shopify/react-native-skia 2.12.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +2 -1
- package/Package.swift +4 -4
- package/android/CMakeLists.txt +22 -177
- package/android/build.gradle +40 -209
- package/android/cpp/jni/JniSkiaManager.cpp +3 -45
- package/android/cpp/jni/include/JniPlatformContext.h +1 -1
- package/android/cpp/jni/include/JniSkiaBaseView.h +18 -11
- package/android/cpp/jni/include/JniSkiaManager.h +3 -4
- package/android/cpp/jni/include/JniSkiaPictureView.h +5 -5
- package/android/cpp/rnskia-android/RNSkAndroidView.h +6 -6
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +4 -4
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +2 -2
- package/android/src/main/AndroidManifest.xml +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/PlatformContext.java +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/RNSkVideo.java +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/RNSkiaModule.java +1 -8
- package/android/src/main/java/com/reactnative/skia/RNSkiaPackage.java +57 -0
- package/android/src/main/java/com/reactnative/skia/SkiaBaseView.java +185 -0
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaBaseViewManager.java +20 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaManager.java +11 -6
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaPictureView.java +3 -3
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaPictureViewManager.java +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaSurfaceView.java +13 -3
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaTextureView.java +5 -3
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/SkiaViewAPI.java +1 -1
- package/android/src/main/java/com/{shopify/reactnative → reactnative}/skia/ViewScreenshotService.java +1 -1
- package/apple/MetalContext.mm +1 -1
- package/apple/RNSkiaModule.h +1 -10
- package/apple/RNSkiaModule.mm +2 -10
- package/apple/SkiaManager.h +0 -2
- package/apple/SkiaManager.mm +4 -6
- package/apple/SkiaPictureView.h +2 -2
- package/apple/SkiaPictureView.mm +0 -4
- package/apple/SkiaUIView.h +3 -18
- package/apple/SkiaUIView.mm +0 -30
- package/cpp/api/CustomBlendModes.h +17 -0
- package/cpp/api/JsiSkCanvas.h +19 -10
- package/cpp/jsi/ViewProperty.h +0 -4
- package/lib/commonjs/mock/index.js +0 -1
- package/lib/commonjs/mock/index.js.map +1 -1
- package/lib/commonjs/renderer/Canvas.d.ts +11 -3
- package/lib/commonjs/renderer/Canvas.js +8 -6
- package/lib/commonjs/renderer/Canvas.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.js +9 -4
- package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +1 -1
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js +3 -0
- package/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.js.map +1 -1
- package/lib/commonjs/views/SkiaPictureView.js +2 -12
- package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
- package/lib/commonjs/views/types.d.ts +19 -8
- package/lib/commonjs/views/types.js.map +1 -1
- package/lib/module/mock/index.js +0 -1
- package/lib/module/mock/index.js.map +1 -1
- package/lib/module/renderer/Canvas.d.ts +11 -3
- package/lib/module/renderer/Canvas.js +7 -5
- package/lib/module/renderer/Canvas.js.map +1 -1
- package/lib/module/skia/web/JsiSkCanvas.js +9 -4
- package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
- package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +1 -1
- package/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/module/specs/SkiaPictureViewNativeComponent.web.js +3 -0
- package/lib/module/specs/SkiaPictureViewNativeComponent.web.js.map +1 -1
- package/lib/module/views/SkiaPictureView.js +2 -12
- package/lib/module/views/SkiaPictureView.js.map +1 -1
- package/lib/module/views/types.d.ts +19 -8
- package/lib/module/views/types.js.map +1 -1
- package/lib/typescript/lib/commonjs/mock/index.d.ts +0 -1
- package/lib/typescript/lib/commonjs/renderer/Canvas.d.ts +2 -2
- package/lib/typescript/lib/commonjs/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/typescript/lib/module/mock/index.d.ts +0 -1
- package/lib/typescript/lib/module/renderer/Canvas.d.ts +2 -2
- package/lib/typescript/lib/module/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/typescript/src/renderer/Canvas.d.ts +11 -3
- package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.d.ts +2 -0
- package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.web.d.ts +3 -1
- package/lib/typescript/src/views/types.d.ts +19 -8
- package/package.json +3 -3
- package/react-native-skia.podspec +4 -10
- package/src/mock/index.ts +0 -1
- package/src/renderer/Canvas.tsx +23 -5
- package/src/skia/web/JsiSkCanvas.ts +14 -9
- package/src/specs/SkiaPictureViewNativeComponent.ts +5 -0
- package/src/specs/SkiaPictureViewNativeComponent.web.ts +5 -0
- package/src/views/SkiaPictureView.tsx +2 -10
- package/src/views/types.ts +23 -10
- package/android/src/latest/java/com/shopify/reactnative/skia/ReactNativeCompatible.java +0 -11
- package/android/src/main/java/com/shopify/reactnative/skia/RNSkiaPackage.java +0 -79
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaAHBView.java +0 -113
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +0 -136
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerDelegate.java +0 -41
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerInterface.java +0 -20
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaWebGPUViewManagerDelegate.java +0 -35
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaWebGPUViewManagerInterface.java +0 -17
- package/android/src/paper/java/com/shopify/reactnative/skia/NativeSkiaModuleSpec.java +0 -38
- package/android/src/reactnative74/java/com/shopify/reactnative/skia/ReactNativeCompatible.java +0 -14
- package/apple/SkiaPictureViewManager.h +0 -8
- package/apple/SkiaPictureViewManager.mm +0 -60
- package/apple/SkiaWebGPUView.h +0 -20
- package/apple/WebGPUMetalView.h +0 -12
package/src/renderer/Canvas.tsx
CHANGED
|
@@ -19,6 +19,7 @@ import type { SharedValue } from "react-native-reanimated";
|
|
|
19
19
|
|
|
20
20
|
import Rea from "../external/reanimated/ReanimatedProxy";
|
|
21
21
|
import { SkiaViewNativeId } from "../views/SkiaViewNativeId";
|
|
22
|
+
import type { AndroidCanvasProps, AndroidSurfaceType } from "../views/types";
|
|
22
23
|
import SkiaPictureViewNativeComponent from "../specs/SkiaPictureViewNativeComponent";
|
|
23
24
|
import type { SkImage, SkRect, SkSize } from "../skia/types";
|
|
24
25
|
import { SkiaSGRoot } from "../sksg/Reconciler";
|
|
@@ -59,13 +60,16 @@ export const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {
|
|
|
59
60
|
return { ref, size };
|
|
60
61
|
};
|
|
61
62
|
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
-
export const isFabric = Boolean((global as any)?.nativeFabricUIManager);
|
|
64
|
-
|
|
65
63
|
export interface CanvasProps extends Omit<ViewProps, "onLayout"> {
|
|
66
64
|
debug?: boolean;
|
|
67
|
-
/** @deprecated Not supported on
|
|
65
|
+
/** @deprecated Not supported on native. Use `onSize` or `useCanvasSize()` instead. */
|
|
68
66
|
onLayout?: ViewProps["onLayout"];
|
|
67
|
+
/**
|
|
68
|
+
* Declares that the canvas covers every pixel of its bounds, so nothing
|
|
69
|
+
* behind it needs to show through. On Android an opaque canvas is backed by
|
|
70
|
+
* a `SurfaceView` by default, the cheapest path (see `android.surfaceType`).
|
|
71
|
+
* Defaults to false.
|
|
72
|
+
*/
|
|
69
73
|
opaque?: boolean;
|
|
70
74
|
onSize?: SharedValue<SkSize>;
|
|
71
75
|
colorSpace?: "p3" | "srgb";
|
|
@@ -78,11 +82,22 @@ export interface CanvasProps extends Omit<ViewProps, "onLayout"> {
|
|
|
78
82
|
* before the canvas is mounted.
|
|
79
83
|
*/
|
|
80
84
|
highBitDepth?: boolean;
|
|
85
|
+
/** Android-only rendering options. Ignored on iOS and web. */
|
|
86
|
+
android?: AndroidCanvasProps;
|
|
81
87
|
ref?: React.Ref<CanvasRef>;
|
|
82
88
|
androidWarmup?: boolean;
|
|
83
89
|
__destroyWebGLContextAfterRender?: boolean;
|
|
84
90
|
}
|
|
85
91
|
|
|
92
|
+
// Anything else reaching the native component would hit the generated
|
|
93
|
+
// string-enum parser, which aborts on unknown values.
|
|
94
|
+
const resolveSurfaceType = (
|
|
95
|
+
surfaceType: AndroidSurfaceType | undefined
|
|
96
|
+
): "auto" | AndroidSurfaceType =>
|
|
97
|
+
surfaceType === "SurfaceView" || surfaceType === "TextureView"
|
|
98
|
+
? surfaceType
|
|
99
|
+
: "auto";
|
|
100
|
+
|
|
86
101
|
export const Canvas = ({
|
|
87
102
|
debug,
|
|
88
103
|
opaque,
|
|
@@ -91,11 +106,12 @@ export const Canvas = ({
|
|
|
91
106
|
colorSpace = "p3",
|
|
92
107
|
highBitDepth = false,
|
|
93
108
|
androidWarmup = false,
|
|
109
|
+
android,
|
|
94
110
|
ref,
|
|
95
111
|
onLayout,
|
|
96
112
|
...viewProps
|
|
97
113
|
}: CanvasProps) => {
|
|
98
|
-
if (onLayout &&
|
|
114
|
+
if (onLayout && Platform.OS !== "web") {
|
|
99
115
|
console.error(
|
|
100
116
|
"<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"
|
|
101
117
|
);
|
|
@@ -192,6 +208,8 @@ export const Canvas = ({
|
|
|
192
208
|
colorSpace={colorSpace}
|
|
193
209
|
highBitDepth={highBitDepth}
|
|
194
210
|
androidWarmup={androidWarmup}
|
|
211
|
+
androidSurfaceType={resolveSurfaceType(android?.surfaceType)}
|
|
212
|
+
androidZOrderOnTop={!!android?.zOrderOnTop}
|
|
195
213
|
onLayout={
|
|
196
214
|
Platform.OS === "web" && (onSize || onLayout) ? onLayoutWeb : onLayout
|
|
197
215
|
}
|
|
@@ -205,15 +205,20 @@ export class JsiSkCanvas
|
|
|
205
205
|
mode?: BlendMode | null,
|
|
206
206
|
paint?: SkPaint
|
|
207
207
|
) {
|
|
208
|
-
this.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
?
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
208
|
+
const defaultPaint = paint ? null : new this.CanvasKit.Paint();
|
|
209
|
+
try {
|
|
210
|
+
this.ref.drawPatch(
|
|
211
|
+
cubics.map(({ x, y }) => [x, y]).flat(),
|
|
212
|
+
colors,
|
|
213
|
+
texs ? texs.flatMap((p) => Array.from(JsiSkPoint.fromValue(p))) : texs,
|
|
214
|
+
mode !== undefined && mode !== null
|
|
215
|
+
? getEnum(this.CanvasKit, "BlendMode", mode)
|
|
216
|
+
: null,
|
|
217
|
+
paint ? JsiSkPaint.fromValue(paint) : defaultPaint!
|
|
218
|
+
);
|
|
219
|
+
} finally {
|
|
220
|
+
defaultPaint?.delete();
|
|
221
|
+
}
|
|
217
222
|
}
|
|
218
223
|
|
|
219
224
|
restoreToCount(saveCount: number) {
|
|
@@ -9,6 +9,11 @@ export interface NativeProps extends ViewProps {
|
|
|
9
9
|
colorSpace?: string;
|
|
10
10
|
highBitDepth?: boolean;
|
|
11
11
|
androidWarmup?: boolean;
|
|
12
|
+
androidSurfaceType?: WithDefault<
|
|
13
|
+
"auto" | "SurfaceView" | "TextureView",
|
|
14
|
+
"auto"
|
|
15
|
+
>;
|
|
16
|
+
androidZOrderOnTop?: WithDefault<boolean, false>;
|
|
12
17
|
pointerEvents?: WithDefault<
|
|
13
18
|
"auto" | "none" | "box-none" | "box-only",
|
|
14
19
|
"auto"
|
|
@@ -7,6 +7,8 @@ export interface NativeProps extends ViewProps {
|
|
|
7
7
|
debug?: boolean;
|
|
8
8
|
opaque?: boolean;
|
|
9
9
|
nativeID: string;
|
|
10
|
+
androidSurfaceType?: "auto" | "SurfaceView" | "TextureView";
|
|
11
|
+
androidZOrderOnTop?: boolean;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
const SkiaPictureViewNativeComponent = ({
|
|
@@ -14,6 +16,9 @@ const SkiaPictureViewNativeComponent = ({
|
|
|
14
16
|
debug,
|
|
15
17
|
opaque,
|
|
16
18
|
onLayout,
|
|
19
|
+
// Android-only, never reaches the DOM
|
|
20
|
+
androidSurfaceType: _androidSurfaceType,
|
|
21
|
+
androidZOrderOnTop: _androidZOrderOnTop,
|
|
17
22
|
...viewProps
|
|
18
23
|
}: NativeProps) => {
|
|
19
24
|
return createElement(SkiaPictureView, {
|
|
@@ -20,15 +20,11 @@ export class SkiaPictureView extends React.Component<SkiaPictureViewProps> {
|
|
|
20
20
|
constructor(props: SkiaPictureViewProps) {
|
|
21
21
|
super(props);
|
|
22
22
|
this._nativeId = SkiaViewNativeId.current++;
|
|
23
|
-
const { picture
|
|
23
|
+
const { picture } = props;
|
|
24
24
|
if (picture) {
|
|
25
25
|
assertSkiaViewApi();
|
|
26
26
|
SkiaViewApi.setJsiProperty(this._nativeId, "picture", picture);
|
|
27
27
|
}
|
|
28
|
-
if (onSize) {
|
|
29
|
-
assertSkiaViewApi();
|
|
30
|
-
SkiaViewApi.setJsiProperty(this._nativeId, "onSize", onSize);
|
|
31
|
-
}
|
|
32
28
|
this.tick();
|
|
33
29
|
}
|
|
34
30
|
|
|
@@ -39,15 +35,11 @@ export class SkiaPictureView extends React.Component<SkiaPictureViewProps> {
|
|
|
39
35
|
}
|
|
40
36
|
|
|
41
37
|
componentDidUpdate(prevProps: SkiaPictureViewProps) {
|
|
42
|
-
const { picture
|
|
38
|
+
const { picture } = this.props;
|
|
43
39
|
if (picture !== prevProps.picture) {
|
|
44
40
|
assertSkiaViewApi();
|
|
45
41
|
SkiaViewApi.setJsiProperty(this._nativeId, "picture", picture);
|
|
46
42
|
}
|
|
47
|
-
if (onSize !== prevProps.onSize) {
|
|
48
|
-
assertSkiaViewApi();
|
|
49
|
-
SkiaViewApi.setJsiProperty(this._nativeId, "onSize", onSize);
|
|
50
|
-
}
|
|
51
43
|
this.tick();
|
|
52
44
|
}
|
|
53
45
|
|
package/src/views/types.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { ViewProps } from "react-native";
|
|
2
|
-
import type { SharedValue } from "react-native-reanimated";
|
|
3
2
|
|
|
4
|
-
import type { Node } from "../dom/types";
|
|
5
3
|
import type { SkImage, SkPicture, SkRect, SkSize } from "../skia/types";
|
|
6
4
|
|
|
7
5
|
export type NativeSkiaViewProps = ViewProps & {
|
|
@@ -9,6 +7,22 @@ export type NativeSkiaViewProps = ViewProps & {
|
|
|
9
7
|
opaque?: boolean;
|
|
10
8
|
};
|
|
11
9
|
|
|
10
|
+
export type AndroidSurfaceType = "SurfaceView" | "TextureView";
|
|
11
|
+
|
|
12
|
+
export interface AndroidCanvasProps {
|
|
13
|
+
/**
|
|
14
|
+
* Backing view. Defaults to `SurfaceView` when the canvas is `opaque` and to
|
|
15
|
+
* `TextureView` otherwise; both composite correctly in React Native stacking
|
|
16
|
+
* order without further flags.
|
|
17
|
+
*/
|
|
18
|
+
surfaceType?: AndroidSurfaceType;
|
|
19
|
+
/**
|
|
20
|
+
* SurfaceView only: composite above every React Native view in the window,
|
|
21
|
+
* ignoring `zIndex`. Ignored for TextureView. Defaults to false.
|
|
22
|
+
*/
|
|
23
|
+
zOrderOnTop?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
12
26
|
export interface ISkiaViewApi {
|
|
13
27
|
web?: boolean;
|
|
14
28
|
setJsiProperty: <T>(nativeId: number, name: string, value: T) => void;
|
|
@@ -24,12 +38,12 @@ export interface SkiaBaseViewProps extends ViewProps {
|
|
|
24
38
|
* average time it takes to render.
|
|
25
39
|
*/
|
|
26
40
|
debug?: boolean;
|
|
41
|
+
|
|
27
42
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
43
|
+
* Declares that the canvas covers every pixel of its bounds. On Android an
|
|
44
|
+
* opaque canvas is backed by a `SurfaceView` by default, the cheapest path
|
|
45
|
+
* (see `android.surfaceType`). Defaults to false.
|
|
30
46
|
*/
|
|
31
|
-
onSize?: SharedValue<SkSize>;
|
|
32
|
-
|
|
33
47
|
opaque?: boolean;
|
|
34
48
|
|
|
35
49
|
/**
|
|
@@ -39,6 +53,9 @@ export interface SkiaBaseViewProps extends ViewProps {
|
|
|
39
53
|
*/
|
|
40
54
|
highBitDepth?: boolean;
|
|
41
55
|
|
|
56
|
+
/** Android-only rendering options. Ignored on iOS and web. */
|
|
57
|
+
android?: AndroidCanvasProps;
|
|
58
|
+
|
|
42
59
|
// On web, only 16 WebGL contextes are allowed. If the drawing is non-animated, set
|
|
43
60
|
// __destroyWebGLContextAfterRender to true to release the context after each draw.
|
|
44
61
|
__destroyWebGLContextAfterRender?: boolean;
|
|
@@ -48,7 +65,3 @@ export interface SkiaPictureViewNativeProps extends SkiaBaseViewProps {
|
|
|
48
65
|
picture?: SkPicture;
|
|
49
66
|
androidWarmup?: boolean;
|
|
50
67
|
}
|
|
51
|
-
|
|
52
|
-
export interface SkiaDomViewNativeProps extends SkiaBaseViewProps {
|
|
53
|
-
root?: Node<unknown>;
|
|
54
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
package com.shopify.reactnative.skia;
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.ReactContext;
|
|
4
|
-
import com.facebook.react.bridge.RuntimeExecutor;
|
|
5
|
-
|
|
6
|
-
/* package */ final class ReactNativeCompatible {
|
|
7
|
-
public static RuntimeExecutor getRuntimeExecutor(ReactContext context) {
|
|
8
|
-
return context.getCatalystInstance().getRuntimeExecutor();
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
// RnskiaPackage.java
|
|
2
|
-
|
|
3
|
-
package com.shopify.reactnative.skia;
|
|
4
|
-
|
|
5
|
-
import androidx.annotation.Nullable;
|
|
6
|
-
|
|
7
|
-
import java.util.Arrays;
|
|
8
|
-
import java.util.HashMap;
|
|
9
|
-
import java.util.List;
|
|
10
|
-
import java.util.Map;
|
|
11
|
-
|
|
12
|
-
import com.facebook.react.TurboReactPackage;
|
|
13
|
-
import com.facebook.react.bridge.NativeModule;
|
|
14
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
15
|
-
import com.facebook.react.module.annotations.ReactModule;
|
|
16
|
-
import com.facebook.react.module.annotations.ReactModuleList;
|
|
17
|
-
import com.facebook.react.module.model.ReactModuleInfo;
|
|
18
|
-
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
|
19
|
-
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
|
20
|
-
import com.facebook.react.uimanager.ViewManager;
|
|
21
|
-
|
|
22
|
-
@ReactModuleList(
|
|
23
|
-
nativeModules = {
|
|
24
|
-
RNSkiaModule.class,
|
|
25
|
-
})
|
|
26
|
-
public class RNSkiaPackage extends TurboReactPackage {
|
|
27
|
-
@Override
|
|
28
|
-
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
|
29
|
-
return Arrays.<NativeModule>asList(new RNSkiaModule(reactContext));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
@Nullable
|
|
33
|
-
@Override
|
|
34
|
-
public NativeModule getModule(String s, ReactApplicationContext reactApplicationContext) {
|
|
35
|
-
switch (s) {
|
|
36
|
-
case RNSkiaModule.NAME:
|
|
37
|
-
return new RNSkiaModule(reactApplicationContext);
|
|
38
|
-
default:
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
@Override
|
|
44
|
-
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
45
|
-
return Arrays.<ViewManager>asList(
|
|
46
|
-
new SkiaPictureViewManager()
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@Override
|
|
51
|
-
public ReactModuleInfoProvider getReactModuleInfoProvider() {
|
|
52
|
-
return new ReactModuleInfoProvider() {
|
|
53
|
-
@Override
|
|
54
|
-
public Map<String, ReactModuleInfo> getReactModuleInfos() {
|
|
55
|
-
final Map<String, ReactModuleInfo> reactModuleInfoMap = new HashMap<>();
|
|
56
|
-
Class<? extends NativeModule>[] moduleList =
|
|
57
|
-
new Class[] {
|
|
58
|
-
RNSkiaModule.class,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
for (Class<? extends NativeModule> moduleClass : moduleList) {
|
|
62
|
-
ReactModule reactModule = moduleClass.getAnnotation(ReactModule.class);
|
|
63
|
-
|
|
64
|
-
reactModuleInfoMap.put(
|
|
65
|
-
reactModule.name(),
|
|
66
|
-
new ReactModuleInfo(
|
|
67
|
-
reactModule.name(),
|
|
68
|
-
moduleClass.getName(),
|
|
69
|
-
reactModule.canOverrideExistingModule(),
|
|
70
|
-
reactModule.needsEagerInit(),
|
|
71
|
-
reactModule.hasConstants(),
|
|
72
|
-
reactModule.isCxxModule(),
|
|
73
|
-
TurboModule.class.isAssignableFrom(moduleClass)));
|
|
74
|
-
}
|
|
75
|
-
return reactModuleInfoMap;
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
package com.shopify.reactnative.skia;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import android.annotation.SuppressLint;
|
|
5
|
-
import android.content.Context;
|
|
6
|
-
import android.graphics.Bitmap;
|
|
7
|
-
import android.graphics.Canvas;
|
|
8
|
-
import android.graphics.Matrix;
|
|
9
|
-
import android.graphics.PixelFormat;
|
|
10
|
-
import android.hardware.HardwareBuffer;
|
|
11
|
-
import android.media.Image;
|
|
12
|
-
import android.media.ImageReader;
|
|
13
|
-
import android.os.Build;
|
|
14
|
-
import android.util.Log;
|
|
15
|
-
import android.view.View;
|
|
16
|
-
|
|
17
|
-
import androidx.annotation.NonNull;
|
|
18
|
-
import androidx.annotation.RequiresApi;
|
|
19
|
-
|
|
20
|
-
@SuppressLint("ViewConstructor")
|
|
21
|
-
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
22
|
-
public class SkiaAHBView extends View implements ImageReader.OnImageAvailableListener {
|
|
23
|
-
|
|
24
|
-
private ImageReader mReader;
|
|
25
|
-
|
|
26
|
-
private Bitmap mBitmap = null;
|
|
27
|
-
|
|
28
|
-
private final Matrix matrix = new Matrix();
|
|
29
|
-
|
|
30
|
-
SkiaViewAPI mApi;
|
|
31
|
-
boolean mDebug;
|
|
32
|
-
|
|
33
|
-
public SkiaAHBView(Context context, SkiaViewAPI api, boolean debug) {
|
|
34
|
-
super(context);
|
|
35
|
-
mApi = api;
|
|
36
|
-
mDebug = debug;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private ImageReader createReader() {
|
|
40
|
-
ImageReader reader = ImageReader.newInstance(getWidth(), getHeight(), PixelFormat.RGBA_8888, 2, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE |
|
|
41
|
-
HardwareBuffer.USAGE_GPU_COLOR_OUTPUT);
|
|
42
|
-
reader.setOnImageAvailableListener(this, null);
|
|
43
|
-
return reader;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@Override
|
|
47
|
-
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
48
|
-
super.onLayout(changed, left, top, right, bottom);
|
|
49
|
-
int width = getWidth();
|
|
50
|
-
int height = getHeight();
|
|
51
|
-
if (mReader == null) {
|
|
52
|
-
mReader = createReader();
|
|
53
|
-
mApi.onSurfaceCreated(mReader.getSurface(), width, height);
|
|
54
|
-
} else {
|
|
55
|
-
mReader = createReader();
|
|
56
|
-
mApi.onSurfaceChanged(mReader.getSurface(), width, height);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@Override
|
|
61
|
-
public void onImageAvailable(ImageReader reader) {
|
|
62
|
-
try (Image image = reader.acquireLatestImage()) {
|
|
63
|
-
if (image != null) {
|
|
64
|
-
HardwareBuffer hb = image.getHardwareBuffer();
|
|
65
|
-
if (mDebug) {
|
|
66
|
-
textureUpdated(image.getTimestamp());
|
|
67
|
-
}
|
|
68
|
-
if (hb != null) {
|
|
69
|
-
Bitmap bitmap = Bitmap.wrapHardwareBuffer(hb, null);
|
|
70
|
-
if (bitmap != null) {
|
|
71
|
-
mBitmap = bitmap;
|
|
72
|
-
hb.close();
|
|
73
|
-
invalidate();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
@Override
|
|
81
|
-
protected void onDraw(@NonNull Canvas canvas) {
|
|
82
|
-
super.onDraw(canvas);
|
|
83
|
-
if (mBitmap != null) {
|
|
84
|
-
float viewWidth = getWidth();
|
|
85
|
-
float viewHeight = getHeight();
|
|
86
|
-
float bitmapWidth = mBitmap.getWidth();
|
|
87
|
-
float bitmapHeight = mBitmap.getHeight();
|
|
88
|
-
|
|
89
|
-
// Calculate the scale factors
|
|
90
|
-
float scaleX = viewWidth / bitmapWidth;
|
|
91
|
-
float scaleY = viewHeight / bitmapHeight;
|
|
92
|
-
|
|
93
|
-
// Reset the matrix and apply scaling
|
|
94
|
-
matrix.reset();
|
|
95
|
-
matrix.setScale(scaleX, scaleY);
|
|
96
|
-
|
|
97
|
-
canvas.drawBitmap(mBitmap, matrix, null);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
private long _prevTimestamp = 0;
|
|
102
|
-
public void textureUpdated(long ts) {
|
|
103
|
-
long frameDuration = (ts - _prevTimestamp)/1000000;
|
|
104
|
-
Log.i("SkiaAHBView", "onSurfaceTextureUpdated "+frameDuration+"ms");
|
|
105
|
-
_prevTimestamp = ts;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
@Override
|
|
109
|
-
protected void onDetachedFromWindow() {
|
|
110
|
-
super.onDetachedFromWindow();
|
|
111
|
-
mApi.onSurfaceDestroyed();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
package com.shopify.reactnative.skia;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
import android.graphics.SurfaceTexture;
|
|
5
|
-
import android.util.Log;
|
|
6
|
-
import android.view.MotionEvent;
|
|
7
|
-
import android.view.Surface;
|
|
8
|
-
import android.view.View;
|
|
9
|
-
|
|
10
|
-
import com.facebook.react.uimanager.PointerEvents;
|
|
11
|
-
import com.facebook.react.views.view.ReactViewGroup;
|
|
12
|
-
|
|
13
|
-
public abstract class SkiaBaseView extends ReactViewGroup implements SkiaViewAPI {
|
|
14
|
-
private View mView;
|
|
15
|
-
|
|
16
|
-
private boolean mHighBitDepth = false;
|
|
17
|
-
|
|
18
|
-
private final boolean debug = false;
|
|
19
|
-
private final String tag = "SkiaView";
|
|
20
|
-
|
|
21
|
-
public SkiaBaseView(Context context) {
|
|
22
|
-
super(context);
|
|
23
|
-
mView = new SkiaTextureView(context, this, debug);
|
|
24
|
-
addView(mView);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@Override
|
|
28
|
-
public boolean dispatchTouchEvent(MotionEvent ev) {
|
|
29
|
-
// When pointerEvents is "none" or "box-none", make this view completely
|
|
30
|
-
// transparent to touch dispatch so events pass through to views behind it
|
|
31
|
-
if (!PointerEvents.canBeTouchTarget(getPointerEvents())) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return super.dispatchTouchEvent(ev);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public void setOpaque(boolean value) {
|
|
38
|
-
if (value && mView instanceof SkiaTextureView) {
|
|
39
|
-
recreateView(true);
|
|
40
|
-
} else if (!value && mView instanceof SkiaSurfaceView) {
|
|
41
|
-
recreateView(false);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public void setHighBitDepth(boolean value) {
|
|
46
|
-
if (mHighBitDepth == value) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
mHighBitDepth = value;
|
|
50
|
-
// The flag only affects the opaque SurfaceView path (see
|
|
51
|
-
// highBitDepthIfOpaque), so only that surface needs to be recreated
|
|
52
|
-
// with the new buffer format.
|
|
53
|
-
if (mView instanceof SkiaSurfaceView) {
|
|
54
|
-
recreateView(true);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private void recreateView(boolean useSurfaceView) {
|
|
59
|
-
removeView(mView);
|
|
60
|
-
mView = useSurfaceView
|
|
61
|
-
? new SkiaSurfaceView(getContext(), this, debug)
|
|
62
|
-
: new SkiaTextureView(getContext(), this, debug);
|
|
63
|
-
addView(mView);
|
|
64
|
-
// React Native sizes native children explicitly through onLayout, so
|
|
65
|
-
// the requestLayout triggered by addView is ignored; size the new
|
|
66
|
-
// child ourselves or it stays 0x0 and never gets a surface.
|
|
67
|
-
if (getWidth() > 0 || getHeight() > 0) {
|
|
68
|
-
mView.layout(0, 0, getWidth(), getHeight());
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private boolean highBitDepthIfOpaque(boolean opaque) {
|
|
73
|
-
if (mHighBitDepth && !opaque) {
|
|
74
|
-
// The 10-bit buffer format only has 2 bits of alpha, which would
|
|
75
|
-
// visibly break translucency; the extra precision would also be
|
|
76
|
-
// lost in the 8-bit composition pass.
|
|
77
|
-
Log.w(tag, "highBitDepth requires the opaque prop on Android, falling back to the 8-bit format");
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
return mHighBitDepth;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
void dropInstance() {
|
|
84
|
-
if (!RNSkiaModule.isModuleValid()) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
unregisterView();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@Override
|
|
91
|
-
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
92
|
-
super.onLayout(changed, left, top, right, bottom);
|
|
93
|
-
mView.layout(0, 0, right - left, bottom - top);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
@Override
|
|
97
|
-
public void onSurfaceCreated(Surface surface, int width, int height) {
|
|
98
|
-
surfaceAvailable(surface, width, height, true, mHighBitDepth);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
@Override
|
|
102
|
-
public void onSurfaceChanged(Surface surface, int width, int height) {
|
|
103
|
-
Log.i(tag, "onSurfaceTextureSizeChanged " + width + "/" + height);
|
|
104
|
-
surfaceSizeChanged(surface, width, height, true, mHighBitDepth);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
@Override
|
|
108
|
-
public void onSurfaceTextureCreated(SurfaceTexture surface, int width, int height) {
|
|
109
|
-
surfaceAvailable(surface, width, height, false, highBitDepthIfOpaque(false));
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
@Override
|
|
113
|
-
public void onSurfaceTextureChanged(SurfaceTexture surface, int width, int height) {
|
|
114
|
-
Log.i(tag, "onSurfaceTextureSizeChanged " + width + "/" + height);
|
|
115
|
-
surfaceSizeChanged(surface, width, height, false, highBitDepthIfOpaque(false));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
@Override
|
|
119
|
-
public void onSurfaceDestroyed() {
|
|
120
|
-
surfaceDestroyed();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
protected abstract void surfaceAvailable(Object surface, int width, int height, boolean opaque, boolean highBitDepth);
|
|
124
|
-
|
|
125
|
-
protected abstract void surfaceSizeChanged(Object surface, int width, int height, boolean opaque, boolean highBitDepth);
|
|
126
|
-
|
|
127
|
-
protected abstract void surfaceDestroyed();
|
|
128
|
-
|
|
129
|
-
protected abstract void setDebugMode(boolean show);
|
|
130
|
-
|
|
131
|
-
protected abstract void registerView(int nativeId);
|
|
132
|
-
|
|
133
|
-
protected abstract void unregisterView();
|
|
134
|
-
|
|
135
|
-
protected abstract int[] getBitmap(int width, int height);
|
|
136
|
-
}
|
package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerDelegate.java
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
3
|
-
*
|
|
4
|
-
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
5
|
-
* once the code is regenerated.
|
|
6
|
-
*
|
|
7
|
-
* @generated by codegen project: GeneratePropsJavaDelegate.js
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
package com.facebook.react.viewmanagers;
|
|
11
|
-
|
|
12
|
-
import android.view.View;
|
|
13
|
-
import androidx.annotation.Nullable;
|
|
14
|
-
import com.facebook.react.uimanager.BaseViewManagerDelegate;
|
|
15
|
-
import com.facebook.react.uimanager.BaseViewManager;
|
|
16
|
-
import com.facebook.react.uimanager.LayoutShadowNode;
|
|
17
|
-
|
|
18
|
-
public class SkiaPictureViewManagerDelegate<T extends View, U extends BaseViewManager<T, ? extends LayoutShadowNode> & SkiaPictureViewManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
|
|
19
|
-
public SkiaPictureViewManagerDelegate(U viewManager) {
|
|
20
|
-
super(viewManager);
|
|
21
|
-
}
|
|
22
|
-
@Override
|
|
23
|
-
public void setProperty(T view, String propName, @Nullable Object value) {
|
|
24
|
-
switch (propName) {
|
|
25
|
-
case "debug":
|
|
26
|
-
mViewManager.setDebug(view, value != null && (boolean) value);
|
|
27
|
-
break;
|
|
28
|
-
case "opaque":
|
|
29
|
-
mViewManager.setOpaque(view, value != null && (boolean) value);
|
|
30
|
-
break;
|
|
31
|
-
case "colorSpace":
|
|
32
|
-
mViewManager.setColorSpace(view, value == null ? null : (String) value);
|
|
33
|
-
break;
|
|
34
|
-
case "androidWarmup":
|
|
35
|
-
mViewManager.setAndroidWarmup(view, value != null && (boolean) value);
|
|
36
|
-
break;
|
|
37
|
-
default:
|
|
38
|
-
super.setProperty(view, propName, value);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerInterface.java
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
3
|
-
*
|
|
4
|
-
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
5
|
-
* once the code is regenerated.
|
|
6
|
-
*
|
|
7
|
-
* @generated by codegen project: GeneratePropsJavaInterface.js
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
package com.facebook.react.viewmanagers;
|
|
11
|
-
|
|
12
|
-
import android.view.View;
|
|
13
|
-
import androidx.annotation.Nullable;
|
|
14
|
-
|
|
15
|
-
public interface SkiaPictureViewManagerInterface<T extends View> {
|
|
16
|
-
void setDebug(T view, boolean value);
|
|
17
|
-
void setOpaque(T view, boolean value);
|
|
18
|
-
void setColorSpace(T view, @Nullable String value);
|
|
19
|
-
void setAndroidWarmup(T view, boolean value);
|
|
20
|
-
}
|
package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaWebGPUViewManagerDelegate.java
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
3
|
-
*
|
|
4
|
-
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
5
|
-
* once the code is regenerated.
|
|
6
|
-
*
|
|
7
|
-
* @generated by codegen project: GeneratePropsJavaDelegate.js
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
package com.facebook.react.viewmanagers;
|
|
11
|
-
|
|
12
|
-
import android.view.View;
|
|
13
|
-
import androidx.annotation.Nullable;
|
|
14
|
-
import com.facebook.react.uimanager.BaseViewManagerDelegate;
|
|
15
|
-
import com.facebook.react.uimanager.BaseViewManager;
|
|
16
|
-
import com.facebook.react.uimanager.LayoutShadowNode;
|
|
17
|
-
|
|
18
|
-
public class SkiaWebGPUViewManagerDelegate<T extends View, U extends BaseViewManager<T, ? extends LayoutShadowNode> & SkiaWebGPUViewManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
|
|
19
|
-
public SkiaWebGPUViewManagerDelegate(U viewManager) {
|
|
20
|
-
super(viewManager);
|
|
21
|
-
}
|
|
22
|
-
@Override
|
|
23
|
-
public void setProperty(T view, String propName, @Nullable Object value) {
|
|
24
|
-
switch (propName) {
|
|
25
|
-
case "contextId":
|
|
26
|
-
mViewManager.setContextId(view, value == null ? 0 : ((Double) value).intValue());
|
|
27
|
-
break;
|
|
28
|
-
case "transparent":
|
|
29
|
-
mViewManager.setTransparent(view, value != null && (boolean) value);
|
|
30
|
-
break;
|
|
31
|
-
default:
|
|
32
|
-
super.setProperty(view, propName, value);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|