@shopify/react-native-skia 1.1.0 → 1.2.1
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 +1 -0
- package/android/build.gradle +1 -0
- package/android/cpp/rnskia-android/AHardwareBufferUtils.cpp +31 -0
- package/android/cpp/rnskia-android/AHardwareBufferUtils.h +13 -0
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +75 -0
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +29 -11
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +1 -2
- package/android/src/main/java/com/shopify/reactnative/skia/ViewScreenshotService.java +3 -2
- package/cpp/api/JsiNativeBuffer.h +43 -0
- package/cpp/api/JsiSkApi.h +4 -0
- package/cpp/api/JsiSkImage.h +1 -1
- package/cpp/api/JsiSkImageFactory.h +15 -1
- package/cpp/api/JsiSkSurface.h +9 -1
- package/cpp/rnskia/RNSkPlatformContext.h +13 -0
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +6 -0
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +98 -2
- package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.h +84 -0
- package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +159 -0
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +5 -0
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +37 -1
- package/lib/commonjs/external/reanimated/textures.js +11 -2
- package/lib/commonjs/external/reanimated/textures.js.map +1 -1
- package/lib/commonjs/external/reanimated/useAnimatedImageValue.d.ts +2 -1
- package/lib/commonjs/external/reanimated/useAnimatedImageValue.js +8 -4
- package/lib/commonjs/external/reanimated/useAnimatedImageValue.js.map +1 -1
- package/lib/commonjs/renderer/Offscreen.d.ts +2 -2
- package/lib/commonjs/renderer/Offscreen.js +2 -2
- package/lib/commonjs/renderer/Offscreen.js.map +1 -1
- package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +17 -10
- 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 -0
- package/lib/commonjs/skia/types/Skia.js.map +1 -1
- package/lib/commonjs/skia/types/Surface/Surface.d.ts +8 -0
- package/lib/commonjs/skia/types/Surface/Surface.js.map +1 -1
- package/lib/commonjs/skia/types/index.d.ts +1 -0
- package/lib/commonjs/skia/types/index.js +11 -0
- package/lib/commonjs/skia/types/index.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -2
- package/lib/commonjs/skia/web/JsiSkImage.js +5 -12
- package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +3 -2
- package/lib/commonjs/skia/web/JsiSkImageFactory.js +19 -0
- 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/JsiSkSurface.d.ts +3 -2
- package/lib/commonjs/skia/web/JsiSkSurface.js +8 -6
- package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkSurfaceFactory.d.ts +1 -1
- package/lib/commonjs/skia/web/JsiSkSurfaceFactory.js +1 -16
- package/lib/commonjs/skia/web/JsiSkSurfaceFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkia.js +3 -1
- package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
- package/lib/module/external/reanimated/textures.js +11 -2
- package/lib/module/external/reanimated/textures.js.map +1 -1
- package/lib/module/external/reanimated/useAnimatedImageValue.d.ts +2 -1
- package/lib/module/external/reanimated/useAnimatedImageValue.js +8 -4
- package/lib/module/external/reanimated/useAnimatedImageValue.js.map +1 -1
- package/lib/module/renderer/Offscreen.d.ts +2 -2
- package/lib/module/renderer/Offscreen.js +2 -2
- package/lib/module/renderer/Offscreen.js.map +1 -1
- package/lib/module/skia/types/Image/ImageFactory.d.ts +17 -10
- 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 -0
- package/lib/module/skia/types/Skia.js.map +1 -1
- package/lib/module/skia/types/Surface/Surface.d.ts +8 -0
- package/lib/module/skia/types/Surface/Surface.js.map +1 -1
- package/lib/module/skia/types/index.d.ts +1 -0
- package/lib/module/skia/types/index.js +1 -0
- package/lib/module/skia/types/index.js.map +1 -1
- package/lib/module/skia/web/JsiSkImage.d.ts +1 -2
- package/lib/module/skia/web/JsiSkImage.js +5 -12
- package/lib/module/skia/web/JsiSkImage.js.map +1 -1
- package/lib/module/skia/web/JsiSkImageFactory.d.ts +3 -2
- package/lib/module/skia/web/JsiSkImageFactory.js +19 -0
- 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/JsiSkSurface.d.ts +3 -2
- package/lib/module/skia/web/JsiSkSurface.js +8 -6
- package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
- package/lib/module/skia/web/JsiSkSurfaceFactory.d.ts +1 -1
- package/lib/module/skia/web/JsiSkSurfaceFactory.js +1 -16
- package/lib/module/skia/web/JsiSkSurfaceFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkia.js +3 -1
- package/lib/module/skia/web/JsiSkia.js.map +1 -1
- package/lib/typescript/src/external/reanimated/useAnimatedImageValue.d.ts +2 -1
- package/lib/typescript/src/renderer/Offscreen.d.ts +2 -2
- package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +17 -10
- 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 -0
- package/lib/typescript/src/skia/types/Surface/Surface.d.ts +8 -0
- package/lib/typescript/src/skia/types/index.d.ts +1 -0
- package/lib/typescript/src/skia/web/JsiSkImage.d.ts +1 -2
- 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/skia/web/JsiSkSurface.d.ts +3 -2
- package/lib/typescript/src/skia/web/JsiSkSurfaceFactory.d.ts +1 -1
- package/package.json +1 -1
- package/src/external/reanimated/textures.tsx +8 -2
- package/src/external/reanimated/useAnimatedImageValue.ts +12 -6
- package/src/renderer/Offscreen.tsx +3 -3
- package/src/skia/types/Image/ImageFactory.ts +17 -18
- 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 -1
- package/src/skia/types/Surface/Surface.ts +10 -0
- package/src/skia/types/index.ts +1 -0
- package/src/skia/web/JsiSkImage.ts +5 -22
- package/src/skia/web/JsiSkImageFactory.ts +36 -3
- package/src/skia/web/JsiSkNativeBufferFactory.ts +35 -0
- package/src/skia/web/JsiSkSurface.ts +10 -9
- package/src/skia/web/JsiSkSurfaceFactory.ts +3 -19
- package/src/skia/web/JsiSkia.ts +2 -0
- package/cpp/skia/include/third_party/vulkan/LICENSE +0 -29
- package/cpp/skia/modules/skcms/README.chromium +0 -6
- package/cpp/skia/readme.txt +0 -1
package/android/CMakeLists.txt
CHANGED
|
@@ -47,6 +47,7 @@ add_library(
|
|
|
47
47
|
"${PROJECT_SOURCE_DIR}/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp"
|
|
48
48
|
"${PROJECT_SOURCE_DIR}/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp"
|
|
49
49
|
"${PROJECT_SOURCE_DIR}/cpp/rnskia-android/GrAHardwareBufferUtils.cpp"
|
|
50
|
+
"${PROJECT_SOURCE_DIR}/cpp/rnskia-android/AHardwareBufferUtils.cpp"
|
|
50
51
|
|
|
51
52
|
"${PROJECT_SOURCE_DIR}/../cpp/jsi/JsiHostObject.cpp"
|
|
52
53
|
"${PROJECT_SOURCE_DIR}/../cpp/jsi/JsiValue.cpp"
|
package/android/build.gradle
CHANGED
|
@@ -137,6 +137,7 @@ android {
|
|
|
137
137
|
targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION)
|
|
138
138
|
versionCode 1
|
|
139
139
|
versionName "1.0"
|
|
140
|
+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
140
141
|
|
|
141
142
|
externalNativeBuild {
|
|
142
143
|
cmake {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#if __ANDROID_API__ >= 26
|
|
2
|
+
|
|
3
|
+
#include "AHardwareBufferUtils.h"
|
|
4
|
+
#include <android/hardware_buffer.h>
|
|
5
|
+
|
|
6
|
+
namespace RNSkia {
|
|
7
|
+
|
|
8
|
+
uint32_t GetBufferFormatFromSkColorType(SkColorType bufferFormat) {
|
|
9
|
+
switch (bufferFormat) {
|
|
10
|
+
case kRGBA_8888_SkColorType:
|
|
11
|
+
return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
|
|
12
|
+
case kRGB_888x_SkColorType:
|
|
13
|
+
return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
|
|
14
|
+
case kRGBA_F16_SkColorType:
|
|
15
|
+
return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
|
|
16
|
+
case kRGB_565_SkColorType:
|
|
17
|
+
return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
|
|
18
|
+
case kRGBA_1010102_SkColorType:
|
|
19
|
+
return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
|
|
20
|
+
#if __ANDROID_API__ >= 33
|
|
21
|
+
case kAlpha_8_SkColorType:
|
|
22
|
+
return AHARDWAREBUFFER_FORMAT_R8_UNORM;
|
|
23
|
+
#endif
|
|
24
|
+
default:
|
|
25
|
+
return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
} // namespace RNSkia
|
|
30
|
+
|
|
31
|
+
#endif
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
// TODO: Add android flags
|
|
4
|
+
#if __ANDROID_API__ >= 26
|
|
5
|
+
#include <android/hardware_buffer.h>
|
|
6
|
+
#endif
|
|
3
7
|
#include <exception>
|
|
4
8
|
#include <functional>
|
|
5
9
|
#include <memory>
|
|
6
10
|
#include <string>
|
|
7
11
|
|
|
12
|
+
#include "AHardwareBufferUtils.h"
|
|
8
13
|
#include "JniPlatformContext.h"
|
|
9
14
|
#include "RNSkPlatformContext.h"
|
|
10
15
|
#include "SkiaOpenGLSurfaceFactory.h"
|
|
@@ -48,6 +53,76 @@ public:
|
|
|
48
53
|
return SkiaOpenGLSurfaceFactory::makeOffscreenSurface(width, height);
|
|
49
54
|
}
|
|
50
55
|
|
|
56
|
+
sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) override {
|
|
57
|
+
return SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(buffer);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void releaseNativeBuffer(uint64_t pointer) override {
|
|
61
|
+
#if __ANDROID_API__ >= 26
|
|
62
|
+
AHardwareBuffer *buffer = reinterpret_cast<AHardwareBuffer *>(pointer);
|
|
63
|
+
AHardwareBuffer_release(buffer);
|
|
64
|
+
#endif
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
uint64_t makeNativeBuffer(sk_sp<SkImage> image) override {
|
|
68
|
+
#if __ANDROID_API__ >= 26
|
|
69
|
+
auto bytesPerPixel = image->imageInfo().bytesPerPixel();
|
|
70
|
+
int bytesPerRow = image->width() * bytesPerPixel;
|
|
71
|
+
auto buf = SkData::MakeUninitialized(image->width() * image->height() *
|
|
72
|
+
bytesPerPixel);
|
|
73
|
+
SkImageInfo info =
|
|
74
|
+
SkImageInfo::Make(image->width(), image->height(), image->colorType(),
|
|
75
|
+
image->alphaType());
|
|
76
|
+
image->readPixels(nullptr, info, const_cast<void *>(buf->data()),
|
|
77
|
+
bytesPerRow, 0, 0);
|
|
78
|
+
const void *pixelData = buf->data();
|
|
79
|
+
|
|
80
|
+
// Define the buffer description
|
|
81
|
+
AHardwareBuffer_Desc desc = {};
|
|
82
|
+
// TODO: use image info here
|
|
83
|
+
desc.width = image->width();
|
|
84
|
+
desc.height = image->height();
|
|
85
|
+
desc.layers = 1; // Single image layer
|
|
86
|
+
desc.format = GetBufferFormatFromSkColorType(
|
|
87
|
+
image->colorType()); // Assuming the image
|
|
88
|
+
// is in this format
|
|
89
|
+
desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
|
|
90
|
+
AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
|
|
91
|
+
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
|
|
92
|
+
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
|
|
93
|
+
desc.stride = bytesPerRow; // Stride in pixels, not in bytes
|
|
94
|
+
|
|
95
|
+
// Allocate the buffer
|
|
96
|
+
AHardwareBuffer *buffer = nullptr;
|
|
97
|
+
if (AHardwareBuffer_allocate(&desc, &buffer) != 0) {
|
|
98
|
+
// Handle allocation failure
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Map the buffer to gain access to its memory
|
|
103
|
+
void *mappedBuffer = nullptr;
|
|
104
|
+
AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1,
|
|
105
|
+
nullptr, &mappedBuffer);
|
|
106
|
+
if (mappedBuffer == nullptr) {
|
|
107
|
+
// Handle mapping failure
|
|
108
|
+
AHardwareBuffer_release(buffer);
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Copy the image data to the buffer
|
|
113
|
+
memcpy(mappedBuffer, pixelData, desc.height * bytesPerRow);
|
|
114
|
+
|
|
115
|
+
// Unmap the buffer
|
|
116
|
+
AHardwareBuffer_unlock(buffer, nullptr);
|
|
117
|
+
|
|
118
|
+
// Return the buffer pointer as a uint64_t. It's the caller's responsibility
|
|
119
|
+
// to manage this buffer.
|
|
120
|
+
return reinterpret_cast<uint64_t>(buffer);
|
|
121
|
+
#else
|
|
122
|
+
return 0;
|
|
123
|
+
#endif
|
|
124
|
+
}
|
|
125
|
+
|
|
51
126
|
sk_sp<SkFontMgr> createFontMgr() override {
|
|
52
127
|
return SkFontMgr_New_Android(nullptr);
|
|
53
128
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#include "include/gpu/ganesh/SkImageGanesh.h"
|
|
9
9
|
#include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
|
|
10
|
+
#include "src/gpu/ganesh/gl/GrGLDefines.h"
|
|
10
11
|
|
|
11
12
|
#pragma clang diagnostic pop
|
|
12
13
|
|
|
@@ -15,30 +16,47 @@ namespace RNSkia {
|
|
|
15
16
|
thread_local SkiaOpenGLContext ThreadContextHolder::ThreadSkiaOpenGLContext;
|
|
16
17
|
|
|
17
18
|
sk_sp<SkImage>
|
|
18
|
-
SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(
|
|
19
|
-
void *buffer) {
|
|
19
|
+
SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(void *buffer) {
|
|
20
20
|
#if __ANDROID_API__ >= 26
|
|
21
|
+
// Setup OpenGL and Skia:
|
|
22
|
+
if (!SkiaOpenGLHelper::createSkiaDirectContextIfNecessary(
|
|
23
|
+
&ThreadContextHolder::ThreadSkiaOpenGLContext)) {
|
|
24
|
+
|
|
25
|
+
RNSkLogger::logToConsole(
|
|
26
|
+
"Could not create Skia Surface from native window / surface. "
|
|
27
|
+
"Failed creating Skia Direct Context");
|
|
28
|
+
return nullptr;
|
|
29
|
+
}
|
|
21
30
|
const AHardwareBuffer *hardwareBuffer =
|
|
22
31
|
static_cast<AHardwareBuffer *>(buffer);
|
|
23
32
|
DeleteImageProc deleteImageProc = nullptr;
|
|
24
33
|
UpdateImageProc updateImageProc = nullptr;
|
|
25
34
|
TexImageCtx deleteImageCtx = nullptr;
|
|
35
|
+
|
|
36
|
+
AHardwareBuffer_Desc description;
|
|
37
|
+
AHardwareBuffer_describe(hardwareBuffer, &description);
|
|
38
|
+
if (description.format != AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) {
|
|
39
|
+
throw std::runtime_error("AHardwareBuffer has unknown format (" +
|
|
40
|
+
std::to_string(description.format) +
|
|
41
|
+
") - cannot convert to SkImage!");
|
|
42
|
+
}
|
|
43
|
+
GrBackendFormat format =
|
|
44
|
+
GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
|
|
45
|
+
|
|
26
46
|
auto backendTex = MakeGLBackendTexture(
|
|
27
47
|
ThreadContextHolder::ThreadSkiaOpenGLContext.directContext.get(),
|
|
28
|
-
const_cast<AHardwareBuffer *>(hardwareBuffer),
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// GR_GL_TEXTURE_EXTERNAL 0x8D65
|
|
32
|
-
GrBackendFormats::MakeGL(0x8058, 0x8D65), false);
|
|
48
|
+
const_cast<AHardwareBuffer *>(hardwareBuffer), description.width,
|
|
49
|
+
description.height, &deleteImageProc, &updateImageProc, &deleteImageCtx,
|
|
50
|
+
false, format, false);
|
|
33
51
|
sk_sp<SkImage> image = SkImages::BorrowTextureFrom(
|
|
34
52
|
ThreadContextHolder::ThreadSkiaOpenGLContext.directContext.get(),
|
|
35
53
|
backendTex, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
|
36
|
-
|
|
54
|
+
kOpaque_SkAlphaType, nullptr);
|
|
37
55
|
return image;
|
|
38
56
|
#else
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
57
|
+
throw std::runtime_error(
|
|
58
|
+
"HardwareBuffers are only supported on Android API 26 or higher! Set "
|
|
59
|
+
"your minSdk to 26 (or higher) and try again.");
|
|
42
60
|
#endif
|
|
43
61
|
}
|
|
44
62
|
|
|
@@ -149,8 +149,7 @@ public:
|
|
|
149
149
|
*/
|
|
150
150
|
static sk_sp<SkSurface> makeOffscreenSurface(int width, int height);
|
|
151
151
|
|
|
152
|
-
static sk_sp<SkImage> makeImageFromHardwareBuffer(
|
|
153
|
-
void *buffer);
|
|
152
|
+
static sk_sp<SkImage> makeImageFromHardwareBuffer(void *buffer);
|
|
154
153
|
|
|
155
154
|
/**
|
|
156
155
|
* Creates a windowed Skia Surface holder.
|
|
@@ -17,7 +17,8 @@ import android.view.ViewGroup;
|
|
|
17
17
|
import android.widget.ScrollView;
|
|
18
18
|
import androidx.annotation.NonNull;
|
|
19
19
|
import com.facebook.react.bridge.ReactContext;
|
|
20
|
-
import com.facebook.react.
|
|
20
|
+
import com.facebook.react.bridge.UIManager;
|
|
21
|
+
import com.facebook.react.uimanager.UIManagerHelper;
|
|
21
22
|
import com.facebook.react.views.view.ReactViewGroup;
|
|
22
23
|
|
|
23
24
|
import java.lang.reflect.Method;
|
|
@@ -29,7 +30,7 @@ public class ViewScreenshotService {
|
|
|
29
30
|
private static final String TAG = "SkiaScreenshot";
|
|
30
31
|
|
|
31
32
|
public static Bitmap makeViewScreenshotFromTag(ReactContext context, int tag) {
|
|
32
|
-
|
|
33
|
+
UIManager uiManager = UIManagerHelper.getUIManagerForReactTag(context, tag);
|
|
33
34
|
View view = null;
|
|
34
35
|
try {
|
|
35
36
|
view = uiManager.resolveView(tag);
|
|
@@ -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,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
#include "JsiSkHostObjects.h"
|
|
8
8
|
|
|
9
|
+
#include "JsiNativeBuffer.h"
|
|
9
10
|
#include "JsiSkAnimatedImage.h"
|
|
10
11
|
#include "JsiSkAnimatedImageFactory.h"
|
|
11
12
|
#include "JsiSkColor.h"
|
|
@@ -122,6 +123,9 @@ public:
|
|
|
122
123
|
installReadonlyProperty(
|
|
123
124
|
"ParagraphBuilder",
|
|
124
125
|
std::make_shared<JsiSkParagraphBuilderFactory>(context));
|
|
126
|
+
|
|
127
|
+
installReadonlyProperty("NativeBuffer",
|
|
128
|
+
std::make_shared<JsiNativeBufferFactory>(context));
|
|
125
129
|
}
|
|
126
130
|
};
|
|
127
131
|
} // namespace RNSkia
|
package/cpp/api/JsiSkImage.h
CHANGED
|
@@ -27,6 +27,18 @@ public:
|
|
|
27
27
|
runtime, std::make_shared<JsiSkImage>(getContext(), std::move(image)));
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
JSI_HOST_FUNCTION(MakeImageFromNativeBuffer) {
|
|
31
|
+
jsi::BigInt pointer = arguments[0].asBigInt(runtime);
|
|
32
|
+
const uintptr_t platformBufferPointer = pointer.asUint64(runtime);
|
|
33
|
+
void *rawPointer = reinterpret_cast<void *>(platformBufferPointer);
|
|
34
|
+
auto image = getContext()->makeImageFromNativeBuffer(rawPointer);
|
|
35
|
+
if (image == nullptr) {
|
|
36
|
+
throw std::runtime_error("Failed to convert PlatformBuffer to SkImage!");
|
|
37
|
+
}
|
|
38
|
+
return jsi::Object::createFromHostObject(
|
|
39
|
+
runtime, std::make_shared<JsiSkImage>(getContext(), std::move(image)));
|
|
40
|
+
}
|
|
41
|
+
|
|
30
42
|
JSI_HOST_FUNCTION(MakeImage) {
|
|
31
43
|
auto imageInfo = JsiSkImageInfo::fromValue(runtime, arguments[0]);
|
|
32
44
|
auto pixelData = JsiSkData::fromValue(runtime, arguments[1]);
|
|
@@ -68,7 +80,9 @@ public:
|
|
|
68
80
|
|
|
69
81
|
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromEncoded),
|
|
70
82
|
JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromViewTag),
|
|
71
|
-
JSI_EXPORT_FUNC(JsiSkImageFactory,
|
|
83
|
+
JSI_EXPORT_FUNC(JsiSkImageFactory,
|
|
84
|
+
MakeImageFromNativeBuffer),
|
|
85
|
+
JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImage))
|
|
72
86
|
|
|
73
87
|
explicit JsiSkImageFactory(std::shared_ptr<RNSkPlatformContext> context)
|
|
74
88
|
: JsiSkHostObject(std::move(context)) {}
|
package/cpp/api/JsiSkSurface.h
CHANGED
|
@@ -31,6 +31,12 @@ public:
|
|
|
31
31
|
|
|
32
32
|
EXPORT_JSI_API_TYPENAME(JsiSkSurface, Surface)
|
|
33
33
|
|
|
34
|
+
// TODO-API: Properties?
|
|
35
|
+
JSI_HOST_FUNCTION(width) { return static_cast<double>(getObject()->width()); }
|
|
36
|
+
JSI_HOST_FUNCTION(height) {
|
|
37
|
+
return static_cast<double>(getObject()->height());
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
JSI_HOST_FUNCTION(getCanvas) {
|
|
35
41
|
return jsi::Object::createFromHostObject(
|
|
36
42
|
runtime,
|
|
@@ -57,7 +63,9 @@ public:
|
|
|
57
63
|
runtime, std::make_shared<JsiSkImage>(getContext(), std::move(image)));
|
|
58
64
|
}
|
|
59
65
|
|
|
60
|
-
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkSurface,
|
|
66
|
+
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkSurface, width),
|
|
67
|
+
JSI_EXPORT_FUNC(JsiSkSurface, height),
|
|
68
|
+
JSI_EXPORT_FUNC(JsiSkSurface, getCanvas),
|
|
61
69
|
JSI_EXPORT_FUNC(JsiSkSurface, makeImageSnapshot),
|
|
62
70
|
JSI_EXPORT_FUNC(JsiSkSurface, flush),
|
|
63
71
|
JSI_EXPORT_FUNC(JsiSkSurface, dispose))
|
|
@@ -133,6 +133,19 @@ public:
|
|
|
133
133
|
*/
|
|
134
134
|
virtual sk_sp<SkSurface> makeOffscreenSurface(int width, int height) = 0;
|
|
135
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Creates an image from a native buffer. (for testing purposes only)
|
|
138
|
+
* - On iOS, this is a `CVPixelBufferRef*`
|
|
139
|
+
* - On Android, this is a `AHardwareBuffer*`
|
|
140
|
+
* @param buffer The native platform buffer.
|
|
141
|
+
* @return sk_sp<SkImage>
|
|
142
|
+
*/
|
|
143
|
+
virtual sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) = 0;
|
|
144
|
+
|
|
145
|
+
virtual void releaseNativeBuffer(uint64_t pointer) = 0;
|
|
146
|
+
|
|
147
|
+
virtual uint64_t makeNativeBuffer(sk_sp<SkImage> image) = 0;
|
|
148
|
+
|
|
136
149
|
/**
|
|
137
150
|
* Return the Platform specific font manager
|
|
138
151
|
*/
|
|
@@ -59,6 +59,12 @@ public:
|
|
|
59
59
|
|
|
60
60
|
sk_sp<SkImage> takeScreenshotFromViewTag(size_t tag) override;
|
|
61
61
|
|
|
62
|
+
sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) override;
|
|
63
|
+
|
|
64
|
+
uint64_t makeNativeBuffer(sk_sp<SkImage> image) override;
|
|
65
|
+
|
|
66
|
+
void releaseNativeBuffer(uint64_t pointer) override;
|
|
67
|
+
|
|
62
68
|
virtual void performStreamOperation(
|
|
63
69
|
const std::string &sourceUri,
|
|
64
70
|
const std::function<void(std::unique_ptr<SkStreamAsset>)> &op) override;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
#import "RNSkiOSPlatformContext.h"
|
|
2
2
|
|
|
3
|
+
#import <CoreMedia/CMSampleBuffer.h>
|
|
3
4
|
#import <React/RCTUtils.h>
|
|
4
5
|
#include <thread>
|
|
5
6
|
#include <utility>
|
|
6
7
|
|
|
7
|
-
#
|
|
8
|
+
#import "SkiaCVPixelBufferUtils.h"
|
|
9
|
+
#import "SkiaMetalSurfaceFactory.h"
|
|
8
10
|
|
|
9
11
|
#pragma clang diagnostic push
|
|
10
12
|
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
@@ -56,6 +58,95 @@ void RNSkiOSPlatformContext::performStreamOperation(
|
|
|
56
58
|
std::thread(loader).detach();
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
void RNSkiOSPlatformContext::releaseNativeBuffer(uint64_t pointer) {
|
|
62
|
+
CMSampleBufferRef sampleBuffer = reinterpret_cast<CMSampleBufferRef>(pointer);
|
|
63
|
+
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
|
|
64
|
+
if (sampleBuffer) {
|
|
65
|
+
CFRelease(sampleBuffer);
|
|
66
|
+
}
|
|
67
|
+
if (pixelBuffer) {
|
|
68
|
+
CFRelease(pixelBuffer);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
uint64_t RNSkiOSPlatformContext::makeNativeBuffer(sk_sp<SkImage> image) {
|
|
73
|
+
// 0. If Image is not in BGRA, convert to BGRA as only BGRA is supported.
|
|
74
|
+
if (image->colorType() != kBGRA_8888_SkColorType) {
|
|
75
|
+
// on iOS, 32_BGRA is the only supported RGB format for CVPixelBuffers.
|
|
76
|
+
image = image->makeColorTypeAndColorSpace(
|
|
77
|
+
ThreadContextHolder::ThreadSkiaMetalContext.skContext.get(),
|
|
78
|
+
kBGRA_8888_SkColorType, SkColorSpace::MakeSRGB());
|
|
79
|
+
if (image == nullptr) {
|
|
80
|
+
throw std::runtime_error(
|
|
81
|
+
"Failed to convert image to BGRA_8888 colortype! Only BGRA_8888 "
|
|
82
|
+
"PlatformBuffers are supported.");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 1. Get image info
|
|
87
|
+
auto bytesPerPixel = image->imageInfo().bytesPerPixel();
|
|
88
|
+
int bytesPerRow = image->width() * bytesPerPixel;
|
|
89
|
+
auto buf = SkData::MakeUninitialized(image->width() * image->height() *
|
|
90
|
+
bytesPerPixel);
|
|
91
|
+
SkImageInfo info = SkImageInfo::Make(image->width(), image->height(),
|
|
92
|
+
image->colorType(), image->alphaType());
|
|
93
|
+
// 2. Copy pixels into our buffer
|
|
94
|
+
image->readPixels(nullptr, info, const_cast<void *>(buf->data()), bytesPerRow,
|
|
95
|
+
0, 0);
|
|
96
|
+
|
|
97
|
+
// 3. Create an IOSurface (GPU + CPU memory)
|
|
98
|
+
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
|
|
99
|
+
kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
|
|
100
|
+
&kCFTypeDictionaryValueCallBacks);
|
|
101
|
+
int width = image->width();
|
|
102
|
+
int height = image->height();
|
|
103
|
+
int pitch = width * bytesPerPixel;
|
|
104
|
+
int size = width * height * bytesPerPixel;
|
|
105
|
+
OSType pixelFormat = kCVPixelFormatType_32BGRA;
|
|
106
|
+
CFDictionarySetValue(
|
|
107
|
+
dict, kIOSurfaceBytesPerRow,
|
|
108
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch));
|
|
109
|
+
CFDictionarySetValue(
|
|
110
|
+
dict, kIOSurfaceBytesPerElement,
|
|
111
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bytesPerPixel));
|
|
112
|
+
CFDictionarySetValue(
|
|
113
|
+
dict, kIOSurfaceWidth,
|
|
114
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width));
|
|
115
|
+
CFDictionarySetValue(
|
|
116
|
+
dict, kIOSurfaceHeight,
|
|
117
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height));
|
|
118
|
+
CFDictionarySetValue(
|
|
119
|
+
dict, kIOSurfacePixelFormat,
|
|
120
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pixelFormat));
|
|
121
|
+
CFDictionarySetValue(
|
|
122
|
+
dict, kIOSurfaceAllocSize,
|
|
123
|
+
CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &size));
|
|
124
|
+
IOSurfaceRef surface = IOSurfaceCreate(dict);
|
|
125
|
+
if (surface == nil) {
|
|
126
|
+
throw std::runtime_error("Failed to create " + std::to_string(width) + "x" +
|
|
127
|
+
std::to_string(height) + " IOSurface!");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// 4. Copy over the memory from the pixels into the IOSurface
|
|
131
|
+
IOSurfaceLock(surface, 0, nil);
|
|
132
|
+
void *base = IOSurfaceGetBaseAddress(surface);
|
|
133
|
+
memcpy(base, buf->data(), buf->size());
|
|
134
|
+
IOSurfaceUnlock(surface, 0, nil);
|
|
135
|
+
|
|
136
|
+
// 5. Create a CVPixelBuffer from the IOSurface
|
|
137
|
+
CVPixelBufferRef pixelBuffer = nullptr;
|
|
138
|
+
CVReturn result =
|
|
139
|
+
CVPixelBufferCreateWithIOSurface(nil, surface, nil, &pixelBuffer);
|
|
140
|
+
if (result != kCVReturnSuccess) {
|
|
141
|
+
throw std::runtime_error(
|
|
142
|
+
"Failed to create CVPixelBuffer from SkImage! Return value: " +
|
|
143
|
+
std::to_string(result));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// 8. Return CVPixelBuffer casted to uint64_t
|
|
147
|
+
return reinterpret_cast<uint64_t>(pixelBuffer);
|
|
148
|
+
}
|
|
149
|
+
|
|
59
150
|
void RNSkiOSPlatformContext::raiseError(const std::exception &err) {
|
|
60
151
|
RCTFatal(RCTErrorWithMessage([NSString stringWithUTF8String:err.what()]));
|
|
61
152
|
}
|
|
@@ -65,6 +156,11 @@ sk_sp<SkSurface> RNSkiOSPlatformContext::makeOffscreenSurface(int width,
|
|
|
65
156
|
return SkiaMetalSurfaceFactory::makeOffscreenSurface(width, height);
|
|
66
157
|
}
|
|
67
158
|
|
|
159
|
+
sk_sp<SkImage> RNSkiOSPlatformContext::makeImageFromNativeBuffer(void *buffer) {
|
|
160
|
+
CVPixelBufferRef sampleBuffer = (CVPixelBufferRef)buffer;
|
|
161
|
+
return SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer(sampleBuffer);
|
|
162
|
+
}
|
|
163
|
+
|
|
68
164
|
sk_sp<SkFontMgr> RNSkiOSPlatformContext::createFontMgr() {
|
|
69
165
|
return SkFontMgr_New_CoreText(nullptr);
|
|
70
166
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
//
|
|
2
|
+
// SkiaCVPixelBufferUtils.h
|
|
3
|
+
// react-native-skia
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 10.04.24.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
#import <CoreMedia/CMSampleBuffer.h>
|
|
10
|
+
#import <CoreVideo/CVMetalTextureCache.h>
|
|
11
|
+
#import <MetalKit/MetalKit.h>
|
|
12
|
+
|
|
13
|
+
#pragma clang diagnostic push
|
|
14
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
15
|
+
#import "include/core/SkColorSpace.h"
|
|
16
|
+
#import <include/gpu/GrBackendSurface.h>
|
|
17
|
+
#pragma clang diagnostic pop
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
Holds a Metal Texture.
|
|
21
|
+
When the `TextureHolder` is destroyed, the underlying Metal Texture
|
|
22
|
+
is marked as invalid and might be overwritten by the Texture Cache,
|
|
23
|
+
so make sure to delete the `TextureHolder` only when the `SkImage`
|
|
24
|
+
has been deleted.
|
|
25
|
+
|
|
26
|
+
For example, use the `releaseProc` parameter in `BorrowImageFromTexture`
|
|
27
|
+
to delete the `TextureHolder`.
|
|
28
|
+
*/
|
|
29
|
+
class TextureHolder {
|
|
30
|
+
public:
|
|
31
|
+
/**
|
|
32
|
+
Create a new instance of TextureHolder which holds
|
|
33
|
+
the given `CVMetalTextureRef`.
|
|
34
|
+
|
|
35
|
+
The given `CVMetalTextureRef` is assumed to already be
|
|
36
|
+
retained with `CFRetain`, and will later be manually
|
|
37
|
+
released with `CFRelease`.
|
|
38
|
+
*/
|
|
39
|
+
explicit TextureHolder(CVMetalTextureRef texture);
|
|
40
|
+
~TextureHolder();
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
Converts this Texture to a Skia GrBackendTexture.
|
|
44
|
+
*/
|
|
45
|
+
GrBackendTexture toGrBackendTexture();
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
CVMetalTextureRef _texture;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
class SkiaCVPixelBufferUtils {
|
|
52
|
+
public:
|
|
53
|
+
enum class CVPixelBufferBaseFormat { rgb };
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
Get the base format (currently only RGB) of the PixelBuffer.
|
|
57
|
+
Depending on the base-format, different methods have to be used to create
|
|
58
|
+
Skia buffers.
|
|
59
|
+
*/
|
|
60
|
+
static CVPixelBufferBaseFormat
|
|
61
|
+
getCVPixelBufferBaseFormat(CVPixelBufferRef pixelBuffer);
|
|
62
|
+
|
|
63
|
+
class RGB {
|
|
64
|
+
public:
|
|
65
|
+
/**
|
|
66
|
+
Gets the Skia Color Type of the RGB pixel-buffer.
|
|
67
|
+
*/
|
|
68
|
+
static SkColorType getCVPixelBufferColorType(CVPixelBufferRef pixelBuffer);
|
|
69
|
+
/**
|
|
70
|
+
Gets a GPU-backed Skia Texture for the given RGB CVPixelBuffer.
|
|
71
|
+
*/
|
|
72
|
+
static TextureHolder *
|
|
73
|
+
getSkiaTextureForCVPixelBuffer(CVPixelBufferRef pixelBuffer);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
private:
|
|
77
|
+
static CVMetalTextureCacheRef getTextureCache();
|
|
78
|
+
static TextureHolder *
|
|
79
|
+
getSkiaTextureForCVPixelBufferPlane(CVPixelBufferRef pixelBuffer,
|
|
80
|
+
size_t planeIndex);
|
|
81
|
+
static MTLPixelFormat
|
|
82
|
+
getMTLPixelFormatForCVPixelBufferPlane(CVPixelBufferRef pixelBuffer,
|
|
83
|
+
size_t planeIndex);
|
|
84
|
+
};
|