@shopify/react-native-skia 1.2.0 → 1.2.2
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/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
|
+
};
|