@shopify/react-native-skia 1.0.6 → 1.2.0
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/JsiPlatformBuffer.h +51 -0
- package/cpp/api/JsiSkApi.h +4 -0
- package/cpp/api/JsiSkImage.h +1 -1
- package/cpp/api/JsiSkImageFactory.h +15 -2
- package/cpp/api/JsiSkSurface.h +9 -1
- package/cpp/rnskia/RNSkJsiViewApi.h +48 -0
- package/cpp/rnskia/RNSkPlatformContext.h +13 -0
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +6 -0
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +115 -0
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +4 -0
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +12 -0
- 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/mock/index.js +1 -0
- package/lib/commonjs/mock/index.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 +14 -0
- package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
- package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +12 -0
- package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.js +6 -0
- package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.js.map +1 -0
- package/lib/commonjs/skia/types/PlatformBuffer/index.d.ts +1 -0
- package/lib/commonjs/skia/types/PlatformBuffer/index.js +17 -0
- package/lib/commonjs/skia/types/PlatformBuffer/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 +2 -2
- package/lib/commonjs/skia/web/JsiSkImageFactory.js +3 -0
- package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.d.ts +8 -0
- package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.js +20 -0
- package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.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 +2 -17
- 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/commonjs/views/SkiaDomView.d.ts +6 -0
- package/lib/commonjs/views/SkiaDomView.js +10 -0
- package/lib/commonjs/views/SkiaDomView.js.map +1 -1
- package/lib/commonjs/views/types.d.ts +1 -0
- package/lib/commonjs/views/types.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/mock/index.js +1 -0
- package/lib/module/mock/index.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 +14 -0
- package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
- package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +12 -0
- package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.js +2 -0
- package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.js.map +1 -0
- package/lib/module/skia/types/PlatformBuffer/index.d.ts +1 -0
- package/lib/module/skia/types/PlatformBuffer/index.js +2 -0
- package/lib/module/skia/types/PlatformBuffer/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 +2 -2
- package/lib/module/skia/web/JsiSkImageFactory.js +3 -0
- package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkPlatformBufferFactory.d.ts +8 -0
- package/lib/module/skia/web/JsiSkPlatformBufferFactory.js +13 -0
- package/lib/module/skia/web/JsiSkPlatformBufferFactory.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 +2 -17
- 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/module/views/SkiaDomView.d.ts +6 -0
- package/lib/module/views/SkiaDomView.js +10 -0
- package/lib/module/views/SkiaDomView.js.map +1 -1
- package/lib/module/views/types.d.ts +1 -0
- package/lib/module/views/types.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 +14 -0
- package/lib/typescript/src/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +12 -0
- package/lib/typescript/src/skia/types/PlatformBuffer/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 +2 -2
- package/lib/typescript/src/skia/web/JsiSkPlatformBufferFactory.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/lib/typescript/src/views/SkiaDomView.d.ts +6 -0
- package/lib/typescript/src/views/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/external/reanimated/textures.tsx +8 -2
- package/src/external/reanimated/useAnimatedImageValue.ts +12 -6
- package/src/mock/index.ts +1 -0
- package/src/renderer/Offscreen.tsx +3 -3
- package/src/skia/types/Image/ImageFactory.ts +15 -0
- package/src/skia/types/PlatformBuffer/PlatformBufferFactory.ts +14 -0
- package/src/skia/types/PlatformBuffer/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 +13 -2
- package/src/skia/web/JsiSkPlatformBufferFactory.ts +22 -0
- package/src/skia/web/JsiSkSurface.ts +10 -9
- package/src/skia/web/JsiSkSurfaceFactory.ts +4 -20
- package/src/skia/web/JsiSkia.ts +2 -0
- package/src/views/SkiaDomView.tsx +10 -0
- package/src/views/types.ts +1 -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> makeImageFromPlatformBuffer(void *buffer) override {
|
|
57
|
+
return SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer(buffer);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void releasePlatformBuffer(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 makePlatformBuffer(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,51 @@
|
|
|
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 JsiPlatformBufferFactory : public JsiSkHostObject {
|
|
19
|
+
public:
|
|
20
|
+
JSI_HOST_FUNCTION(MakeFromImage) {
|
|
21
|
+
auto image = JsiSkImage::fromValue(runtime, arguments[0]);
|
|
22
|
+
image->makeNonTextureImage();
|
|
23
|
+
|
|
24
|
+
uint64_t pointer = getContext()->makePlatformBuffer(image);
|
|
25
|
+
jsi::HostFunctionType deleteFunc =
|
|
26
|
+
[=](jsi::Runtime &runtime, const jsi::Value &thisArg,
|
|
27
|
+
const jsi::Value *args, size_t count) -> jsi::Value {
|
|
28
|
+
getContext()->releasePlatformBuffer(pointer);
|
|
29
|
+
return jsi::Value::undefined();
|
|
30
|
+
};
|
|
31
|
+
return jsi::BigInt::fromUint64(runtime, pointer);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
JSI_HOST_FUNCTION(Release) {
|
|
35
|
+
|
|
36
|
+
jsi::BigInt pointer = arguments[0].asBigInt(runtime);
|
|
37
|
+
const uintptr_t platformBufferPointer = pointer.asUint64(runtime);
|
|
38
|
+
|
|
39
|
+
getContext()->releasePlatformBuffer(platformBufferPointer);
|
|
40
|
+
return jsi::Value::undefined();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiPlatformBufferFactory, Release),
|
|
44
|
+
JSI_EXPORT_FUNC(JsiPlatformBufferFactory, MakeFromImage))
|
|
45
|
+
|
|
46
|
+
explicit JsiPlatformBufferFactory(
|
|
47
|
+
std::shared_ptr<RNSkPlatformContext> context)
|
|
48
|
+
: JsiSkHostObject(std::move(context)) {}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
} // namespace RNSkia
|
package/cpp/api/JsiSkApi.h
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
#include "JsiSkHostObjects.h"
|
|
8
8
|
|
|
9
|
+
#include "JsiPlatformBuffer.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(
|
|
128
|
+
"PlatformBuffer", std::make_shared<JsiPlatformBufferFactory>(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(MakeImageFromPlatformBuffer) {
|
|
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()->makeImageFromPlatformBuffer(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]);
|
|
@@ -47,7 +59,6 @@ public:
|
|
|
47
59
|
[context = std::move(context), viewTag](
|
|
48
60
|
jsi::Runtime &runtime,
|
|
49
61
|
std::shared_ptr<RNJsi::JsiPromises::Promise> promise) -> void {
|
|
50
|
-
// Create a stream operation - this will be run on the main thread
|
|
51
62
|
context->makeViewScreenshot(
|
|
52
63
|
viewTag, [&runtime, context = std::move(context),
|
|
53
64
|
promise = std::move(promise)](sk_sp<SkImage> image) {
|
|
@@ -69,7 +80,9 @@ public:
|
|
|
69
80
|
|
|
70
81
|
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromEncoded),
|
|
71
82
|
JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImageFromViewTag),
|
|
72
|
-
JSI_EXPORT_FUNC(JsiSkImageFactory,
|
|
83
|
+
JSI_EXPORT_FUNC(JsiSkImageFactory,
|
|
84
|
+
MakeImageFromPlatformBuffer),
|
|
85
|
+
JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImage))
|
|
73
86
|
|
|
74
87
|
explicit JsiSkImageFactory(std::shared_ptr<RNSkPlatformContext> context)
|
|
75
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))
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include <mutex>
|
|
6
6
|
#include <string>
|
|
7
7
|
#include <unordered_map>
|
|
8
|
+
#include <utility>
|
|
8
9
|
#include <vector>
|
|
9
10
|
|
|
10
11
|
#include "JsiHostObject.h"
|
|
@@ -177,9 +178,56 @@ public:
|
|
|
177
178
|
return jsi::Value::undefined();
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
JSI_HOST_FUNCTION(makeImageSnapshotAsync) {
|
|
182
|
+
if (count < 1) {
|
|
183
|
+
_platformContext->raiseError(std::string(
|
|
184
|
+
"makeImageSnapshotAsync: Expected at least 1 argument, got " +
|
|
185
|
+
std::to_string(count) + "."));
|
|
186
|
+
return jsi::Value::undefined();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (!arguments[0].isNumber()) {
|
|
190
|
+
_platformContext->raiseError(
|
|
191
|
+
"makeImageSnapshot: First argument must be a number");
|
|
192
|
+
return jsi::Value::undefined();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// find Skia view
|
|
196
|
+
int nativeId = arguments[0].asNumber();
|
|
197
|
+
auto info = getEnsuredViewInfo(nativeId);
|
|
198
|
+
auto context = _platformContext;
|
|
199
|
+
auto bounds =
|
|
200
|
+
count > 1 && !arguments[1].isUndefined() && !arguments[1].isNull()
|
|
201
|
+
? JsiSkRect::fromValue(runtime, arguments[1])
|
|
202
|
+
: nullptr;
|
|
203
|
+
return RNJsi::JsiPromises::createPromiseAsJSIValue(
|
|
204
|
+
runtime, [context = std::move(context), info, bounds](
|
|
205
|
+
jsi::Runtime &runtime,
|
|
206
|
+
std::shared_ptr<RNJsi::JsiPromises::Promise> promise) {
|
|
207
|
+
context->runOnMainThread([&runtime, info = std::move(info),
|
|
208
|
+
promise = std::move(promise),
|
|
209
|
+
context = std::move(context), bounds]() {
|
|
210
|
+
auto image = info->view->makeImageSnapshot(
|
|
211
|
+
bounds == nullptr ? nullptr : bounds.get());
|
|
212
|
+
context->runOnJavascriptThread(
|
|
213
|
+
[&runtime, context = std::move(context),
|
|
214
|
+
promise = std::move(promise), image = std::move(image)]() {
|
|
215
|
+
if (image == nullptr) {
|
|
216
|
+
promise->reject("Failed to make snapshot from view.");
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
promise->resolve(jsi::Object::createFromHostObject(
|
|
220
|
+
runtime, std::make_shared<JsiSkImage>(std::move(context),
|
|
221
|
+
std::move(image))));
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
180
227
|
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(RNSkJsiViewApi, setJsiProperty),
|
|
181
228
|
JSI_EXPORT_FUNC(RNSkJsiViewApi, callJsiMethod),
|
|
182
229
|
JSI_EXPORT_FUNC(RNSkJsiViewApi, requestRedraw),
|
|
230
|
+
JSI_EXPORT_FUNC(RNSkJsiViewApi, makeImageSnapshotAsync),
|
|
183
231
|
JSI_EXPORT_FUNC(RNSkJsiViewApi, makeImageSnapshot))
|
|
184
232
|
|
|
185
233
|
/**
|
|
@@ -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 platform buffer.
|
|
138
|
+
* - On iOS, this is a `CMSampleBuffer`
|
|
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> makeImageFromPlatformBuffer(void *buffer) = 0;
|
|
144
|
+
|
|
145
|
+
virtual void releasePlatformBuffer(uint64_t pointer) = 0;
|
|
146
|
+
|
|
147
|
+
virtual uint64_t makePlatformBuffer(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> makeImageFromPlatformBuffer(void *buffer) override;
|
|
63
|
+
|
|
64
|
+
uint64_t makePlatformBuffer(sk_sp<SkImage> image) override;
|
|
65
|
+
|
|
66
|
+
void releasePlatformBuffer(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,5 +1,6 @@
|
|
|
1
1
|
#include "RNSkiOSPlatformContext.h"
|
|
2
2
|
|
|
3
|
+
#import <CoreMedia/CMSampleBuffer.h>
|
|
3
4
|
#import <React/RCTUtils.h>
|
|
4
5
|
#include <thread>
|
|
5
6
|
#include <utility>
|
|
@@ -56,6 +57,89 @@ void RNSkiOSPlatformContext::performStreamOperation(
|
|
|
56
57
|
std::thread(loader).detach();
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
void RNSkiOSPlatformContext::releasePlatformBuffer(uint64_t pointer) {
|
|
61
|
+
CMSampleBufferRef sampleBuffer = reinterpret_cast<CMSampleBufferRef>(pointer);
|
|
62
|
+
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
|
|
63
|
+
if (sampleBuffer) {
|
|
64
|
+
CFRelease(sampleBuffer);
|
|
65
|
+
}
|
|
66
|
+
if (pixelBuffer) {
|
|
67
|
+
CFRelease(pixelBuffer);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
uint64_t RNSkiOSPlatformContext::makePlatformBuffer(sk_sp<SkImage> image) {
|
|
72
|
+
auto bytesPerPixel = image->imageInfo().bytesPerPixel();
|
|
73
|
+
int bytesPerRow = image->width() * bytesPerPixel;
|
|
74
|
+
auto buf = SkData::MakeUninitialized(image->width() * image->height() *
|
|
75
|
+
bytesPerPixel);
|
|
76
|
+
SkImageInfo info = SkImageInfo::Make(image->width(), image->height(),
|
|
77
|
+
image->colorType(), image->alphaType());
|
|
78
|
+
image->readPixels(nullptr, info, const_cast<void *>(buf->data()), bytesPerRow,
|
|
79
|
+
0, 0);
|
|
80
|
+
auto pixelData = const_cast<void *>(buf->data());
|
|
81
|
+
|
|
82
|
+
// Create a CVPixelBuffer from the raw pixel data
|
|
83
|
+
CVPixelBufferRef pixelBuffer = nullptr;
|
|
84
|
+
// OSType pixelFormatType = MapSkColorTypeToOSType(image->colorType());
|
|
85
|
+
|
|
86
|
+
// You will need to fill in the details for creating the pixel buffer
|
|
87
|
+
// CVPixelBufferCreateWithBytes or CVPixelBufferCreateWithPlanarBytes
|
|
88
|
+
// Create the CVPixelBuffer with the image data
|
|
89
|
+
void *context = static_cast<void *>(
|
|
90
|
+
new sk_sp<SkData>(buf)); // Create a copy for the context
|
|
91
|
+
CVReturn r = CVPixelBufferCreateWithBytes(
|
|
92
|
+
nullptr, // allocator
|
|
93
|
+
image->width(), image->height(), kCVPixelFormatType_32BGRA,
|
|
94
|
+
pixelData, // pixel data
|
|
95
|
+
bytesPerRow, // bytes per row
|
|
96
|
+
[](void *releaseRefCon, const void *baseAddress) { // release callback
|
|
97
|
+
auto buf = static_cast<sk_sp<SkData> *>(releaseRefCon);
|
|
98
|
+
buf->reset(); // This effectively calls unref on the SkData object
|
|
99
|
+
delete buf; // Cleanup the dynamically allocated context
|
|
100
|
+
},
|
|
101
|
+
context, // release callback context
|
|
102
|
+
nullptr, // pixel buffer attributes
|
|
103
|
+
&pixelBuffer // the newly created pixel buffer
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
if (r != kCVReturnSuccess) {
|
|
107
|
+
return 0; // or handle error appropriately
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Wrap the CVPixelBuffer in a CMSampleBuffer
|
|
111
|
+
CMSampleBufferRef sampleBuffer = nullptr;
|
|
112
|
+
|
|
113
|
+
CMFormatDescriptionRef formatDescription = nullptr;
|
|
114
|
+
CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer,
|
|
115
|
+
&formatDescription);
|
|
116
|
+
|
|
117
|
+
// Assuming no specific timing is required, we initialize the timing info to
|
|
118
|
+
// zero.
|
|
119
|
+
CMSampleTimingInfo timingInfo = {0};
|
|
120
|
+
timingInfo.duration = kCMTimeInvalid; // Indicate an unknown duration.
|
|
121
|
+
timingInfo.presentationTimeStamp = kCMTimeZero; // Start at time zero.
|
|
122
|
+
timingInfo.decodeTimeStamp = kCMTimeInvalid; // No specific decode time.
|
|
123
|
+
|
|
124
|
+
// Create the sample buffer.
|
|
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;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Return sampleBuffer casted to uint64_t
|
|
140
|
+
return reinterpret_cast<uint64_t>(sampleBuffer);
|
|
141
|
+
}
|
|
142
|
+
|
|
59
143
|
void RNSkiOSPlatformContext::raiseError(const std::exception &err) {
|
|
60
144
|
RCTFatal(RCTErrorWithMessage([NSString stringWithUTF8String:err.what()]));
|
|
61
145
|
}
|
|
@@ -65,6 +149,37 @@ sk_sp<SkSurface> RNSkiOSPlatformContext::makeOffscreenSurface(int width,
|
|
|
65
149
|
return SkiaMetalSurfaceFactory::makeOffscreenSurface(width, height);
|
|
66
150
|
}
|
|
67
151
|
|
|
152
|
+
sk_sp<SkImage>
|
|
153
|
+
RNSkiOSPlatformContext::makeImageFromPlatformBuffer(void *buffer) {
|
|
154
|
+
CMSampleBufferRef sampleBuffer = (CMSampleBufferRef)buffer;
|
|
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;
|
|
181
|
+
}
|
|
182
|
+
|
|
68
183
|
sk_sp<SkFontMgr> RNSkiOSPlatformContext::createFontMgr() {
|
|
69
184
|
return SkFontMgr_New_CoreText(nullptr);
|
|
70
185
|
}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
5
5
|
|
|
6
6
|
#import "include/core/SkCanvas.h"
|
|
7
|
+
#import <CoreMedia/CMSampleBuffer.h>
|
|
8
|
+
#import <CoreVideo/CVMetalTextureCache.h>
|
|
7
9
|
#import <include/gpu/GrDirectContext.h>
|
|
8
10
|
|
|
9
11
|
#pragma clang diagnostic pop
|
|
@@ -24,6 +26,8 @@ public:
|
|
|
24
26
|
int height);
|
|
25
27
|
static sk_sp<SkSurface> makeOffscreenSurface(int width, int height);
|
|
26
28
|
|
|
29
|
+
static sk_sp<SkImage> makeTextureFromImage(sk_sp<SkImage> image);
|
|
30
|
+
|
|
27
31
|
private:
|
|
28
32
|
static id<MTLDevice> device;
|
|
29
33
|
static bool
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
#import <include/gpu/GrBackendSurface.h>
|
|
13
13
|
#import <include/gpu/GrDirectContext.h>
|
|
14
|
+
#import <include/gpu/ganesh/SkImageGanesh.h>
|
|
14
15
|
#import <include/gpu/ganesh/SkSurfaceGanesh.h>
|
|
16
|
+
#import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>
|
|
15
17
|
|
|
16
18
|
#pragma clang diagnostic pop
|
|
17
19
|
|
|
@@ -103,3 +105,13 @@ sk_sp<SkSurface> SkiaMetalSurfaceFactory::makeOffscreenSurface(int width,
|
|
|
103
105
|
|
|
104
106
|
return surface;
|
|
105
107
|
}
|
|
108
|
+
|
|
109
|
+
sk_sp<SkImage>
|
|
110
|
+
SkiaMetalSurfaceFactory::makeTextureFromImage(sk_sp<SkImage> image) {
|
|
111
|
+
if (!SkiaMetalSurfaceFactory::createSkiaDirectContextIfNecessary(
|
|
112
|
+
&ThreadContextHolder::ThreadSkiaMetalContext)) {
|
|
113
|
+
throw std::runtime_error("Failed to create Skia Context for this Thread!");
|
|
114
|
+
}
|
|
115
|
+
return SkImages::TextureFromImage(
|
|
116
|
+
ThreadContextHolder::ThreadSkiaMetalContext.skContext.get(), image);
|
|
117
|
+
}
|