@shopify/react-native-skia 1.11.11 → 1.12.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/android/build.gradle +10 -0
- package/cpp/rnskia/DawnContext.h +1 -1
- package/lib/commonjs/sksg/Recorder/Core.d.ts +1 -5
- package/lib/commonjs/sksg/Recorder/Core.js +12 -4
- package/lib/commonjs/sksg/Recorder/Core.js.map +1 -1
- package/lib/commonjs/sksg/Recorder/Player.js +4 -5
- package/lib/commonjs/sksg/Recorder/Player.js.map +1 -1
- package/lib/commonjs/sksg/Recorder/commands/Box.js +2 -4
- package/lib/commonjs/sksg/Recorder/commands/Box.js.map +1 -1
- package/lib/commonjs/specs/NativeSkiaModule.web.d.ts +2 -0
- package/lib/commonjs/specs/NativeSkiaModule.web.js +10 -1
- package/lib/commonjs/specs/NativeSkiaModule.web.js.map +1 -1
- package/lib/module/sksg/Recorder/Core.d.ts +1 -5
- package/lib/module/sksg/Recorder/Core.js +10 -2
- package/lib/module/sksg/Recorder/Core.js.map +1 -1
- package/lib/module/sksg/Recorder/Player.js +5 -6
- package/lib/module/sksg/Recorder/Player.js.map +1 -1
- package/lib/module/sksg/Recorder/commands/Box.js +3 -5
- package/lib/module/sksg/Recorder/commands/Box.js.map +1 -1
- package/lib/module/specs/NativeSkiaModule.web.d.ts +2 -0
- package/lib/module/specs/NativeSkiaModule.web.js +10 -1
- package/lib/module/specs/NativeSkiaModule.web.js.map +1 -1
- package/lib/typescript/lib/commonjs/sksg/Recorder/Core.d.ts +1 -1
- package/lib/typescript/lib/module/sksg/Recorder/Core.d.ts +1 -1
- package/lib/typescript/src/sksg/Recorder/Core.d.ts +1 -5
- package/lib/typescript/src/specs/NativeSkiaModule.web.d.ts +2 -0
- package/package.json +5 -4
- package/react-native-skia.podspec +3 -3
- package/src/sksg/Recorder/Core.ts +5 -7
- package/src/sksg/Recorder/Player.ts +5 -6
- package/src/sksg/Recorder/commands/Box.ts +3 -5
- package/src/specs/NativeSkiaModule.web.ts +12 -2
- package/ios/RNSkia-iOS/MetalContext.h +0 -134
- package/ios/RNSkia-iOS/MetalContext.mm +0 -34
- package/ios/RNSkia-iOS/MetalWindowContext.h +0 -39
- package/ios/RNSkia-iOS/MetalWindowContext.mm +0 -60
- package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.h +0 -38
- package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm +0 -103
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +0 -75
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +0 -303
- package/ios/RNSkia-iOS/RNSkiOSVideo.h +0 -51
- package/ios/RNSkia-iOS/RNSkiOSVideo.mm +0 -137
- package/ios/RNSkia-iOS/RNSkiOSView.h +0 -37
- package/ios/RNSkia-iOS/RNSkiOSView.mm +0 -35
- package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.h +0 -119
- package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +0 -344
- package/ios/RNSkia-iOS/SkiaManager.h +0 -25
- package/ios/RNSkia-iOS/SkiaManager.mm +0 -62
- package/ios/RNSkia-iOS/SkiaPictureView.h +0 -7
- package/ios/RNSkia-iOS/SkiaPictureView.mm +0 -66
- package/ios/RNSkia-iOS/SkiaPictureViewManager.h +0 -8
- package/ios/RNSkia-iOS/SkiaPictureViewManager.mm +0 -51
- package/ios/RNSkia-iOS/SkiaUIView.h +0 -37
- package/ios/RNSkia-iOS/SkiaUIView.mm +0 -168
- package/ios/RNSkia-iOS/ViewScreenshotService.h +0 -21
- package/ios/RNSkia-iOS/ViewScreenshotService.mm +0 -85
- package/ios/RNSkiaModule.h +0 -20
- package/ios/RNSkiaModule.mm +0 -55
- package/ios/Rnskia.xcodeproj/project.pbxproj +0 -281
- package/ios/Rnskia.xcworkspace/contents.xcworkspacedata +0 -7
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["global","SkiaViewApi","views","web","registerView","nativeId","view","setJsiProperty","name","value","
|
1
|
+
{"version":3,"names":["global","SkiaViewApi","views","deferedPictures","web","registerView","nativeId","view","setPicture","setJsiProperty","name","value","requestRedraw","redraw","makeImageSnapshot","rect","makeImageSnapshotAsync","Promise","resolve","reject","result","Error"],"sources":["NativeSkiaModule.web.ts"],"sourcesContent":["/* eslint-disable import/no-anonymous-default-export */\nimport type { SkPicture, SkRect } from \"../skia/types\";\nimport type { ISkiaViewApi } from \"../views/types\";\nimport type { SkiaPictureView } from \"../views/SkiaPictureView.web\";\n\nexport type ISkiaViewApiWeb = ISkiaViewApi & {\n views: Record<string, SkiaPictureView>;\n deferedPictures: Record<string, SkPicture>;\n registerView(nativeId: string, view: SkiaPictureView): void;\n};\n\nglobal.SkiaViewApi = {\n views: {},\n deferedPictures: {},\n web: true,\n registerView(nativeId: string, view: SkiaPictureView) {\n // Maybe a picture for this view was already set\n if (this.deferedPictures[nativeId]) {\n view.setPicture(this.deferedPictures[nativeId] as SkPicture);\n }\n this.views[nativeId] = view;\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setJsiProperty(nativeId: number, name: string, value: any) {\n if (name === \"picture\") {\n if (!this.views[`${nativeId}`]) {\n this.deferedPictures[`${nativeId}`] = value;\n } else {\n this.views[`${nativeId}`].setPicture(value);\n }\n }\n },\n requestRedraw(nativeId: number) {\n this.views[`${nativeId}`].redraw();\n },\n makeImageSnapshot(nativeId: number, rect?: SkRect) {\n return this.views[`${nativeId}`].makeImageSnapshot(rect);\n },\n makeImageSnapshotAsync(nativeId: number, rect?: SkRect) {\n return new Promise((resolve, reject) => {\n const result = this.views[`${nativeId}`].makeImageSnapshot(rect);\n if (result) {\n resolve(result);\n } else {\n reject(new Error(\"Failed to make image snapshot\"));\n }\n });\n },\n} as ISkiaViewApiWeb;\n\n// eslint-disable-next-line import/no-default-export\nexport default {};\n"],"mappings":"AAAA;;AAWAA,MAAM,CAACC,WAAW,GAAG;EACnBC,KAAK,EAAE,CAAC,CAAC;EACTC,eAAe,EAAE,CAAC,CAAC;EACnBC,GAAG,EAAE,IAAI;EACTC,YAAYA,CAACC,QAAgB,EAAEC,IAAqB,EAAE;IACpD;IACA,IAAI,IAAI,CAACJ,eAAe,CAACG,QAAQ,CAAC,EAAE;MAClCC,IAAI,CAACC,UAAU,CAAC,IAAI,CAACL,eAAe,CAACG,QAAQ,CAAc,CAAC;IAC9D;IACA,IAAI,CAACJ,KAAK,CAACI,QAAQ,CAAC,GAAGC,IAAI;EAC7B,CAAC;EACD;EACAE,cAAcA,CAACH,QAAgB,EAAEI,IAAY,EAAEC,KAAU,EAAE;IACzD,IAAID,IAAI,KAAK,SAAS,EAAE;MACtB,IAAI,CAAC,IAAI,CAACR,KAAK,CAAC,GAAGI,QAAQ,EAAE,CAAC,EAAE;QAC9B,IAAI,CAACH,eAAe,CAAC,GAAGG,QAAQ,EAAE,CAAC,GAAGK,KAAK;MAC7C,CAAC,MAAM;QACL,IAAI,CAACT,KAAK,CAAC,GAAGI,QAAQ,EAAE,CAAC,CAACE,UAAU,CAACG,KAAK,CAAC;MAC7C;IACF;EACF,CAAC;EACDC,aAAaA,CAACN,QAAgB,EAAE;IAC9B,IAAI,CAACJ,KAAK,CAAC,GAAGI,QAAQ,EAAE,CAAC,CAACO,MAAM,CAAC,CAAC;EACpC,CAAC;EACDC,iBAAiBA,CAACR,QAAgB,EAAES,IAAa,EAAE;IACjD,OAAO,IAAI,CAACb,KAAK,CAAC,GAAGI,QAAQ,EAAE,CAAC,CAACQ,iBAAiB,CAACC,IAAI,CAAC;EAC1D,CAAC;EACDC,sBAAsBA,CAACV,QAAgB,EAAES,IAAa,EAAE;IACtD,OAAO,IAAIE,OAAO,CAAC,CAACC,OAAO,EAAEC,MAAM,KAAK;MACtC,MAAMC,MAAM,GAAG,IAAI,CAAClB,KAAK,CAAC,GAAGI,QAAQ,EAAE,CAAC,CAACQ,iBAAiB,CAACC,IAAI,CAAC;MAChE,IAAIK,MAAM,EAAE;QACVF,OAAO,CAACE,MAAM,CAAC;MACjB,CAAC,MAAM;QACLD,MAAM,CAAC,IAAIE,KAAK,CAAC,+BAA+B,CAAC,CAAC;MACpD;IACF,CAAC,CAAC;EACJ;AACF,CAAoB;;AAEpB;AACA,eAAe,CAAC,CAAC","ignoreList":[]}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
export const __esModule: boolean;
|
2
2
|
export const CommandType: {};
|
3
|
-
export function
|
3
|
+
export function materializeCommand(command: any): any;
|
4
4
|
export function isCommand(command: any, type: any): boolean;
|
5
5
|
export function isGroup(command: any): boolean;
|
6
6
|
export function isDrawCommand(command: any, type: any): boolean;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
export let CommandType: {};
|
2
|
-
export function
|
2
|
+
export function materializeCommand(command: any): any;
|
3
3
|
export function isCommand(command: any, type: any): boolean;
|
4
4
|
export function isGroup(command: any): boolean;
|
5
5
|
export function isDrawCommand(command: any, type: any): boolean;
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import type { SharedValue } from "react-native-reanimated";
|
2
1
|
import type { BlurMaskFilterProps, CircleProps, CTMProps, ImageProps, PointsProps, PathProps, RectProps, RoundedRectProps, OvalProps, LineProps, PatchProps, VerticesProps, DiffRectProps, TextProps, TextPathProps, TextBlobProps, GlyphsProps, PictureProps, ImageSVGProps, ParagraphProps, AtlasProps, DrawingNodeProps } from "../../dom/types";
|
3
2
|
export declare enum CommandType {
|
4
3
|
Group = 0,
|
@@ -44,10 +43,7 @@ export type Command<T extends CommandType = CommandType> = {
|
|
44
43
|
type: T;
|
45
44
|
[key: string]: unknown;
|
46
45
|
};
|
47
|
-
export declare const
|
48
|
-
props: Record<string, unknown>;
|
49
|
-
animatedProps?: Record<string, SharedValue<unknown>>;
|
50
|
-
}) => void;
|
46
|
+
export declare const materializeCommand: (command: any) => any;
|
51
47
|
export declare const isCommand: <T extends CommandType>(command: Command, type: T) => command is Command<T>;
|
52
48
|
interface GroupCommand extends Command<CommandType.Group> {
|
53
49
|
children: Command[];
|
@@ -1,7 +1,9 @@
|
|
1
|
+
import type { SkPicture } from "../skia/types";
|
1
2
|
import type { ISkiaViewApi } from "../views/types";
|
2
3
|
import type { SkiaPictureView } from "../views/SkiaPictureView.web";
|
3
4
|
export type ISkiaViewApiWeb = ISkiaViewApi & {
|
4
5
|
views: Record<string, SkiaPictureView>;
|
6
|
+
deferedPictures: Record<string, SkPicture>;
|
5
7
|
registerView(nativeId: string, view: SkiaPictureView): void;
|
6
8
|
};
|
7
9
|
declare const _default: {};
|
package/package.json
CHANGED
@@ -5,10 +5,10 @@
|
|
5
5
|
"provenance": true
|
6
6
|
},
|
7
7
|
"bin": {
|
8
|
-
"setup-skia-web": "
|
8
|
+
"setup-skia-web": "scripts/setup-canvaskit.js"
|
9
9
|
},
|
10
10
|
"title": "React Native Skia",
|
11
|
-
"version": "1.
|
11
|
+
"version": "1.12.0",
|
12
12
|
"description": "High-performance React Native Graphics using Skia",
|
13
13
|
"main": "lib/module/index.js",
|
14
14
|
"react-native": "src/index.ts",
|
@@ -76,8 +76,8 @@
|
|
76
76
|
"licenseFilename": "LICENSE.md",
|
77
77
|
"readmeFilename": "README.md",
|
78
78
|
"peerDependencies": {
|
79
|
-
"react": ">=18.0",
|
80
|
-
"react-native": ">=0.64",
|
79
|
+
"react": ">=18.0 <19.0.0",
|
80
|
+
"react-native": ">=0.64 <0.78.0",
|
81
81
|
"react-native-reanimated": ">=2.0.0"
|
82
82
|
},
|
83
83
|
"peerDependenciesMeta": {
|
@@ -91,6 +91,7 @@
|
|
91
91
|
"devDependencies": {
|
92
92
|
"@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
|
93
93
|
"@semantic-release/commit-analyzer": "^13.0.0",
|
94
|
+
"@semantic-release/exec": "^7.0.3",
|
94
95
|
"@semantic-release/github": "^10.3.3",
|
95
96
|
"@semantic-release/release-notes-generator": "^14.0.1",
|
96
97
|
"@types/jest": "29.5.6",
|
@@ -41,7 +41,7 @@ Pod::Spec.new do |s|
|
|
41
41
|
"Christian Falch" => "christian.falch@gmail.com",
|
42
42
|
"William Candillon" => "wcandillon@gmail.com"
|
43
43
|
}
|
44
|
-
s.platforms = { :ios => "13.0", :tvos => "13.0" }
|
44
|
+
s.platforms = { :ios => "13.0", :tvos => "13.0", :osx => "11" }
|
45
45
|
s.source = { :git => "https://github.com/shopify/react-native-skia/react-native-skia.git", :tag => "#{s.version}" }
|
46
46
|
|
47
47
|
s.requires_arc = true
|
@@ -54,13 +54,13 @@ Pod::Spec.new do |s|
|
|
54
54
|
|
55
55
|
s.frameworks = ['MetalKit', 'AVFoundation', 'AVKit', 'CoreMedia']
|
56
56
|
|
57
|
-
s.vendored_frameworks = use_graphite ?
|
57
|
+
s.vendored_frameworks = use_graphite ?
|
58
58
|
base_frameworks + graphite_frameworks :
|
59
59
|
base_frameworks
|
60
60
|
|
61
61
|
# All iOS cpp/h files
|
62
62
|
s.source_files = [
|
63
|
-
"
|
63
|
+
"apple/**/*.{h,c,cc,cpp,m,mm,swift}",
|
64
64
|
"cpp/**/*.{h,cpp}"
|
65
65
|
]
|
66
66
|
|
@@ -1,5 +1,3 @@
|
|
1
|
-
import type { SharedValue } from "react-native-reanimated";
|
2
|
-
|
3
1
|
import type {
|
4
2
|
BlurMaskFilterProps,
|
5
3
|
CircleProps,
|
@@ -115,16 +113,16 @@ export type Command<T extends CommandType = CommandType> = {
|
|
115
113
|
[key: string]: unknown;
|
116
114
|
};
|
117
115
|
|
118
|
-
|
119
|
-
|
120
|
-
animatedProps?: Record<string, SharedValue<unknown>>;
|
121
|
-
}) => {
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
117
|
+
export const materializeCommand = (command: any) => {
|
122
118
|
"worklet";
|
119
|
+
const newProps = { ...command.props };
|
123
120
|
if (command.animatedProps) {
|
124
121
|
for (const key in command.animatedProps) {
|
125
|
-
|
122
|
+
newProps[key] = command.animatedProps[key].value;
|
126
123
|
}
|
127
124
|
}
|
125
|
+
return { ...command, props: newProps };
|
128
126
|
};
|
129
127
|
|
130
128
|
export const isCommand = <T extends CommandType>(
|
@@ -44,19 +44,18 @@ import {
|
|
44
44
|
isCommand,
|
45
45
|
isDrawCommand,
|
46
46
|
isGroup,
|
47
|
-
|
47
|
+
materializeCommand,
|
48
48
|
type Command,
|
49
49
|
} from "./Core";
|
50
50
|
import type { DrawingContext } from "./DrawingContext";
|
51
51
|
|
52
|
-
function play(ctx: DrawingContext,
|
52
|
+
function play(ctx: DrawingContext, _command: Command) {
|
53
53
|
"worklet";
|
54
|
-
if (isGroup(
|
55
|
-
|
54
|
+
if (isGroup(_command)) {
|
55
|
+
_command.children.forEach((child) => play(ctx, child));
|
56
56
|
return;
|
57
57
|
}
|
58
|
-
|
59
|
-
materializeProps(command as any);
|
58
|
+
const command = materializeCommand(_command);
|
60
59
|
if (isCommand(command, CommandType.SaveBackdropFilter)) {
|
61
60
|
ctx.saveBackdropFilter();
|
62
61
|
} else if (isCommand(command, CommandType.SaveLayer)) {
|
@@ -2,7 +2,7 @@ import { deflate, inflate, processColor } from "../../../dom/nodes";
|
|
2
2
|
import type { BoxProps, BoxShadowProps } from "../../../dom/types";
|
3
3
|
import { BlurStyle, ClipOp, isRRect } from "../../../skia/types";
|
4
4
|
import type { Command } from "../Core";
|
5
|
-
import { CommandType,
|
5
|
+
import { CommandType, materializeCommand } from "../Core";
|
6
6
|
import type { DrawingContext } from "../DrawingContext";
|
7
7
|
|
8
8
|
interface BoxCommand extends Command<CommandType.DrawBox> {
|
@@ -17,11 +17,9 @@ export const isBoxCommand = (command: Command): command is BoxCommand => {
|
|
17
17
|
|
18
18
|
export const drawBox = (ctx: DrawingContext, command: BoxCommand) => {
|
19
19
|
"worklet";
|
20
|
-
command.shadows.
|
21
|
-
|
22
|
-
materializeProps(shadow as any);
|
20
|
+
const shadows = command.shadows.map((shadow) => {
|
21
|
+
return materializeCommand(shadow).props;
|
23
22
|
});
|
24
|
-
const shadows = command.shadows.map((shadow) => shadow.props);
|
25
23
|
const { paint, Skia, canvas } = ctx;
|
26
24
|
const { box: defaultBox } = command.props;
|
27
25
|
const opacity = paint.getAlphaf();
|
@@ -1,23 +1,33 @@
|
|
1
1
|
/* eslint-disable import/no-anonymous-default-export */
|
2
|
-
import type { SkRect } from "../skia/types";
|
2
|
+
import type { SkPicture, SkRect } from "../skia/types";
|
3
3
|
import type { ISkiaViewApi } from "../views/types";
|
4
4
|
import type { SkiaPictureView } from "../views/SkiaPictureView.web";
|
5
5
|
|
6
6
|
export type ISkiaViewApiWeb = ISkiaViewApi & {
|
7
7
|
views: Record<string, SkiaPictureView>;
|
8
|
+
deferedPictures: Record<string, SkPicture>;
|
8
9
|
registerView(nativeId: string, view: SkiaPictureView): void;
|
9
10
|
};
|
10
11
|
|
11
12
|
global.SkiaViewApi = {
|
12
13
|
views: {},
|
14
|
+
deferedPictures: {},
|
13
15
|
web: true,
|
14
16
|
registerView(nativeId: string, view: SkiaPictureView) {
|
17
|
+
// Maybe a picture for this view was already set
|
18
|
+
if (this.deferedPictures[nativeId]) {
|
19
|
+
view.setPicture(this.deferedPictures[nativeId] as SkPicture);
|
20
|
+
}
|
15
21
|
this.views[nativeId] = view;
|
16
22
|
},
|
17
23
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
18
24
|
setJsiProperty(nativeId: number, name: string, value: any) {
|
19
25
|
if (name === "picture") {
|
20
|
-
this.views[`${nativeId}`]
|
26
|
+
if (!this.views[`${nativeId}`]) {
|
27
|
+
this.deferedPictures[`${nativeId}`] = value;
|
28
|
+
} else {
|
29
|
+
this.views[`${nativeId}`].setPicture(value);
|
30
|
+
}
|
21
31
|
}
|
22
32
|
},
|
23
33
|
requestRedraw(nativeId: number) {
|
@@ -1,134 +0,0 @@
|
|
1
|
-
#pragma once
|
2
|
-
|
3
|
-
#include "MetalWindowContext.h"
|
4
|
-
#include "SkiaCVPixelBufferUtils.h"
|
5
|
-
|
6
|
-
#include "include/core/SkSurface.h"
|
7
|
-
|
8
|
-
#import <include/gpu/ganesh/GrBackendSurface.h>
|
9
|
-
#import <include/gpu/ganesh/GrDirectContext.h>
|
10
|
-
#import <include/gpu/ganesh/SkImageGanesh.h>
|
11
|
-
#import <include/gpu/ganesh/SkSurfaceGanesh.h>
|
12
|
-
#import <include/gpu/ganesh/mtl/GrMtlBackendContext.h>
|
13
|
-
#import <include/gpu/ganesh/mtl/GrMtlBackendSurface.h>
|
14
|
-
#import <include/gpu/ganesh/mtl/GrMtlDirectContext.h>
|
15
|
-
#import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>
|
16
|
-
|
17
|
-
// namespace RNSkia {
|
18
|
-
// class RNSkiOSPlatformContext;
|
19
|
-
// }
|
20
|
-
|
21
|
-
class MetalSharedContext {
|
22
|
-
public:
|
23
|
-
static MetalSharedContext &getInstance() {
|
24
|
-
static MetalSharedContext instance;
|
25
|
-
return instance;
|
26
|
-
}
|
27
|
-
|
28
|
-
id<MTLDevice> getDevice() { return _device; }
|
29
|
-
|
30
|
-
private:
|
31
|
-
MetalSharedContext() {
|
32
|
-
_device = MTLCreateSystemDefaultDevice();
|
33
|
-
if (!_device) {
|
34
|
-
throw std::runtime_error("Failed to create Metal device");
|
35
|
-
}
|
36
|
-
}
|
37
|
-
|
38
|
-
MetalSharedContext(const MetalSharedContext &) = delete;
|
39
|
-
MetalSharedContext &operator=(const MetalSharedContext &) = delete;
|
40
|
-
|
41
|
-
id<MTLDevice> _device;
|
42
|
-
};
|
43
|
-
|
44
|
-
struct OffscreenRenderContext {
|
45
|
-
id<MTLTexture> texture;
|
46
|
-
|
47
|
-
OffscreenRenderContext(id<MTLDevice> device,
|
48
|
-
sk_sp<GrDirectContext> skiaContext,
|
49
|
-
id<MTLCommandQueue> commandQueue, int width,
|
50
|
-
int height) {
|
51
|
-
// Create a Metal texture descriptor
|
52
|
-
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor
|
53
|
-
texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
|
54
|
-
width:width
|
55
|
-
height:height
|
56
|
-
mipmapped:NO];
|
57
|
-
textureDescriptor.usage =
|
58
|
-
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
|
59
|
-
texture = [device newTextureWithDescriptor:textureDescriptor];
|
60
|
-
}
|
61
|
-
};
|
62
|
-
|
63
|
-
class MetalContext {
|
64
|
-
|
65
|
-
public:
|
66
|
-
MetalContext(const MetalContext &) = delete;
|
67
|
-
MetalContext &operator=(const MetalContext &) = delete;
|
68
|
-
|
69
|
-
static MetalContext &getInstance() {
|
70
|
-
static thread_local MetalContext instance;
|
71
|
-
return instance;
|
72
|
-
}
|
73
|
-
|
74
|
-
sk_sp<SkSurface> MakeOffscreen(int width, int height) {
|
75
|
-
auto device = MetalSharedContext::getInstance().getDevice();
|
76
|
-
auto ctx = new OffscreenRenderContext(device, _directContext, _commandQueue,
|
77
|
-
width, height);
|
78
|
-
|
79
|
-
// Create a GrBackendTexture from the Metal texture
|
80
|
-
GrMtlTextureInfo info;
|
81
|
-
info.fTexture.retain((__bridge void *)ctx->texture);
|
82
|
-
GrBackendTexture backendTexture =
|
83
|
-
GrBackendTextures::MakeMtl(width, height, skgpu::Mipmapped::kNo, info);
|
84
|
-
|
85
|
-
// Create a SkSurface from the GrBackendTexture
|
86
|
-
auto surface = SkSurfaces::WrapBackendTexture(
|
87
|
-
_directContext.get(), backendTexture, kTopLeft_GrSurfaceOrigin, 0,
|
88
|
-
kBGRA_8888_SkColorType, nullptr, nullptr,
|
89
|
-
[](void *addr) { delete (OffscreenRenderContext *)addr; }, ctx);
|
90
|
-
|
91
|
-
return surface;
|
92
|
-
}
|
93
|
-
|
94
|
-
sk_sp<SkImage> MakeImageFromBuffer(void *buffer) {
|
95
|
-
|
96
|
-
CVPixelBufferRef sampleBuffer = (CVPixelBufferRef)buffer;
|
97
|
-
SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat format =
|
98
|
-
SkiaCVPixelBufferUtils::getCVPixelBufferBaseFormat(sampleBuffer);
|
99
|
-
switch (format) {
|
100
|
-
case SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat::rgb: {
|
101
|
-
// CVPixelBuffer is in any RGB format, single-plane
|
102
|
-
return SkiaCVPixelBufferUtils::RGB::makeSkImageFromCVPixelBuffer(
|
103
|
-
_directContext.get(), sampleBuffer);
|
104
|
-
}
|
105
|
-
case SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat::yuv: {
|
106
|
-
// CVPixelBuffer is in any YUV format, multi-plane
|
107
|
-
return SkiaCVPixelBufferUtils::YUV::makeSkImageFromCVPixelBuffer(
|
108
|
-
_directContext.get(), sampleBuffer);
|
109
|
-
}
|
110
|
-
default:
|
111
|
-
[[unlikely]] {
|
112
|
-
throw std::runtime_error("Failed to convert NativeBuffer to SkImage - "
|
113
|
-
"NativeBuffer has unsupported PixelFormat! " +
|
114
|
-
std::to_string(static_cast<int>(format)));
|
115
|
-
}
|
116
|
-
}
|
117
|
-
}
|
118
|
-
|
119
|
-
std::unique_ptr<RNSkia::WindowContext> MakeWindow(CALayer *window, int width,
|
120
|
-
int height) {
|
121
|
-
auto device = MetalSharedContext::getInstance().getDevice();
|
122
|
-
return std::make_unique<MetalWindowContext>(
|
123
|
-
_directContext.get(), device, _commandQueue, window, width, height);
|
124
|
-
}
|
125
|
-
|
126
|
-
GrDirectContext *getDirectContext() { return _directContext.get(); }
|
127
|
-
|
128
|
-
private:
|
129
|
-
// friend class RNSkia::RNSkiOSPlatformContext;
|
130
|
-
id<MTLCommandQueue> _commandQueue = nullptr;
|
131
|
-
sk_sp<GrDirectContext> _directContext = nullptr;
|
132
|
-
|
133
|
-
MetalContext();
|
134
|
-
};
|
@@ -1,34 +0,0 @@
|
|
1
|
-
#include "MetalContext.h"
|
2
|
-
|
3
|
-
#include "RNSkLog.h"
|
4
|
-
|
5
|
-
#import <MetalKit/MetalKit.h>
|
6
|
-
|
7
|
-
#pragma clang diagnostic push
|
8
|
-
#pragma clang diagnostic ignored "-Wdocumentation"
|
9
|
-
|
10
|
-
#import <include/gpu/ganesh/GrBackendSurface.h>
|
11
|
-
#import <include/gpu/ganesh/SkImageGanesh.h>
|
12
|
-
#import <include/gpu/ganesh/mtl/GrMtlBackendContext.h>
|
13
|
-
#import <include/gpu/ganesh/mtl/GrMtlBackendSurface.h>
|
14
|
-
#import <include/gpu/ganesh/mtl/GrMtlDirectContext.h>
|
15
|
-
#import <include/gpu/ganesh/mtl/GrMtlTypes.h>
|
16
|
-
#import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>
|
17
|
-
|
18
|
-
#pragma clang diagnostic pop
|
19
|
-
|
20
|
-
MetalContext::MetalContext() {
|
21
|
-
auto device = MetalSharedContext::getInstance().getDevice();
|
22
|
-
_commandQueue =
|
23
|
-
id<MTLCommandQueue>(CFRetain((GrMTLHandle)[device newCommandQueue]));
|
24
|
-
GrMtlBackendContext backendContext = {};
|
25
|
-
backendContext.fDevice.reset((__bridge void *)device);
|
26
|
-
backendContext.fQueue.reset((__bridge void *)_commandQueue);
|
27
|
-
GrContextOptions grContextOptions; // set different options here.
|
28
|
-
|
29
|
-
// Create the Skia Direct Context
|
30
|
-
_directContext = GrDirectContexts::MakeMetal(backendContext);
|
31
|
-
if (_directContext == nullptr) {
|
32
|
-
RNSkia::RNSkLogger::logToConsole("Couldn't create a Skia Metal Context");
|
33
|
-
}
|
34
|
-
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
#pragma once
|
2
|
-
|
3
|
-
#import <MetalKit/MetalKit.h>
|
4
|
-
|
5
|
-
#include "WindowContext.h"
|
6
|
-
|
7
|
-
class SkiaMetalContext;
|
8
|
-
|
9
|
-
class MetalWindowContext : public RNSkia::WindowContext {
|
10
|
-
public:
|
11
|
-
MetalWindowContext(GrDirectContext *directContext, id<MTLDevice> device,
|
12
|
-
id<MTLCommandQueue> commandQueue, CALayer *layer,
|
13
|
-
int width, int height);
|
14
|
-
~MetalWindowContext() = default;
|
15
|
-
|
16
|
-
sk_sp<SkSurface> getSurface() override;
|
17
|
-
|
18
|
-
void present() override;
|
19
|
-
|
20
|
-
int getWidth() override {
|
21
|
-
return _layer.frame.size.width * _layer.contentsScale;
|
22
|
-
};
|
23
|
-
|
24
|
-
int getHeight() override {
|
25
|
-
return _layer.frame.size.height * _layer.contentsScale;
|
26
|
-
};
|
27
|
-
|
28
|
-
void resize(int width, int height) override { _skSurface = nullptr; }
|
29
|
-
|
30
|
-
private:
|
31
|
-
GrDirectContext *_directContext;
|
32
|
-
id<MTLCommandQueue> _commandQueue;
|
33
|
-
sk_sp<SkSurface> _skSurface = nullptr;
|
34
|
-
#pragma clang diagnostic push
|
35
|
-
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
36
|
-
CAMetalLayer *_layer;
|
37
|
-
#pragma clang diagnostic pop
|
38
|
-
id<CAMetalDrawable> _currentDrawable = nil;
|
39
|
-
};
|
@@ -1,60 +0,0 @@
|
|
1
|
-
#include "MetalWindowContext.h"
|
2
|
-
|
3
|
-
#include "MetalContext.h"
|
4
|
-
#include "RNSkLog.h"
|
5
|
-
|
6
|
-
MetalWindowContext::MetalWindowContext(GrDirectContext *directContext,
|
7
|
-
id<MTLDevice> device,
|
8
|
-
id<MTLCommandQueue> commandQueue,
|
9
|
-
CALayer *layer, int width, int height)
|
10
|
-
: _directContext(directContext), _commandQueue(commandQueue) {
|
11
|
-
#pragma clang diagnostic push
|
12
|
-
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
13
|
-
_layer = (CAMetalLayer *)layer;
|
14
|
-
#pragma clang diagnostic pop
|
15
|
-
_layer.framebufferOnly = NO;
|
16
|
-
_layer.device = device;
|
17
|
-
_layer.opaque = false;
|
18
|
-
_layer.contentsScale = [UIScreen mainScreen].scale;
|
19
|
-
_layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
20
|
-
_layer.contentsGravity = kCAGravityBottomLeft;
|
21
|
-
_layer.drawableSize = CGSizeMake(width, height);
|
22
|
-
}
|
23
|
-
|
24
|
-
sk_sp<SkSurface> MetalWindowContext::getSurface() {
|
25
|
-
if (_skSurface) {
|
26
|
-
return _skSurface;
|
27
|
-
}
|
28
|
-
|
29
|
-
// Get the next drawable from the CAMetalLayer
|
30
|
-
_currentDrawable = [_layer nextDrawable];
|
31
|
-
if (!_currentDrawable) {
|
32
|
-
RNSkia::RNSkLogger::logToConsole(
|
33
|
-
"Could not retrieve drawable from CAMetalLayer");
|
34
|
-
return nullptr;
|
35
|
-
}
|
36
|
-
|
37
|
-
// Get the texture from the drawable
|
38
|
-
GrMtlTextureInfo fbInfo;
|
39
|
-
fbInfo.fTexture.retain((__bridge void *)_currentDrawable.texture);
|
40
|
-
|
41
|
-
GrBackendRenderTarget backendRT = GrBackendRenderTargets::MakeMtl(
|
42
|
-
_layer.drawableSize.width, _layer.drawableSize.height, fbInfo);
|
43
|
-
|
44
|
-
_skSurface = SkSurfaces::WrapBackendRenderTarget(
|
45
|
-
_directContext, backendRT, kTopLeft_GrSurfaceOrigin,
|
46
|
-
kBGRA_8888_SkColorType, nullptr, nullptr);
|
47
|
-
|
48
|
-
return _skSurface;
|
49
|
-
}
|
50
|
-
|
51
|
-
void MetalWindowContext::present() {
|
52
|
-
if (auto dContext = GrAsDirectContext(_skSurface->recordingContext())) {
|
53
|
-
dContext->flushAndSubmit();
|
54
|
-
}
|
55
|
-
|
56
|
-
id<MTLCommandBuffer> commandBuffer([_commandQueue commandBuffer]);
|
57
|
-
[commandBuffer presentDrawable:_currentDrawable];
|
58
|
-
[commandBuffer commit];
|
59
|
-
_skSurface = nullptr;
|
60
|
-
}
|
@@ -1,38 +0,0 @@
|
|
1
|
-
#pragma once
|
2
|
-
|
3
|
-
#import "RNSkPlatformContext.h"
|
4
|
-
#import "RNSkView.h"
|
5
|
-
|
6
|
-
#import <MetalKit/MetalKit.h>
|
7
|
-
#import <QuartzCore/CAMetalLayer.h>
|
8
|
-
|
9
|
-
#pragma clang diagnostic push
|
10
|
-
#pragma clang diagnostic ignored "-Wdocumentation"
|
11
|
-
|
12
|
-
#import <include/gpu/ganesh/GrDirectContext.h>
|
13
|
-
|
14
|
-
#pragma clang diagnostic pop
|
15
|
-
|
16
|
-
class RNSkMetalCanvasProvider : public RNSkia::RNSkCanvasProvider {
|
17
|
-
public:
|
18
|
-
RNSkMetalCanvasProvider(std::function<void()> requestRedraw,
|
19
|
-
std::shared_ptr<RNSkia::RNSkPlatformContext> context);
|
20
|
-
|
21
|
-
~RNSkMetalCanvasProvider();
|
22
|
-
|
23
|
-
int getScaledWidth() override;
|
24
|
-
int getScaledHeight() override;
|
25
|
-
|
26
|
-
bool renderToCanvas(const std::function<void(SkCanvas *)> &cb) override;
|
27
|
-
|
28
|
-
void setSize(int width, int height);
|
29
|
-
CALayer *getLayer();
|
30
|
-
|
31
|
-
private:
|
32
|
-
std::shared_ptr<RNSkia::RNSkPlatformContext> _context;
|
33
|
-
std::unique_ptr<RNSkia::WindowContext> _ctx = nullptr;
|
34
|
-
#pragma clang diagnostic push
|
35
|
-
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
36
|
-
CAMetalLayer *_layer;
|
37
|
-
#pragma clang diagnostic pop
|
38
|
-
};
|
@@ -1,103 +0,0 @@
|
|
1
|
-
#import "RNSkMetalCanvasProvider.h"
|
2
|
-
|
3
|
-
#import "RNSkLog.h"
|
4
|
-
|
5
|
-
#if defined(SK_GRAPHITE)
|
6
|
-
#import "DawnContext.h"
|
7
|
-
#else
|
8
|
-
#import "MetalContext.h"
|
9
|
-
#endif
|
10
|
-
|
11
|
-
#pragma clang diagnostic push
|
12
|
-
#pragma clang diagnostic ignored "-Wdocumentation"
|
13
|
-
|
14
|
-
#import "include/core/SkCanvas.h"
|
15
|
-
#import "include/core/SkColorSpace.h"
|
16
|
-
#import "include/core/SkSurface.h"
|
17
|
-
|
18
|
-
#import <include/gpu/ganesh/GrBackendSurface.h>
|
19
|
-
#import <include/gpu/ganesh/GrDirectContext.h>
|
20
|
-
#import <include/gpu/ganesh/SkSurfaceGanesh.h>
|
21
|
-
|
22
|
-
#pragma clang diagnostic pop
|
23
|
-
|
24
|
-
RNSkMetalCanvasProvider::RNSkMetalCanvasProvider(
|
25
|
-
std::function<void()> requestRedraw,
|
26
|
-
std::shared_ptr<RNSkia::RNSkPlatformContext> context)
|
27
|
-
: RNSkCanvasProvider(requestRedraw), _context(context) {
|
28
|
-
#pragma clang diagnostic push
|
29
|
-
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
30
|
-
_layer = [CAMetalLayer layer];
|
31
|
-
#pragma clang diagnostic pop
|
32
|
-
}
|
33
|
-
|
34
|
-
RNSkMetalCanvasProvider::~RNSkMetalCanvasProvider() {}
|
35
|
-
|
36
|
-
/**
|
37
|
-
Returns the scaled width of the view
|
38
|
-
*/
|
39
|
-
int RNSkMetalCanvasProvider::getScaledWidth() {
|
40
|
-
return _ctx ? _ctx->getWidth() : -1;
|
41
|
-
};
|
42
|
-
|
43
|
-
/**
|
44
|
-
Returns the scaled height of the view
|
45
|
-
*/
|
46
|
-
int RNSkMetalCanvasProvider::getScaledHeight() {
|
47
|
-
return _ctx ? _ctx->getHeight() : -1;
|
48
|
-
};
|
49
|
-
|
50
|
-
/**
|
51
|
-
Render to a canvas
|
52
|
-
*/
|
53
|
-
bool RNSkMetalCanvasProvider::renderToCanvas(
|
54
|
-
const std::function<void(SkCanvas *)> &cb) {
|
55
|
-
if (!_ctx) {
|
56
|
-
return false;
|
57
|
-
}
|
58
|
-
|
59
|
-
// Make sure to NOT render or try any render operations while we're in the
|
60
|
-
// background or inactive. This will cause an error that might clear the
|
61
|
-
// CAMetalLayer so that the canvas is empty when the app receives focus again.
|
62
|
-
// Reference: https://github.com/Shopify/react-native-skia/issues/1257
|
63
|
-
// NOTE: UIApplication.sharedApplication.applicationState can only be
|
64
|
-
// accessed from the main thread so we need to check here.
|
65
|
-
if ([[NSThread currentThread] isMainThread]) {
|
66
|
-
auto state = UIApplication.sharedApplication.applicationState;
|
67
|
-
if (state == UIApplicationStateBackground) {
|
68
|
-
// Request a redraw in the next run loop callback
|
69
|
-
_requestRedraw();
|
70
|
-
// and don't draw now since it might cause errors in the metal renderer if
|
71
|
-
// we try to render while in the background. (see above issue)
|
72
|
-
return false;
|
73
|
-
}
|
74
|
-
}
|
75
|
-
// Wrap in auto release pool since we want the system to clean up after
|
76
|
-
// rendering and not wait until later - we've seen some example of memory
|
77
|
-
// usage growing very fast in the simulator without this.
|
78
|
-
@autoreleasepool {
|
79
|
-
auto surface = _ctx->getSurface();
|
80
|
-
if (!surface) {
|
81
|
-
return false;
|
82
|
-
}
|
83
|
-
auto canvas = surface->getCanvas();
|
84
|
-
cb(canvas);
|
85
|
-
_ctx->present();
|
86
|
-
}
|
87
|
-
return true;
|
88
|
-
};
|
89
|
-
|
90
|
-
void RNSkMetalCanvasProvider::setSize(int width, int height) {
|
91
|
-
_layer.frame = CGRectMake(0, 0, width, height);
|
92
|
-
auto w = width * _context->getPixelDensity();
|
93
|
-
auto h = height * _context->getPixelDensity();
|
94
|
-
#if defined(SK_GRAPHITE)
|
95
|
-
_ctx = RNSkia::DawnContext::getInstance().MakeWindow((__bridge void *)_layer,
|
96
|
-
w, h);
|
97
|
-
#else
|
98
|
-
_ctx = MetalContext::getInstance().MakeWindow(_layer, w, h);
|
99
|
-
#endif
|
100
|
-
_requestRedraw();
|
101
|
-
}
|
102
|
-
|
103
|
-
CALayer *RNSkMetalCanvasProvider::getLayer() { return _layer; }
|