@shopify/react-native-skia 1.2.0 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +3 -3
- package/android/src/main/java/com/shopify/reactnative/skia/ViewScreenshotService.java +13 -8
- package/cpp/api/JsiNativeBuffer.h +43 -0
- package/cpp/api/JsiSkApi.h +3 -3
- package/cpp/api/JsiSkImageFactory.h +3 -3
- package/cpp/rnskia/RNSkPlatformContext.h +5 -5
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +3 -3
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +70 -93
- package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.h +119 -0
- package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +332 -0
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +2 -1
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +27 -6
- package/lib/commonjs/external/ModuleProxy.d.ts +10 -0
- package/lib/commonjs/external/ModuleProxy.js +36 -0
- package/lib/commonjs/external/ModuleProxy.js.map +1 -0
- package/lib/commonjs/external/reanimated/ReanimatedProxy.d.ts +3 -0
- package/lib/commonjs/external/reanimated/ReanimatedProxy.js +18 -0
- package/lib/commonjs/external/reanimated/ReanimatedProxy.js.map +1 -0
- package/lib/commonjs/external/reanimated/buffers.js +9 -6
- package/lib/commonjs/external/reanimated/buffers.js.map +1 -1
- package/lib/commonjs/external/reanimated/interpolators.js +8 -7
- package/lib/commonjs/external/reanimated/interpolators.js.map +1 -1
- package/lib/commonjs/external/reanimated/renderHelpers.js +27 -11
- package/lib/commonjs/external/reanimated/renderHelpers.js.map +1 -1
- package/lib/commonjs/external/reanimated/textures.js +4 -3
- package/lib/commonjs/external/reanimated/textures.js.map +1 -1
- package/lib/commonjs/external/reanimated/useAnimatedImageValue.js +6 -6
- package/lib/commonjs/external/reanimated/useAnimatedImageValue.js.map +1 -1
- package/lib/commonjs/external/reanimated/useDerivedValueOnJS.js +6 -5
- package/lib/commonjs/external/reanimated/useDerivedValueOnJS.js.map +1 -1
- package/lib/commonjs/renderer/Offscreen.js +1 -5
- package/lib/commonjs/renderer/Offscreen.js.map +1 -1
- package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +8 -15
- package/lib/commonjs/skia/types/Image/ImageFactory.js +1 -10
- package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
- package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.d.ts +18 -0
- package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.js +13 -0
- package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.js.map +1 -0
- package/lib/commonjs/skia/types/NativeBuffer/index.d.ts +1 -0
- package/lib/commonjs/skia/types/NativeBuffer/index.js +17 -0
- package/lib/commonjs/skia/types/NativeBuffer/index.js.map +1 -0
- package/lib/commonjs/skia/types/Skia.d.ts +2 -2
- package/lib/commonjs/skia/types/Skia.js.map +1 -1
- package/lib/commonjs/skia/types/index.d.ts +1 -1
- package/lib/commonjs/skia/types/index.js +4 -4
- package/lib/commonjs/skia/types/index.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +3 -2
- package/lib/commonjs/skia/web/JsiSkImageFactory.js +18 -2
- package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkNativeBufferFactory.d.ts +8 -0
- package/lib/commonjs/skia/web/JsiSkNativeBufferFactory.js +29 -0
- package/lib/commonjs/skia/web/JsiSkNativeBufferFactory.js.map +1 -0
- package/lib/commonjs/skia/web/JsiSkia.js +2 -2
- package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
- package/lib/commonjs/specs/NativeSkiaModule.web.d.ts +0 -2
- package/lib/commonjs/specs/NativeSkiaModule.web.js +0 -8
- package/lib/commonjs/specs/NativeSkiaModule.web.js.map +1 -1
- package/lib/module/external/ModuleProxy.d.ts +10 -0
- package/lib/module/external/ModuleProxy.js +28 -0
- package/lib/module/external/ModuleProxy.js.map +1 -0
- package/lib/module/external/reanimated/ReanimatedProxy.d.ts +3 -0
- package/lib/module/external/reanimated/ReanimatedProxy.js +12 -0
- package/lib/module/external/reanimated/ReanimatedProxy.js.map +1 -0
- package/lib/module/external/reanimated/buffers.js +8 -6
- package/lib/module/external/reanimated/buffers.js.map +1 -1
- package/lib/module/external/reanimated/interpolators.js +7 -7
- package/lib/module/external/reanimated/interpolators.js.map +1 -1
- package/lib/module/external/reanimated/renderHelpers.js +26 -11
- package/lib/module/external/reanimated/renderHelpers.js.map +1 -1
- package/lib/module/external/reanimated/textures.js +3 -3
- package/lib/module/external/reanimated/textures.js.map +1 -1
- package/lib/module/external/reanimated/useAnimatedImageValue.js +5 -6
- package/lib/module/external/reanimated/useAnimatedImageValue.js.map +1 -1
- package/lib/module/external/reanimated/useDerivedValueOnJS.js +5 -5
- package/lib/module/external/reanimated/useDerivedValueOnJS.js.map +1 -1
- package/lib/module/renderer/Offscreen.js +1 -5
- package/lib/module/renderer/Offscreen.js.map +1 -1
- package/lib/module/skia/types/Image/ImageFactory.d.ts +8 -15
- package/lib/module/skia/types/Image/ImageFactory.js +1 -10
- package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
- package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.d.ts +18 -0
- package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.js +4 -0
- package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.js.map +1 -0
- package/lib/module/skia/types/NativeBuffer/index.d.ts +1 -0
- package/lib/module/skia/types/NativeBuffer/index.js +2 -0
- package/lib/module/skia/types/NativeBuffer/index.js.map +1 -0
- package/lib/module/skia/types/Skia.d.ts +2 -2
- package/lib/module/skia/types/Skia.js.map +1 -1
- package/lib/module/skia/types/index.d.ts +1 -1
- package/lib/module/skia/types/index.js +1 -1
- package/lib/module/skia/types/index.js.map +1 -1
- package/lib/module/skia/web/JsiSkImageFactory.d.ts +3 -2
- package/lib/module/skia/web/JsiSkImageFactory.js +18 -2
- package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkNativeBufferFactory.d.ts +8 -0
- package/lib/module/skia/web/JsiSkNativeBufferFactory.js +22 -0
- package/lib/module/skia/web/JsiSkNativeBufferFactory.js.map +1 -0
- package/lib/module/skia/web/JsiSkia.js +2 -2
- package/lib/module/skia/web/JsiSkia.js.map +1 -1
- package/lib/module/specs/NativeSkiaModule.web.d.ts +0 -2
- package/lib/module/specs/NativeSkiaModule.web.js +0 -3
- package/lib/module/specs/NativeSkiaModule.web.js.map +1 -1
- package/lib/typescript/src/external/ModuleProxy.d.ts +10 -0
- package/lib/typescript/src/external/reanimated/ReanimatedProxy.d.ts +3 -0
- package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +8 -15
- package/lib/typescript/src/skia/types/NativeBuffer/NativeBufferFactory.d.ts +18 -0
- package/lib/typescript/src/skia/types/NativeBuffer/index.d.ts +1 -0
- package/lib/typescript/src/skia/types/Skia.d.ts +2 -2
- package/lib/typescript/src/skia/types/index.d.ts +1 -1
- package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +3 -2
- package/lib/typescript/src/skia/web/JsiSkNativeBufferFactory.d.ts +8 -0
- package/lib/typescript/src/specs/NativeSkiaModule.web.d.ts +0 -2
- package/libs/ios/libskia.xcframework/Info.plist +5 -5
- package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
- package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
- package/libs/ios/libskottie.xcframework/Info.plist +5 -5
- package/libs/ios/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
- package/libs/ios/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
- package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
- package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
- package/libs/ios/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
- package/libs/ios/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
- package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
- package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
- package/libs/ios/libskunicode.xcframework/ios-arm64_arm64e/libskunicode.a +0 -0
- package/libs/ios/libskunicode.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode.a +0 -0
- package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
- package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
- package/package.json +1 -1
- package/src/external/ModuleProxy.ts +30 -0
- package/src/external/reanimated/ReanimatedProxy.ts +18 -0
- package/src/external/reanimated/buffers.ts +7 -6
- package/src/external/reanimated/interpolators.ts +7 -12
- package/src/external/reanimated/renderHelpers.ts +31 -18
- package/src/external/reanimated/textures.tsx +3 -3
- package/src/external/reanimated/useAnimatedImageValue.ts +5 -10
- package/src/external/reanimated/useDerivedValueOnJS.ts +5 -10
- package/src/renderer/Offscreen.tsx +1 -7
- package/src/skia/types/Image/ImageFactory.ts +7 -23
- package/src/skia/types/NativeBuffer/NativeBufferFactory.ts +38 -0
- package/src/skia/types/NativeBuffer/index.ts +1 -0
- package/src/skia/types/Skia.ts +2 -2
- package/src/skia/types/index.ts +1 -1
- package/src/skia/web/JsiSkImageFactory.ts +28 -6
- package/src/skia/web/JsiSkNativeBufferFactory.ts +35 -0
- package/src/skia/web/JsiSkia.ts +2 -2
- package/src/specs/NativeSkiaModule.web.ts +0 -4
- package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaDrawViewManagerDelegate.java +0 -34
- package/cpp/api/JsiPlatformBuffer.h +0 -51
- package/cpp/skia/include/gpu/GrBackendDrawableInfo.h +0 -9
- package/lib/commonjs/external/reanimated/moduleWrapper.d.ts +0 -15
- package/lib/commonjs/external/reanimated/moduleWrapper.js +0 -46
- package/lib/commonjs/external/reanimated/moduleWrapper.js.map +0 -1
- package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +0 -12
- package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.js +0 -6
- package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.js.map +0 -1
- package/lib/commonjs/skia/types/PlatformBuffer/index.d.ts +0 -1
- package/lib/commonjs/skia/types/PlatformBuffer/index.js +0 -17
- package/lib/commonjs/skia/types/PlatformBuffer/index.js.map +0 -1
- package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.d.ts +0 -8
- package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.js +0 -20
- package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.js.map +0 -1
- package/lib/module/external/reanimated/moduleWrapper.d.ts +0 -15
- package/lib/module/external/reanimated/moduleWrapper.js +0 -37
- package/lib/module/external/reanimated/moduleWrapper.js.map +0 -1
- package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +0 -12
- package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.js +0 -2
- package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.js.map +0 -1
- package/lib/module/skia/types/PlatformBuffer/index.d.ts +0 -1
- package/lib/module/skia/types/PlatformBuffer/index.js +0 -2
- package/lib/module/skia/types/PlatformBuffer/index.js.map +0 -1
- package/lib/module/skia/web/JsiSkPlatformBufferFactory.d.ts +0 -8
- package/lib/module/skia/web/JsiSkPlatformBufferFactory.js +0 -13
- package/lib/module/skia/web/JsiSkPlatformBufferFactory.js.map +0 -1
- package/lib/typescript/src/external/reanimated/moduleWrapper.d.ts +0 -15
- package/lib/typescript/src/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +0 -12
- package/lib/typescript/src/skia/types/PlatformBuffer/index.d.ts +0 -1
- package/lib/typescript/src/skia/web/JsiSkPlatformBufferFactory.d.ts +0 -8
- package/src/external/reanimated/moduleWrapper.ts +0 -83
- package/src/skia/types/PlatformBuffer/PlatformBufferFactory.ts +0 -14
- package/src/skia/types/PlatformBuffer/index.ts +0 -1
- package/src/skia/web/JsiSkPlatformBufferFactory.ts +0 -22
@@ -53,18 +53,18 @@ public:
|
|
53
53
|
return SkiaOpenGLSurfaceFactory::makeOffscreenSurface(width, height);
|
54
54
|
}
|
55
55
|
|
56
|
-
sk_sp<SkImage>
|
56
|
+
sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) override {
|
57
57
|
return SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(buffer);
|
58
58
|
}
|
59
59
|
|
60
|
-
void
|
60
|
+
void releaseNativeBuffer(uint64_t pointer) override {
|
61
61
|
#if __ANDROID_API__ >= 26
|
62
62
|
AHardwareBuffer *buffer = reinterpret_cast<AHardwareBuffer *>(pointer);
|
63
63
|
AHardwareBuffer_release(buffer);
|
64
64
|
#endif
|
65
65
|
}
|
66
66
|
|
67
|
-
uint64_t
|
67
|
+
uint64_t makeNativeBuffer(sk_sp<SkImage> image) override {
|
68
68
|
#if __ANDROID_API__ >= 26
|
69
69
|
auto bytesPerPixel = image->imageInfo().bytesPerPixel();
|
70
70
|
int bytesPerRow = image->width() * bytesPerPixel;
|
@@ -162,16 +162,21 @@ public class ViewScreenshotService {
|
|
162
162
|
latch.await(SURFACE_VIEW_READ_PIXELS_TIMEOUT, TimeUnit.SECONDS);
|
163
163
|
} catch (Exception e) {
|
164
164
|
Log.e(TAG, "Cannot PixelCopy for " + sv, e);
|
165
|
+
drawSurfaceViewFromCache(canvas, sv, paint, opacity);
|
165
166
|
}
|
166
167
|
} else {
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
168
|
+
drawSurfaceViewFromCache(canvas, sv, paint, opacity);
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
private static void drawSurfaceViewFromCache(Canvas canvas, SurfaceView sv, Paint paint, float opacity) {
|
173
|
+
Bitmap cache = sv.getDrawingCache();
|
174
|
+
if (cache != null) {
|
175
|
+
canvas.save();
|
176
|
+
applyTransformations(canvas, sv);
|
177
|
+
paint.setAlpha(Math.round(opacity * 255)); // Set paint alpha based on opacity
|
178
|
+
canvas.drawBitmap(cache, 0, 0, paint);
|
179
|
+
canvas.restore();
|
175
180
|
}
|
176
181
|
}
|
177
182
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <memory>
|
4
|
+
#include <utility>
|
5
|
+
|
6
|
+
#include <jsi/jsi.h>
|
7
|
+
|
8
|
+
#include "JsiSkImage.h"
|
9
|
+
|
10
|
+
namespace RNSkia {
|
11
|
+
|
12
|
+
namespace jsi = facebook::jsi;
|
13
|
+
|
14
|
+
/**
|
15
|
+
Implementation of the ParagraphBuilderFactory for making ParagraphBuilder JSI
|
16
|
+
object
|
17
|
+
*/
|
18
|
+
class JsiNativeBufferFactory : public JsiSkHostObject {
|
19
|
+
public:
|
20
|
+
JSI_HOST_FUNCTION(MakeFromImage) {
|
21
|
+
auto image = JsiSkImage::fromValue(runtime, arguments[0]);
|
22
|
+
image->makeNonTextureImage();
|
23
|
+
uint64_t pointer = getContext()->makeNativeBuffer(image);
|
24
|
+
return jsi::BigInt::fromUint64(runtime, pointer);
|
25
|
+
}
|
26
|
+
|
27
|
+
JSI_HOST_FUNCTION(Release) {
|
28
|
+
|
29
|
+
jsi::BigInt pointer = arguments[0].asBigInt(runtime);
|
30
|
+
const uintptr_t nativeBufferPointer = pointer.asUint64(runtime);
|
31
|
+
|
32
|
+
getContext()->releaseNativeBuffer(nativeBufferPointer);
|
33
|
+
return jsi::Value::undefined();
|
34
|
+
}
|
35
|
+
|
36
|
+
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiNativeBufferFactory, Release),
|
37
|
+
JSI_EXPORT_FUNC(JsiNativeBufferFactory, MakeFromImage))
|
38
|
+
|
39
|
+
explicit JsiNativeBufferFactory(std::shared_ptr<RNSkPlatformContext> context)
|
40
|
+
: JsiSkHostObject(std::move(context)) {}
|
41
|
+
};
|
42
|
+
|
43
|
+
} // namespace RNSkia
|
package/cpp/api/JsiSkApi.h
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
#include "JsiSkHostObjects.h"
|
8
8
|
|
9
|
-
#include "
|
9
|
+
#include "JsiNativeBuffer.h"
|
10
10
|
#include "JsiSkAnimatedImage.h"
|
11
11
|
#include "JsiSkAnimatedImageFactory.h"
|
12
12
|
#include "JsiSkColor.h"
|
@@ -124,8 +124,8 @@ public:
|
|
124
124
|
"ParagraphBuilder",
|
125
125
|
std::make_shared<JsiSkParagraphBuilderFactory>(context));
|
126
126
|
|
127
|
-
installReadonlyProperty(
|
128
|
-
|
127
|
+
installReadonlyProperty("NativeBuffer",
|
128
|
+
std::make_shared<JsiNativeBufferFactory>(context));
|
129
129
|
}
|
130
130
|
};
|
131
131
|
} // namespace RNSkia
|
@@ -27,11 +27,11 @@ public:
|
|
27
27
|
runtime, std::make_shared<JsiSkImage>(getContext(), std::move(image)));
|
28
28
|
}
|
29
29
|
|
30
|
-
JSI_HOST_FUNCTION(
|
30
|
+
JSI_HOST_FUNCTION(MakeImageFromNativeBuffer) {
|
31
31
|
jsi::BigInt pointer = arguments[0].asBigInt(runtime);
|
32
32
|
const uintptr_t platformBufferPointer = pointer.asUint64(runtime);
|
33
33
|
void *rawPointer = reinterpret_cast<void *>(platformBufferPointer);
|
34
|
-
auto image = getContext()->
|
34
|
+
auto image = getContext()->makeImageFromNativeBuffer(rawPointer);
|
35
35
|
if (image == nullptr) {
|
36
36
|
throw std::runtime_error("Failed to convert PlatformBuffer to SkImage!");
|
37
37
|
}
|
@@ -81,7 +81,7 @@ public:
|
|
81
81
|
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromEncoded),
|
82
82
|
JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromViewTag),
|
83
83
|
JSI_EXPORT_FUNC(JsiSkImageFactory,
|
84
|
-
|
84
|
+
MakeImageFromNativeBuffer),
|
85
85
|
JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImage))
|
86
86
|
|
87
87
|
explicit JsiSkImageFactory(std::shared_ptr<RNSkPlatformContext> context)
|
@@ -134,17 +134,17 @@ public:
|
|
134
134
|
virtual sk_sp<SkSurface> makeOffscreenSurface(int width, int height) = 0;
|
135
135
|
|
136
136
|
/**
|
137
|
-
* Creates an image from a native
|
138
|
-
* - On iOS, this is a `
|
137
|
+
* Creates an image from a native buffer.
|
138
|
+
* - On iOS, this is a `CVPixelBufferRef`
|
139
139
|
* - On Android, this is a `AHardwareBuffer*`
|
140
140
|
* @param buffer The native platform buffer.
|
141
141
|
* @return sk_sp<SkImage>
|
142
142
|
*/
|
143
|
-
virtual sk_sp<SkImage>
|
143
|
+
virtual sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) = 0;
|
144
144
|
|
145
|
-
virtual void
|
145
|
+
virtual void releaseNativeBuffer(uint64_t pointer) = 0;
|
146
146
|
|
147
|
-
virtual uint64_t
|
147
|
+
virtual uint64_t makeNativeBuffer(sk_sp<SkImage> image) = 0;
|
148
148
|
|
149
149
|
/**
|
150
150
|
* Return the Platform specific font manager
|
@@ -59,11 +59,11 @@ public:
|
|
59
59
|
|
60
60
|
sk_sp<SkImage> takeScreenshotFromViewTag(size_t tag) override;
|
61
61
|
|
62
|
-
sk_sp<SkImage>
|
62
|
+
sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) override;
|
63
63
|
|
64
|
-
uint64_t
|
64
|
+
uint64_t makeNativeBuffer(sk_sp<SkImage> image) override;
|
65
65
|
|
66
|
-
void
|
66
|
+
void releaseNativeBuffer(uint64_t pointer) override;
|
67
67
|
|
68
68
|
virtual void performStreamOperation(
|
69
69
|
const std::string &sourceUri,
|
@@ -1,11 +1,12 @@
|
|
1
|
-
#
|
1
|
+
#import "RNSkiOSPlatformContext.h"
|
2
2
|
|
3
3
|
#import <CoreMedia/CMSampleBuffer.h>
|
4
4
|
#import <React/RCTUtils.h>
|
5
5
|
#include <thread>
|
6
6
|
#include <utility>
|
7
7
|
|
8
|
-
#
|
8
|
+
#import "SkiaCVPixelBufferUtils.h"
|
9
|
+
#import "SkiaMetalSurfaceFactory.h"
|
9
10
|
|
10
11
|
#pragma clang diagnostic push
|
11
12
|
#pragma clang diagnostic ignored "-Wdocumentation"
|
@@ -57,87 +58,89 @@ void RNSkiOSPlatformContext::performStreamOperation(
|
|
57
58
|
std::thread(loader).detach();
|
58
59
|
}
|
59
60
|
|
60
|
-
void RNSkiOSPlatformContext::
|
61
|
-
|
62
|
-
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
|
63
|
-
if (sampleBuffer) {
|
64
|
-
CFRelease(sampleBuffer);
|
65
|
-
}
|
61
|
+
void RNSkiOSPlatformContext::releaseNativeBuffer(uint64_t pointer) {
|
62
|
+
CVPixelBufferRef pixelBuffer = reinterpret_cast<CVPixelBufferRef>(pointer);
|
66
63
|
if (pixelBuffer) {
|
67
64
|
CFRelease(pixelBuffer);
|
68
65
|
}
|
69
66
|
}
|
70
67
|
|
71
|
-
uint64_t RNSkiOSPlatformContext::
|
68
|
+
uint64_t RNSkiOSPlatformContext::makeNativeBuffer(sk_sp<SkImage> image) {
|
69
|
+
// 0. If Image is not in BGRA, convert to BGRA as only BGRA is supported.
|
70
|
+
if (image->colorType() != kBGRA_8888_SkColorType) {
|
71
|
+
// on iOS, 32_BGRA is the only supported RGB format for CVPixelBuffers.
|
72
|
+
image = image->makeColorTypeAndColorSpace(
|
73
|
+
ThreadContextHolder::ThreadSkiaMetalContext.skContext.get(),
|
74
|
+
kBGRA_8888_SkColorType, SkColorSpace::MakeSRGB());
|
75
|
+
if (image == nullptr) {
|
76
|
+
throw std::runtime_error(
|
77
|
+
"Failed to convert image to BGRA_8888 colortype! Only BGRA_8888 "
|
78
|
+
"PlatformBuffers are supported.");
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
// 1. Get image info
|
72
83
|
auto bytesPerPixel = image->imageInfo().bytesPerPixel();
|
73
84
|
int bytesPerRow = image->width() * bytesPerPixel;
|
74
85
|
auto buf = SkData::MakeUninitialized(image->width() * image->height() *
|
75
86
|
bytesPerPixel);
|
76
87
|
SkImageInfo info = SkImageInfo::Make(image->width(), image->height(),
|
77
88
|
image->colorType(), image->alphaType());
|
89
|
+
// 2. Copy pixels into our buffer
|
78
90
|
image->readPixels(nullptr, info, const_cast<void *>(buf->data()), bytesPerRow,
|
79
91
|
0, 0);
|
80
|
-
auto pixelData = const_cast<void *>(buf->data());
|
81
92
|
|
82
|
-
// Create
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
93
|
+
// 3. Create an IOSurface (GPU + CPU memory)
|
94
|
+
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
|
95
|
+
kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
|
96
|
+
&kCFTypeDictionaryValueCallBacks);
|
97
|
+
int width = image->width();
|
98
|
+
int height = image->height();
|
99
|
+
int pitch = width * bytesPerPixel;
|
100
|
+
int size = width * height * bytesPerPixel;
|
101
|
+
OSType pixelFormat = kCVPixelFormatType_32BGRA;
|
102
|
+
CFDictionarySetValue(
|
103
|
+
dict, kIOSurfaceBytesPerRow,
|
104
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch));
|
105
|
+
CFDictionarySetValue(
|
106
|
+
dict, kIOSurfaceBytesPerElement,
|
107
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bytesPerPixel));
|
108
|
+
CFDictionarySetValue(
|
109
|
+
dict, kIOSurfaceWidth,
|
110
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width));
|
111
|
+
CFDictionarySetValue(
|
112
|
+
dict, kIOSurfaceHeight,
|
113
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height));
|
114
|
+
CFDictionarySetValue(
|
115
|
+
dict, kIOSurfacePixelFormat,
|
116
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pixelFormat));
|
117
|
+
CFDictionarySetValue(
|
118
|
+
dict, kIOSurfaceAllocSize,
|
119
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &size));
|
120
|
+
IOSurfaceRef surface = IOSurfaceCreate(dict);
|
121
|
+
if (surface == nil) {
|
122
|
+
throw std::runtime_error("Failed to create " + std::to_string(width) + "x" +
|
123
|
+
std::to_string(height) + " IOSurface!");
|
108
124
|
}
|
109
125
|
|
110
|
-
//
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
&formatDescription);
|
126
|
+
// 4. Copy over the memory from the pixels into the IOSurface
|
127
|
+
IOSurfaceLock(surface, 0, nil);
|
128
|
+
void *base = IOSurfaceGetBaseAddress(surface);
|
129
|
+
memcpy(base, buf->data(), buf->size());
|
130
|
+
IOSurfaceUnlock(surface, 0, nil);
|
116
131
|
|
117
|
-
//
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
OSStatus status = CMSampleBufferCreateReadyWithImageBuffer(
|
126
|
-
kCFAllocatorDefault, pixelBuffer, formatDescription, &timingInfo,
|
127
|
-
&sampleBuffer);
|
128
|
-
|
129
|
-
if (status != noErr) {
|
130
|
-
if (formatDescription) {
|
131
|
-
CFRelease(formatDescription);
|
132
|
-
}
|
133
|
-
if (pixelBuffer) {
|
134
|
-
CFRelease(pixelBuffer);
|
135
|
-
}
|
136
|
-
return 0;
|
132
|
+
// 5. Create a CVPixelBuffer from the IOSurface
|
133
|
+
CVPixelBufferRef pixelBuffer = nullptr;
|
134
|
+
CVReturn result =
|
135
|
+
CVPixelBufferCreateWithIOSurface(nil, surface, nil, &pixelBuffer);
|
136
|
+
if (result != kCVReturnSuccess) {
|
137
|
+
throw std::runtime_error(
|
138
|
+
"Failed to create CVPixelBuffer from SkImage! Return value: " +
|
139
|
+
std::to_string(result));
|
137
140
|
}
|
138
141
|
|
139
|
-
// Return
|
140
|
-
return reinterpret_cast<uint64_t>(
|
142
|
+
// 8. Return CVPixelBuffer casted to uint64_t
|
143
|
+
return reinterpret_cast<uint64_t>(pixelBuffer);
|
141
144
|
}
|
142
145
|
|
143
146
|
void RNSkiOSPlatformContext::raiseError(const std::exception &err) {
|
@@ -149,35 +152,9 @@ sk_sp<SkSurface> RNSkiOSPlatformContext::makeOffscreenSurface(int width,
|
|
149
152
|
return SkiaMetalSurfaceFactory::makeOffscreenSurface(width, height);
|
150
153
|
}
|
151
154
|
|
152
|
-
sk_sp<SkImage>
|
153
|
-
|
154
|
-
|
155
|
-
// DO the CPU transfer (debugging only)
|
156
|
-
// Step 1: Extract the CVPixelBufferRef from the CMSampleBufferRef
|
157
|
-
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
|
158
|
-
|
159
|
-
// Step 2: Lock the pixel buffer to access the raw pixel data
|
160
|
-
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
|
161
|
-
|
162
|
-
// Step 3: Get information about the image
|
163
|
-
void *baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer);
|
164
|
-
size_t width = CVPixelBufferGetWidth(pixelBuffer);
|
165
|
-
size_t height = CVPixelBufferGetHeight(pixelBuffer);
|
166
|
-
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
|
167
|
-
|
168
|
-
// Assuming the pixel format is 32BGRA, which is common for iOS video frames.
|
169
|
-
// You might need to adjust this based on the actual pixel format.
|
170
|
-
SkImageInfo info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType,
|
171
|
-
kUnpremul_SkAlphaType);
|
172
|
-
|
173
|
-
// Step 4: Create an SkImage from the pixel buffer
|
174
|
-
sk_sp<SkData> data =
|
175
|
-
SkData::MakeWithoutCopy(baseAddress, height * bytesPerRow);
|
176
|
-
sk_sp<SkImage> image = SkImages::RasterFromData(info, data, bytesPerRow);
|
177
|
-
auto texture = SkiaMetalSurfaceFactory::makeTextureFromImage(image);
|
178
|
-
// Step 5: Unlock the pixel buffer
|
179
|
-
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
|
180
|
-
return texture;
|
155
|
+
sk_sp<SkImage> RNSkiOSPlatformContext::makeImageFromNativeBuffer(void *buffer) {
|
156
|
+
CVPixelBufferRef sampleBuffer = (CVPixelBufferRef)buffer;
|
157
|
+
return SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer(sampleBuffer);
|
181
158
|
}
|
182
159
|
|
183
160
|
sk_sp<SkFontMgr> RNSkiOSPlatformContext::createFontMgr() {
|
@@ -0,0 +1,119 @@
|
|
1
|
+
//
|
2
|
+
// SkiaCVPixelBufferUtils.h
|
3
|
+
// react-native-skia
|
4
|
+
//
|
5
|
+
// Created by Marc Rousavy on 10.04.24.
|
6
|
+
//
|
7
|
+
|
8
|
+
#pragma once
|
9
|
+
|
10
|
+
#import <vector>
|
11
|
+
|
12
|
+
#import <CoreMedia/CMSampleBuffer.h>
|
13
|
+
#import <CoreVideo/CVMetalTextureCache.h>
|
14
|
+
#import <MetalKit/MetalKit.h>
|
15
|
+
|
16
|
+
#pragma clang diagnostic push
|
17
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
18
|
+
#import "include/core/SkColorSpace.h"
|
19
|
+
#import "include/core/SkImage.h"
|
20
|
+
#import "include/gpu/GrBackendSurface.h"
|
21
|
+
#import "include/gpu/GrYUVABackendTextures.h"
|
22
|
+
#pragma clang diagnostic pop
|
23
|
+
|
24
|
+
/**
|
25
|
+
Holds a Metal Texture.
|
26
|
+
When the `TextureHolder` is destroyed, the underlying Metal Texture
|
27
|
+
is marked as invalid and might be overwritten by the Texture Cache,
|
28
|
+
so make sure to delete the `TextureHolder` only when the `SkImage`
|
29
|
+
has been deleted.
|
30
|
+
|
31
|
+
For example, use the `releaseProc` parameter in `BorrowImageFromTexture`
|
32
|
+
to delete the `TextureHolder`.
|
33
|
+
*/
|
34
|
+
class TextureHolder {
|
35
|
+
public:
|
36
|
+
/**
|
37
|
+
Create a new instance of TextureHolder which holds
|
38
|
+
the given `CVMetalTextureRef`.
|
39
|
+
|
40
|
+
The given `CVMetalTextureRef` is assumed to already be
|
41
|
+
retained with `CFRetain`, and will later be manually
|
42
|
+
released with `CFRelease`.
|
43
|
+
*/
|
44
|
+
TextureHolder(CVMetalTextureRef texture);
|
45
|
+
~TextureHolder();
|
46
|
+
|
47
|
+
/**
|
48
|
+
Converts this Texture to a Skia GrBackendTexture.
|
49
|
+
*/
|
50
|
+
GrBackendTexture toGrBackendTexture();
|
51
|
+
|
52
|
+
private:
|
53
|
+
CVMetalTextureRef _texture;
|
54
|
+
};
|
55
|
+
|
56
|
+
/**
|
57
|
+
Same as `TextureHolder`, but for multiple planar textures (e.g. YUVA)
|
58
|
+
*/
|
59
|
+
class MultiTexturesHolder {
|
60
|
+
public:
|
61
|
+
~MultiTexturesHolder();
|
62
|
+
void addTexture(TextureHolder *texture);
|
63
|
+
|
64
|
+
private:
|
65
|
+
std::vector<TextureHolder *> _textures;
|
66
|
+
};
|
67
|
+
|
68
|
+
class SkiaCVPixelBufferUtils {
|
69
|
+
public:
|
70
|
+
enum class CVPixelBufferBaseFormat { rgb, yuv };
|
71
|
+
|
72
|
+
/**
|
73
|
+
Get the base format (currently only RGB) of the PixelBuffer.
|
74
|
+
Depending on the base-format, different methods have to be used to create
|
75
|
+
Skia buffers.
|
76
|
+
*/
|
77
|
+
static CVPixelBufferBaseFormat
|
78
|
+
getCVPixelBufferBaseFormat(CVPixelBufferRef pixelBuffer);
|
79
|
+
|
80
|
+
class RGB {
|
81
|
+
public:
|
82
|
+
/**
|
83
|
+
Creates a GPU-backed Skia Texture (SkImage) with the given RGB
|
84
|
+
CVPixelBuffer.
|
85
|
+
*/
|
86
|
+
static sk_sp<SkImage>
|
87
|
+
makeSkImageFromCVPixelBuffer(GrDirectContext *context,
|
88
|
+
CVPixelBufferRef pixelBuffer);
|
89
|
+
|
90
|
+
private:
|
91
|
+
static SkColorType getCVPixelBufferColorType(CVPixelBufferRef pixelBuffer);
|
92
|
+
};
|
93
|
+
|
94
|
+
class YUV {
|
95
|
+
public:
|
96
|
+
/**
|
97
|
+
Creates a GPU-backed Skia Texture (SkImage) with the given YUV
|
98
|
+
CVPixelBuffer.
|
99
|
+
*/
|
100
|
+
static sk_sp<SkImage>
|
101
|
+
makeSkImageFromCVPixelBuffer(GrDirectContext *context,
|
102
|
+
CVPixelBufferRef pixelBuffer);
|
103
|
+
|
104
|
+
private:
|
105
|
+
static SkYUVAInfo::PlaneConfig getPlaneConfig(OSType pixelFormat);
|
106
|
+
static SkYUVAInfo::Subsampling getSubsampling(OSType pixelFormat);
|
107
|
+
static SkYUVColorSpace getColorspace(OSType pixelFormat);
|
108
|
+
static SkYUVAInfo getYUVAInfoForCVPixelBuffer(CVPixelBufferRef pixelBuffer);
|
109
|
+
};
|
110
|
+
|
111
|
+
private:
|
112
|
+
static CVMetalTextureCacheRef getTextureCache();
|
113
|
+
static TextureHolder *
|
114
|
+
getSkiaTextureForCVPixelBufferPlane(CVPixelBufferRef pixelBuffer,
|
115
|
+
size_t planeIndex);
|
116
|
+
static MTLPixelFormat
|
117
|
+
getMTLPixelFormatForCVPixelBufferPlane(CVPixelBufferRef pixelBuffer,
|
118
|
+
size_t planeIndex);
|
119
|
+
};
|