@shopify/react-native-skia 2.4.18 → 2.4.20

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 (86) hide show
  1. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +34 -0
  2. package/android/cpp/rnskia-android/RNSkAndroidVideo.h +3 -0
  3. package/android/src/main/java/com/shopify/reactnative/skia/RNSkVideo.java +72 -18
  4. package/apple/RNSkAppleVideo.h +30 -3
  5. package/apple/RNSkAppleVideo.mm +172 -17
  6. package/cpp/api/JsiSkApi.h +15 -13
  7. package/cpp/api/JsiSkHostObjects.h +57 -3
  8. package/cpp/api/JsiSkImage.h +19 -10
  9. package/cpp/api/JsiSkPicture.h +18 -9
  10. package/cpp/api/JsiSkSurface.h +18 -9
  11. package/cpp/api/JsiVideo.h +15 -2
  12. package/cpp/api/recorder/Convertor.h +4 -2
  13. package/cpp/jsi2/EnumMapper.h +49 -34
  14. package/cpp/jsi2/JSIConverter.h +149 -99
  15. package/cpp/jsi2/NativeObject.h +23 -25
  16. package/cpp/jsi2/Promise.cpp +10 -6
  17. package/cpp/jsi2/Promise.h +9 -7
  18. package/cpp/rnskia/RNDawnContext.h +3 -8
  19. package/cpp/rnskia/RNSkManager.cpp +13 -7
  20. package/cpp/rnskia/RNSkVideo.h +3 -0
  21. package/cpp/rnwgpu/api/GPUAdapter.cpp +31 -32
  22. package/cpp/rnwgpu/api/GPUAdapter.h +1 -1
  23. package/cpp/rnwgpu/api/GPUBuffer.cpp +8 -8
  24. package/cpp/rnwgpu/api/GPUCommandEncoder.h +4 -4
  25. package/cpp/rnwgpu/api/GPUDevice.h +12 -12
  26. package/cpp/rnwgpu/api/GPUQueue.cpp +45 -44
  27. package/cpp/rnwgpu/api/GPUQueue.h +1 -1
  28. package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +1 -1
  29. package/cpp/rnwgpu/api/GPURenderPassEncoder.h +1 -1
  30. package/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h +1 -1
  31. package/cpp/rnwgpu/api/descriptors/GPUComputePipelineDescriptor.h +1 -1
  32. package/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h +7 -6
  33. package/cpp/rnwgpu/api/descriptors/GPURenderPassDescriptor.h +1 -1
  34. package/cpp/rnwgpu/api/descriptors/GPURenderPipelineDescriptor.h +1 -1
  35. package/cpp/rnwgpu/api/descriptors/GPUVertexState.h +1 -1
  36. package/cpp/rnwgpu/async/AsyncRunner.cpp +2 -1
  37. package/cpp/rnwgpu/async/AsyncRunner.h +2 -1
  38. package/lib/commonjs/external/reanimated/useVideo.js +30 -31
  39. package/lib/commonjs/external/reanimated/useVideo.js.map +1 -1
  40. package/lib/commonjs/renderer/Offscreen.js +1 -0
  41. package/lib/commonjs/renderer/Offscreen.js.map +1 -1
  42. package/lib/commonjs/skia/types/Video/Video.d.ts +3 -0
  43. package/lib/commonjs/skia/types/Video/Video.js.map +1 -1
  44. package/lib/commonjs/skia/web/JsiVideo.d.ts +3 -0
  45. package/lib/commonjs/skia/web/JsiVideo.js +9 -0
  46. package/lib/commonjs/skia/web/JsiVideo.js.map +1 -1
  47. package/lib/commonjs/sksg/Container.web.js +1 -0
  48. package/lib/commonjs/sksg/Container.web.js.map +1 -1
  49. package/lib/commonjs/sksg/HostConfig.js +4 -1
  50. package/lib/commonjs/sksg/HostConfig.js.map +1 -1
  51. package/lib/commonjs/sksg/Reconciler.js +6 -6
  52. package/lib/commonjs/sksg/Reconciler.js.map +1 -1
  53. package/lib/commonjs/sksg/StaticContainer.js +1 -0
  54. package/lib/commonjs/sksg/StaticContainer.js.map +1 -1
  55. package/lib/module/external/reanimated/useVideo.js +30 -31
  56. package/lib/module/external/reanimated/useVideo.js.map +1 -1
  57. package/lib/module/renderer/Offscreen.js +1 -0
  58. package/lib/module/renderer/Offscreen.js.map +1 -1
  59. package/lib/module/skia/types/Video/Video.d.ts +3 -0
  60. package/lib/module/skia/types/Video/Video.js.map +1 -1
  61. package/lib/module/skia/web/JsiVideo.d.ts +3 -0
  62. package/lib/module/skia/web/JsiVideo.js +9 -0
  63. package/lib/module/skia/web/JsiVideo.js.map +1 -1
  64. package/lib/module/sksg/Container.web.js +1 -0
  65. package/lib/module/sksg/Container.web.js.map +1 -1
  66. package/lib/module/sksg/HostConfig.js +4 -1
  67. package/lib/module/sksg/HostConfig.js.map +1 -1
  68. package/lib/module/sksg/Reconciler.js +6 -6
  69. package/lib/module/sksg/Reconciler.js.map +1 -1
  70. package/lib/module/sksg/StaticContainer.js +1 -0
  71. package/lib/module/sksg/StaticContainer.js.map +1 -1
  72. package/lib/typescript/lib/commonjs/skia/web/JsiVideo.d.ts +3 -0
  73. package/lib/typescript/lib/commonjs/sksg/HostConfig.d.ts +2 -0
  74. package/lib/typescript/lib/module/skia/web/JsiVideo.d.ts +3 -0
  75. package/lib/typescript/lib/module/sksg/HostConfig.d.ts +2 -0
  76. package/lib/typescript/src/skia/types/Video/Video.d.ts +3 -0
  77. package/lib/typescript/src/skia/web/JsiVideo.d.ts +3 -0
  78. package/package.json +1 -1
  79. package/src/external/reanimated/useVideo.ts +32 -32
  80. package/src/renderer/Offscreen.tsx +1 -0
  81. package/src/skia/types/Video/Video.ts +3 -0
  82. package/src/skia/web/JsiVideo.ts +12 -0
  83. package/src/sksg/Container.web.ts +1 -0
  84. package/src/sksg/HostConfig.ts +4 -0
  85. package/src/sksg/Reconciler.ts +5 -6
  86. package/src/sksg/StaticContainer.ts +1 -0
@@ -289,24 +289,33 @@ public:
289
289
  std::move(image)) {
290
290
  // Get the dispatcher for the current thread
291
291
  _dispatcher = Dispatcher::getDispatcher();
292
- // Process any pending operations
292
+ // Process any pending operations (e.g. deletions of previous resources)
293
293
  _dispatcher->processQueue();
294
294
  }
295
295
 
296
+ public:
296
297
  ~JsiSkImage() override {
297
- // Queue deletion on the creation thread if needed
298
- auto image = getObject();
299
- if (image && _dispatcher) {
300
- _dispatcher->run([image]() {
301
- // Image will be deleted when this lambda is destroyed
302
- });
298
+ if (!isDisposed()) {
299
+ // This JSI Object is being deleted from a GC, which might happen
300
+ // on a separate Thread. GPU resources (like SkImage) must be deleted
301
+ // on the same Thread they were created on, so in this case we schedule
302
+ // deletion to run on the Thread this Object was created on.
303
+ auto image = getObjectUnchecked();
304
+ if (image && _dispatcher) {
305
+ _dispatcher->run([image]() {
306
+ // Image will be deleted when this lambda is destroyed, on the
307
+ // original Thread.
308
+ });
309
+ }
310
+ releaseResources();
303
311
  }
304
- // Clear the object to prevent base class destructor from deleting it
305
- setObject(nullptr);
306
312
  }
307
313
 
308
314
  size_t getMemoryPressure() const override {
309
- auto image = getObject();
315
+ if (isDisposed()) {
316
+ return 0;
317
+ }
318
+ auto image = getObjectUnchecked();
310
319
  if (image) {
311
320
  if (image->isTextureBacked()) {
312
321
  return image->textureSize();
@@ -34,16 +34,22 @@ public:
34
34
  _dispatcher->processQueue();
35
35
  }
36
36
 
37
+ public:
37
38
  ~JsiSkPicture() override {
38
- // Queue deletion on the creation thread if needed
39
- auto picture = getObject();
40
- if (picture && _dispatcher) {
41
- _dispatcher->run([picture]() {
42
- // Picture will be deleted when this lambda is destroyed
43
- });
39
+ if (!isDisposed()) {
40
+ // This JSI Object is being deleted from a GC, which might happen
41
+ // on a separate Thread. GPU resources (like SkPicture) must be deleted
42
+ // on the same Thread they were created on, so in this case we schedule
43
+ // deletion to run on the Thread this Object was created on.
44
+ auto picture = getObjectUnchecked();
45
+ if (picture && _dispatcher) {
46
+ _dispatcher->run([picture]() {
47
+ // Picture will be deleted when this lambda is destroyed, on the
48
+ // original Thread.
49
+ });
50
+ }
51
+ releaseResources();
44
52
  }
45
- // Clear the object to prevent base class destructor from deleting it
46
- setObject(nullptr);
47
53
  }
48
54
 
49
55
  JSI_HOST_FUNCTION(makeShader) {
@@ -91,7 +97,10 @@ public:
91
97
  JSI_EXPORT_FUNC(JsiSkPicture, dispose))
92
98
 
93
99
  size_t getMemoryPressure() const override {
94
- auto picture = getObject();
100
+ if (isDisposed()) {
101
+ return 0;
102
+ }
103
+ auto picture = getObjectUnchecked();
95
104
  if (!picture) {
96
105
  return 0;
97
106
  }
@@ -45,16 +45,22 @@ public:
45
45
  _dispatcher->processQueue();
46
46
  }
47
47
 
48
+ public:
48
49
  ~JsiSkSurface() override {
49
- // Queue deletion on the creation thread if needed
50
- auto surface = getObject();
51
- if (surface && _dispatcher) {
52
- _dispatcher->run([surface]() {
53
- // Surface will be deleted when this lambda is destroyed
54
- });
50
+ if (!isDisposed()) {
51
+ // This JSI Object is being deleted from a GC, which might happen
52
+ // on a separate Thread. GPU resources (like SkSurface) must be deleted
53
+ // on the same Thread they were created on, so in this case we schedule
54
+ // deletion to run on the Thread this Object was created on.
55
+ auto surface = getObjectUnchecked();
56
+ if (surface && _dispatcher) {
57
+ _dispatcher->run([surface]() {
58
+ // Surface will be deleted when this lambda is destroyed, on the
59
+ // original Thread.
60
+ });
61
+ }
62
+ releaseResources();
55
63
  }
56
- // Clear the object to prevent base class destructor from deleting it
57
- setObject(nullptr);
58
64
  }
59
65
 
60
66
  EXPORT_JSI_API_TYPENAME(JsiSkSurface, Surface)
@@ -117,7 +123,10 @@ public:
117
123
  }
118
124
 
119
125
  size_t getMemoryPressure() const override {
120
- auto surface = getObject();
126
+ if (isDisposed()) {
127
+ return 0;
128
+ }
129
+ auto surface = getObjectUnchecked();
121
130
  if (!surface) {
122
131
  return 0;
123
132
  }
@@ -49,6 +49,10 @@ public:
49
49
 
50
50
  JSI_HOST_FUNCTION(framerate) { return getObject()->framerate(); }
51
51
 
52
+ JSI_HOST_FUNCTION(currentTime) { return getObject()->currentTime(); }
53
+
54
+ JSI_HOST_FUNCTION(isPlaying) { return getObject()->isPlaying(); }
55
+
52
56
  JSI_HOST_FUNCTION(seek) {
53
57
  double timestamp = arguments[0].asNumber();
54
58
  getObject()->seek(timestamp);
@@ -86,12 +90,21 @@ public:
86
90
  return jsi::Value::undefined();
87
91
  }
88
92
 
93
+ JSI_HOST_FUNCTION(setLooping) {
94
+ auto looping = arguments[0].asBool();
95
+ getObject()->setLooping(looping);
96
+ return jsi::Value::undefined();
97
+ }
98
+
89
99
  JSI_EXPORT_FUNCTIONS(
90
100
  JSI_EXPORT_FUNC(JsiVideo, nextImage), JSI_EXPORT_FUNC(JsiVideo, duration),
91
- JSI_EXPORT_FUNC(JsiVideo, framerate), JSI_EXPORT_FUNC(JsiVideo, seek),
101
+ JSI_EXPORT_FUNC(JsiVideo, framerate),
102
+ JSI_EXPORT_FUNC(JsiVideo, currentTime),
103
+ JSI_EXPORT_FUNC(JsiVideo, isPlaying), JSI_EXPORT_FUNC(JsiVideo, seek),
92
104
  JSI_EXPORT_FUNC(JsiVideo, rotation), JSI_EXPORT_FUNC(JsiVideo, size),
93
105
  JSI_EXPORT_FUNC(JsiVideo, play), JSI_EXPORT_FUNC(JsiVideo, pause),
94
- JSI_EXPORT_FUNC(JsiVideo, setVolume), JSI_EXPORT_FUNC(JsiVideo, dispose))
106
+ JSI_EXPORT_FUNC(JsiVideo, setVolume),
107
+ JSI_EXPORT_FUNC(JsiVideo, setLooping), JSI_EXPORT_FUNC(JsiVideo, dispose))
95
108
 
96
109
  JsiVideo(std::shared_ptr<RNSkPlatformContext> context,
97
110
  std::shared_ptr<RNSkVideo> video)
@@ -667,7 +667,8 @@ SkPath1DPathEffect::Style getPropertyValue(jsi::Runtime &runtime,
667
667
  throw std::runtime_error("Invalid prop value for Path1DEffectStyle received");
668
668
  }
669
669
 
670
- // Wrapper type for blend mode to avoid conflict with int template specialization
670
+ // Wrapper type for blend mode to avoid conflict with int template
671
+ // specialization
671
672
  struct BlendModeValue {
672
673
  int value;
673
674
  BlendModeValue(int v = 0) : value(v) {}
@@ -745,7 +746,8 @@ BlendModeValue getPropertyValue(jsi::Runtime &runtime, const jsi::Value &val) {
745
746
  throw std::runtime_error("Invalid prop value for BlendMode received");
746
747
  }
747
748
 
748
- // Keep SkBlendMode specialization for other usages (Shaders, ImageFilters, ColorFilters, Drawings)
749
+ // Keep SkBlendMode specialization for other usages (Shaders, ImageFilters,
750
+ // ColorFilters, Drawings)
749
751
  template <>
750
752
  SkBlendMode getPropertyValue(jsi::Runtime &runtime, const jsi::Value &val) {
751
753
  if (val.isString()) {
@@ -6,40 +6,55 @@
6
6
  namespace rnwgpu {
7
7
 
8
8
  namespace EnumMapper {
9
- // Add these two methods in namespace "EnumMapper" to allow parsing a custom enum:
10
- // 1. `static void convertJSUnionToEnum(const std::string& inUnion, Enum* outEnum)`
11
- // 2. `static void convertEnumToJSUnion(Enum inEnum, std::string* outUnion)`
12
-
13
- static std::runtime_error invalidUnion(const std::string& passedUnion) {
14
- return std::runtime_error("Cannot convert JS Value to Enum: Invalid Union value passed! (\"" + std::string(passedUnion) + "\")");
15
- }
16
-
17
- template <typename T> static std::runtime_error invalidEnum(T passedEnum) {
18
- return std::runtime_error("Cannot convert Enum to JS Value: Invalid Enum passed! (Value #" +
19
- std::to_string(static_cast<int>(passedEnum)) + ")");
20
- }
21
-
22
- // Trait to check if a convertJSUnionToEnum function for enum type T exists
23
- template <typename T, typename = void> struct has_js_union_to_enum : std::false_type {};
24
- template <typename T>
25
- struct has_js_union_to_enum<T, std::void_t<decltype(convertJSUnionToEnum(std::declval<std::string>(), std::declval<T*>()))>>
26
- : std::true_type {};
27
-
28
- // Trait to check if a convertEnumToJSUnion function for enum type T exists
29
- template <typename T, typename = void> struct has_enum_to_js_union : std::false_type {};
30
- template <typename T>
31
- struct has_enum_to_js_union<T, std::void_t<decltype(convertEnumToJSUnion(std::declval<T>(), std::declval<std::string*>()))>>
32
- : std::true_type {};
33
-
34
- template <typename TEnum> static void convertJSUnionToEnum(const std::string&, TEnum*) {
35
- static_assert(has_js_union_to_enum<TEnum>::value,
36
- "Cannot convert a JS union to this enum type. Did you implement EnumMapper::convertJSUnionToEnum(...)?");
37
- }
38
-
39
- template <typename TEnum> static void convertEnumToJSUnion(TEnum, std::string*) {
40
- static_assert(has_enum_to_js_union<TEnum>::value,
41
- "Cannot convert this enum type to a JS union. Did you implement EnumMapper::convertEnumToJSUnion(...)?");
42
- }
9
+ // Add these two methods in namespace "EnumMapper" to allow parsing a custom
10
+ // enum:
11
+ // 1. `static void convertJSUnionToEnum(const std::string& inUnion, Enum*
12
+ // outEnum)`
13
+ // 2. `static void convertEnumToJSUnion(Enum inEnum, std::string* outUnion)`
14
+
15
+ static std::runtime_error invalidUnion(const std::string &passedUnion) {
16
+ return std::runtime_error(
17
+ "Cannot convert JS Value to Enum: Invalid Union value passed! (\"" +
18
+ std::string(passedUnion) + "\")");
19
+ }
20
+
21
+ template <typename T> static std::runtime_error invalidEnum(T passedEnum) {
22
+ return std::runtime_error(
23
+ "Cannot convert Enum to JS Value: Invalid Enum passed! (Value #" +
24
+ std::to_string(static_cast<int>(passedEnum)) + ")");
25
+ }
26
+
27
+ // Trait to check if a convertJSUnionToEnum function for enum type T exists
28
+ template <typename T, typename = void>
29
+ struct has_js_union_to_enum : std::false_type {};
30
+ template <typename T>
31
+ struct has_js_union_to_enum<
32
+ T, std::void_t<decltype(convertJSUnionToEnum(std::declval<std::string>(),
33
+ std::declval<T *>()))>>
34
+ : std::true_type {};
35
+
36
+ // Trait to check if a convertEnumToJSUnion function for enum type T exists
37
+ template <typename T, typename = void>
38
+ struct has_enum_to_js_union : std::false_type {};
39
+ template <typename T>
40
+ struct has_enum_to_js_union<
41
+ T, std::void_t<decltype(convertEnumToJSUnion(
42
+ std::declval<T>(), std::declval<std::string *>()))>>
43
+ : std::true_type {};
44
+
45
+ template <typename TEnum>
46
+ static void convertJSUnionToEnum(const std::string &, TEnum *) {
47
+ static_assert(has_js_union_to_enum<TEnum>::value,
48
+ "Cannot convert a JS union to this enum type. Did you "
49
+ "implement EnumMapper::convertJSUnionToEnum(...)?");
50
+ }
51
+
52
+ template <typename TEnum>
53
+ static void convertEnumToJSUnion(TEnum, std::string *) {
54
+ static_assert(has_enum_to_js_union<TEnum>::value,
55
+ "Cannot convert this enum type to a JS union. Did you "
56
+ "implement EnumMapper::convertEnumToJSUnion(...)?");
57
+ }
43
58
  } // namespace EnumMapper
44
59
 
45
60
  } // namespace rnwgpu