@shopify/react-native-skia 2.2.19 → 2.2.21
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/CMakeLists.txt +2 -0
- package/apple/SkiaCVPixelBufferUtils.mm +8 -4
- package/cpp/api/JsiSkCanvas.h +22 -0
- package/cpp/api/JsiSkDispatcher.cpp +9 -0
- package/cpp/api/JsiSkDispatcher.h +149 -0
- package/cpp/api/JsiSkImage.h +27 -9
- package/cpp/api/JsiSkPicture.h +22 -1
- package/cpp/api/JsiSkSurface.h +15 -10
- package/cpp/api/recorder/Drawings.h +43 -9
- package/cpp/api/recorder/JsiRecorder.h +3 -1
- package/cpp/api/recorder/RNRecorder.h +10 -4
- package/lib/commonjs/external/reanimated/textures.js +31 -28
- package/lib/commonjs/external/reanimated/textures.js.map +1 -1
- package/lib/commonjs/renderer/Offscreen.js +1 -7
- package/lib/commonjs/renderer/Offscreen.js.map +1 -1
- package/lib/commonjs/skia/core/SVG.web.d.ts +2 -2
- package/lib/commonjs/skia/core/SVG.web.js +23 -7
- package/lib/commonjs/skia/core/SVG.web.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.d.ts +1 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.js +7 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.d.ts +4 -0
- package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.js +4 -0
- package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.js.map +1 -1
- package/lib/module/external/reanimated/textures.js +33 -30
- package/lib/module/external/reanimated/textures.js.map +1 -1
- package/lib/module/renderer/Offscreen.js +1 -8
- package/lib/module/renderer/Offscreen.js.map +1 -1
- package/lib/module/skia/core/SVG.web.d.ts +2 -2
- package/lib/module/skia/core/SVG.web.js +23 -7
- package/lib/module/skia/core/SVG.web.js.map +1 -1
- package/lib/module/skia/web/JsiSkCanvas.d.ts +1 -1
- package/lib/module/skia/web/JsiSkCanvas.js +7 -1
- package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/module/sksg/Recorder/ReanimatedRecorder.d.ts +4 -0
- package/lib/module/sksg/Recorder/ReanimatedRecorder.js +5 -0
- package/lib/module/sksg/Recorder/ReanimatedRecorder.js.map +1 -1
- package/lib/typescript/lib/commonjs/skia/core/SVG.web.d.ts +1 -1
- package/lib/typescript/lib/commonjs/skia/web/JsiSkCanvas.d.ts +1 -1
- package/lib/typescript/lib/commonjs/sksg/Recorder/ReanimatedRecorder.d.ts +4 -0
- package/lib/typescript/lib/module/skia/core/SVG.web.d.ts +1 -1
- package/lib/typescript/lib/module/skia/web/JsiSkCanvas.d.ts +1 -1
- package/lib/typescript/lib/module/sksg/Recorder/ReanimatedRecorder.d.ts +4 -0
- package/lib/typescript/src/skia/core/SVG.web.d.ts +2 -2
- package/lib/typescript/src/skia/web/JsiSkCanvas.d.ts +1 -1
- package/lib/typescript/src/sksg/Recorder/ReanimatedRecorder.d.ts +4 -0
- package/package.json +6 -1
- package/src/external/reanimated/textures.tsx +36 -27
- package/src/renderer/Offscreen.tsx +1 -7
- package/src/skia/core/SVG.web.ts +35 -21
- package/src/skia/web/JsiSkCanvas.ts +3 -1
- package/src/sksg/Recorder/ReanimatedRecorder.ts +4 -0
- package/cpp/api/JsiSkThreadSafeDeletion.h +0 -105
package/src/skia/core/SVG.web.ts
CHANGED
@@ -1,32 +1,46 @@
|
|
1
|
+
import { useEffect, useState } from "react";
|
2
|
+
|
1
3
|
import { Skia } from "../Skia";
|
2
|
-
import type { DataSourceParam } from "../types";
|
4
|
+
import type { DataSourceParam, SkSVG } from "../types";
|
3
5
|
|
4
6
|
export const useSVG = (
|
5
7
|
source: DataSourceParam,
|
6
8
|
onError?: (err: Error) => void
|
7
9
|
) => {
|
10
|
+
const [svg, setSVG] = useState<SkSVG | null>(null);
|
8
11
|
if (source === null || source === undefined) {
|
9
12
|
throw new Error(`Invalid svg data source. Got: ${source}`);
|
10
13
|
}
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
source
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
14
|
+
useEffect(() => {
|
15
|
+
(async () => {
|
16
|
+
let src: string;
|
17
|
+
if (typeof source === "string") {
|
18
|
+
src = source;
|
19
|
+
} else if (
|
20
|
+
typeof source === "object" &&
|
21
|
+
"default" in source &&
|
22
|
+
typeof source.default === "string"
|
23
|
+
) {
|
24
|
+
src = source.default;
|
25
|
+
} else if (typeof source === "object" && "uri" in source) {
|
26
|
+
src = source.uri;
|
27
|
+
} else {
|
28
|
+
throw new Error(
|
29
|
+
`Invalid svg data source. Make sure that the source resolves to a string. Got: ${JSON.stringify(
|
30
|
+
source,
|
31
|
+
null,
|
32
|
+
2
|
33
|
+
)}`
|
34
|
+
);
|
35
|
+
}
|
36
|
+
const result = await fetch(src);
|
37
|
+
const svgStr = await result.text();
|
38
|
+
const newSvg = Skia.SVG.MakeFromString(svgStr);
|
39
|
+
setSVG(newSvg);
|
40
|
+
if (newSvg === null && onError !== undefined) {
|
41
|
+
onError(new Error("Failed to create SVG from source."));
|
42
|
+
}
|
43
|
+
})();
|
44
|
+
}, [onError, source]);
|
31
45
|
return svg;
|
32
46
|
};
|
@@ -305,7 +305,9 @@ export class JsiSkCanvas
|
|
305
305
|
);
|
306
306
|
}
|
307
307
|
|
308
|
-
drawSvg(svg: SkSVG,
|
308
|
+
drawSvg(svg: SkSVG, width?: number, height?: number) {
|
309
|
+
const ctm = this.ref.getLocalToDevice();
|
310
|
+
console.log({ ctm, width, height });
|
309
311
|
const image = this.CanvasKit.MakeImageFromCanvasImageSource(
|
310
312
|
(svg as JsiSkSVG).ref
|
311
313
|
);
|
@@ -32,6 +32,10 @@ import type {
|
|
32
32
|
import type { AnimatedProps } from "../../renderer";
|
33
33
|
import { isSharedValue } from "../utils";
|
34
34
|
|
35
|
+
/**
|
36
|
+
* Currently the recorder only work if the GPU resources (e.g Images) are owned by the main thread.
|
37
|
+
* It will crash otherwise on Ganesh (iOS/Android).
|
38
|
+
*/
|
35
39
|
export class ReanimatedRecorder implements BaseRecorder {
|
36
40
|
private values = new Set<SharedValue<unknown>>();
|
37
41
|
private recorder: JsiRecorder;
|
@@ -1,105 +0,0 @@
|
|
1
|
-
#pragma once
|
2
|
-
|
3
|
-
#include <functional>
|
4
|
-
#include <memory>
|
5
|
-
#include <mutex>
|
6
|
-
#include <queue>
|
7
|
-
#include <thread>
|
8
|
-
|
9
|
-
// Define this to disable thread-safe deletion (for testing purposes)
|
10
|
-
// #define DISABLE_THREAD_SAFE_DELETION
|
11
|
-
|
12
|
-
namespace RNSkia {
|
13
|
-
|
14
|
-
/**
|
15
|
-
* Utility class for managing thread-safe deletion of Skia objects.
|
16
|
-
* Ensures objects are deleted on the thread that created them.
|
17
|
-
*/
|
18
|
-
template <typename T> class ThreadSafeDeletion {
|
19
|
-
private:
|
20
|
-
struct DeletionItem {
|
21
|
-
sk_sp<T> object;
|
22
|
-
std::thread::id creationThreadId;
|
23
|
-
};
|
24
|
-
|
25
|
-
static inline std::mutex _queueMutex;
|
26
|
-
static inline std::queue<DeletionItem> _deletionQueue;
|
27
|
-
|
28
|
-
std::thread::id _creationThreadId;
|
29
|
-
|
30
|
-
public:
|
31
|
-
ThreadSafeDeletion() : _creationThreadId(std::this_thread::get_id()) {}
|
32
|
-
|
33
|
-
/**
|
34
|
-
* Handles deletion of the object. If we're on the wrong thread,
|
35
|
-
* queues it for later deletion. Otherwise, allows immediate deletion.
|
36
|
-
* The object is always considered handled after this call.
|
37
|
-
*/
|
38
|
-
void handleDeletion(sk_sp<T> object) {
|
39
|
-
if (!object) {
|
40
|
-
return;
|
41
|
-
}
|
42
|
-
|
43
|
-
#ifdef DISABLE_THREAD_SAFE_DELETION
|
44
|
-
// When disabled, allow immediate deletion
|
45
|
-
// This will likely cause crashes when objects are deleted on wrong thread
|
46
|
-
return;
|
47
|
-
#else
|
48
|
-
// Always try to drain the queue when handling deletions
|
49
|
-
drainDeletionQueue();
|
50
|
-
|
51
|
-
// Check if we're on the creation thread
|
52
|
-
if (std::this_thread::get_id() != _creationThreadId) {
|
53
|
-
// Queue for deletion on the correct thread
|
54
|
-
std::lock_guard<std::mutex> lock(_queueMutex);
|
55
|
-
_deletionQueue.push({object, _creationThreadId});
|
56
|
-
return;
|
57
|
-
}
|
58
|
-
|
59
|
-
// We're on the correct thread, allow immediate deletion via destructor
|
60
|
-
return;
|
61
|
-
#endif
|
62
|
-
}
|
63
|
-
|
64
|
-
/**
|
65
|
-
* Drains the deletion queue for objects created on the current thread.
|
66
|
-
* Should be called periodically (e.g., when creating new objects).
|
67
|
-
*/
|
68
|
-
static void drainDeletionQueue() {
|
69
|
-
#ifndef DISABLE_THREAD_SAFE_DELETION
|
70
|
-
auto currentThreadId = std::this_thread::get_id();
|
71
|
-
std::queue<DeletionItem> remainingItems;
|
72
|
-
|
73
|
-
std::lock_guard<std::mutex> lock(_queueMutex);
|
74
|
-
|
75
|
-
// Process all items in the queue
|
76
|
-
while (!_deletionQueue.empty()) {
|
77
|
-
auto item = _deletionQueue.front();
|
78
|
-
_deletionQueue.pop();
|
79
|
-
|
80
|
-
// If this item belongs to the current thread, let it be deleted
|
81
|
-
if (item.creationThreadId == currentThreadId) {
|
82
|
-
// The sk_sp destructor will handle the cleanup
|
83
|
-
// Just let it go out of scope
|
84
|
-
} else {
|
85
|
-
// Keep items that belong to other threads
|
86
|
-
remainingItems.push(item);
|
87
|
-
}
|
88
|
-
}
|
89
|
-
|
90
|
-
// Put back items that couldn't be deleted
|
91
|
-
_deletionQueue = std::move(remainingItems);
|
92
|
-
#endif
|
93
|
-
}
|
94
|
-
|
95
|
-
/**
|
96
|
-
* Returns the number of items waiting for deletion.
|
97
|
-
* Useful for debugging and testing.
|
98
|
-
*/
|
99
|
-
static size_t getPendingDeletionCount() {
|
100
|
-
std::lock_guard<std::mutex> lock(_queueMutex);
|
101
|
-
return _deletionQueue.size();
|
102
|
-
}
|
103
|
-
};
|
104
|
-
|
105
|
-
} // namespace RNSkia
|