@shopify/react-native-skia 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. package/android/CMakeLists.txt +1 -0
  2. package/android/build.gradle +1 -0
  3. package/android/cpp/rnskia-android/AHardwareBufferUtils.cpp +31 -0
  4. package/android/cpp/rnskia-android/AHardwareBufferUtils.h +13 -0
  5. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +75 -0
  6. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +29 -11
  7. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +1 -2
  8. package/android/src/main/java/com/shopify/reactnative/skia/ViewScreenshotService.java +3 -2
  9. package/cpp/api/JsiPlatformBuffer.h +51 -0
  10. package/cpp/api/JsiSkApi.h +4 -0
  11. package/cpp/api/JsiSkImage.h +1 -1
  12. package/cpp/api/JsiSkImageFactory.h +15 -1
  13. package/cpp/api/JsiSkSurface.h +9 -1
  14. package/cpp/rnskia/RNSkPlatformContext.h +13 -0
  15. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +6 -0
  16. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +115 -0
  17. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +4 -0
  18. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +12 -0
  19. package/lib/commonjs/external/reanimated/textures.js +11 -2
  20. package/lib/commonjs/external/reanimated/textures.js.map +1 -1
  21. package/lib/commonjs/external/reanimated/useAnimatedImageValue.d.ts +2 -1
  22. package/lib/commonjs/external/reanimated/useAnimatedImageValue.js +8 -4
  23. package/lib/commonjs/external/reanimated/useAnimatedImageValue.js.map +1 -1
  24. package/lib/commonjs/renderer/Offscreen.d.ts +2 -2
  25. package/lib/commonjs/renderer/Offscreen.js +2 -2
  26. package/lib/commonjs/renderer/Offscreen.js.map +1 -1
  27. package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +14 -0
  28. package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
  29. package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +12 -0
  30. package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.js +6 -0
  31. package/lib/commonjs/skia/types/PlatformBuffer/PlatformBufferFactory.js.map +1 -0
  32. package/lib/commonjs/skia/types/PlatformBuffer/index.d.ts +1 -0
  33. package/lib/commonjs/skia/types/PlatformBuffer/index.js +17 -0
  34. package/lib/commonjs/skia/types/PlatformBuffer/index.js.map +1 -0
  35. package/lib/commonjs/skia/types/Skia.d.ts +2 -0
  36. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  37. package/lib/commonjs/skia/types/Surface/Surface.d.ts +8 -0
  38. package/lib/commonjs/skia/types/Surface/Surface.js.map +1 -1
  39. package/lib/commonjs/skia/types/index.d.ts +1 -0
  40. package/lib/commonjs/skia/types/index.js +11 -0
  41. package/lib/commonjs/skia/types/index.js.map +1 -1
  42. package/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -2
  43. package/lib/commonjs/skia/web/JsiSkImage.js +5 -12
  44. package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
  45. package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +2 -2
  46. package/lib/commonjs/skia/web/JsiSkImageFactory.js +3 -0
  47. package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
  48. package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.d.ts +8 -0
  49. package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.js +20 -0
  50. package/lib/commonjs/skia/web/JsiSkPlatformBufferFactory.js.map +1 -0
  51. package/lib/commonjs/skia/web/JsiSkSurface.d.ts +3 -2
  52. package/lib/commonjs/skia/web/JsiSkSurface.js +8 -6
  53. package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
  54. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.d.ts +1 -1
  55. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.js +1 -16
  56. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.js.map +1 -1
  57. package/lib/commonjs/skia/web/JsiSkia.js +3 -1
  58. package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
  59. package/lib/module/external/reanimated/textures.js +11 -2
  60. package/lib/module/external/reanimated/textures.js.map +1 -1
  61. package/lib/module/external/reanimated/useAnimatedImageValue.d.ts +2 -1
  62. package/lib/module/external/reanimated/useAnimatedImageValue.js +8 -4
  63. package/lib/module/external/reanimated/useAnimatedImageValue.js.map +1 -1
  64. package/lib/module/renderer/Offscreen.d.ts +2 -2
  65. package/lib/module/renderer/Offscreen.js +2 -2
  66. package/lib/module/renderer/Offscreen.js.map +1 -1
  67. package/lib/module/skia/types/Image/ImageFactory.d.ts +14 -0
  68. package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
  69. package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +12 -0
  70. package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.js +2 -0
  71. package/lib/module/skia/types/PlatformBuffer/PlatformBufferFactory.js.map +1 -0
  72. package/lib/module/skia/types/PlatformBuffer/index.d.ts +1 -0
  73. package/lib/module/skia/types/PlatformBuffer/index.js +2 -0
  74. package/lib/module/skia/types/PlatformBuffer/index.js.map +1 -0
  75. package/lib/module/skia/types/Skia.d.ts +2 -0
  76. package/lib/module/skia/types/Skia.js.map +1 -1
  77. package/lib/module/skia/types/Surface/Surface.d.ts +8 -0
  78. package/lib/module/skia/types/Surface/Surface.js.map +1 -1
  79. package/lib/module/skia/types/index.d.ts +1 -0
  80. package/lib/module/skia/types/index.js +1 -0
  81. package/lib/module/skia/types/index.js.map +1 -1
  82. package/lib/module/skia/web/JsiSkImage.d.ts +1 -2
  83. package/lib/module/skia/web/JsiSkImage.js +5 -12
  84. package/lib/module/skia/web/JsiSkImage.js.map +1 -1
  85. package/lib/module/skia/web/JsiSkImageFactory.d.ts +2 -2
  86. package/lib/module/skia/web/JsiSkImageFactory.js +3 -0
  87. package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
  88. package/lib/module/skia/web/JsiSkPlatformBufferFactory.d.ts +8 -0
  89. package/lib/module/skia/web/JsiSkPlatformBufferFactory.js +13 -0
  90. package/lib/module/skia/web/JsiSkPlatformBufferFactory.js.map +1 -0
  91. package/lib/module/skia/web/JsiSkSurface.d.ts +3 -2
  92. package/lib/module/skia/web/JsiSkSurface.js +8 -6
  93. package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
  94. package/lib/module/skia/web/JsiSkSurfaceFactory.d.ts +1 -1
  95. package/lib/module/skia/web/JsiSkSurfaceFactory.js +1 -16
  96. package/lib/module/skia/web/JsiSkSurfaceFactory.js.map +1 -1
  97. package/lib/module/skia/web/JsiSkia.js +3 -1
  98. package/lib/module/skia/web/JsiSkia.js.map +1 -1
  99. package/lib/typescript/src/external/reanimated/useAnimatedImageValue.d.ts +2 -1
  100. package/lib/typescript/src/renderer/Offscreen.d.ts +2 -2
  101. package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +14 -0
  102. package/lib/typescript/src/skia/types/PlatformBuffer/PlatformBufferFactory.d.ts +12 -0
  103. package/lib/typescript/src/skia/types/PlatformBuffer/index.d.ts +1 -0
  104. package/lib/typescript/src/skia/types/Skia.d.ts +2 -0
  105. package/lib/typescript/src/skia/types/Surface/Surface.d.ts +8 -0
  106. package/lib/typescript/src/skia/types/index.d.ts +1 -0
  107. package/lib/typescript/src/skia/web/JsiSkImage.d.ts +1 -2
  108. package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +2 -2
  109. package/lib/typescript/src/skia/web/JsiSkPlatformBufferFactory.d.ts +8 -0
  110. package/lib/typescript/src/skia/web/JsiSkSurface.d.ts +3 -2
  111. package/lib/typescript/src/skia/web/JsiSkSurfaceFactory.d.ts +1 -1
  112. package/package.json +1 -1
  113. package/src/external/reanimated/textures.tsx +8 -2
  114. package/src/external/reanimated/useAnimatedImageValue.ts +12 -6
  115. package/src/renderer/Offscreen.tsx +3 -3
  116. package/src/skia/types/Image/ImageFactory.ts +15 -0
  117. package/src/skia/types/PlatformBuffer/PlatformBufferFactory.ts +14 -0
  118. package/src/skia/types/PlatformBuffer/index.ts +1 -0
  119. package/src/skia/types/Skia.ts +2 -1
  120. package/src/skia/types/Surface/Surface.ts +10 -0
  121. package/src/skia/types/index.ts +1 -0
  122. package/src/skia/web/JsiSkImage.ts +5 -22
  123. package/src/skia/web/JsiSkImageFactory.ts +13 -2
  124. package/src/skia/web/JsiSkPlatformBufferFactory.ts +22 -0
  125. package/src/skia/web/JsiSkSurface.ts +10 -9
  126. package/src/skia/web/JsiSkSurfaceFactory.ts +3 -19
  127. package/src/skia/web/JsiSkia.ts +2 -0
  128. package/cpp/skia/include/third_party/vulkan/LICENSE +0 -29
  129. package/cpp/skia/modules/skcms/README.chromium +0 -6
  130. package/cpp/skia/readme.txt +0 -1
@@ -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"
@@ -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
@@ -0,0 +1,13 @@
1
+ #pragma once
2
+
3
+ #include "include/core/SkColorType.h"
4
+
5
+ #if __ANDROID_API__ >= 26
6
+
7
+ namespace RNSkia {
8
+
9
+ uint32_t GetBufferFormatFromSkColorType(SkColorType bufferFormat);
10
+
11
+ } // namespace RNSkia
12
+
13
+ #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(const SkImageInfo &info,
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), info.width(),
29
- info.height(), &deleteImageProc, &updateImageProc, &deleteImageCtx, false,
30
- // GR_GL_RGBA8 0x8058
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
- kPremul_SkAlphaType, nullptr);
54
+ kOpaque_SkAlphaType, nullptr);
37
55
  return image;
38
56
  #else
39
- RNSkLogger::logToConsole(
40
- "Hardware buffer in only supported on Android API level 26 and above.");
41
- return nullptr;
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(const SkImageInfo &info,
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.uimanager.UIManagerModule;
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
- UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
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
@@ -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
@@ -177,7 +177,7 @@ public:
177
177
  if (!getObject()->readPixels(info, bfrPtr, bytesPerRow, srcX, srcY)) {
178
178
  return jsi::Value::null();
179
179
  }
180
- return std::move(dest);
180
+ return dest;
181
181
  }
182
182
 
183
183
  JSI_HOST_FUNCTION(makeNonTextureImage) {
@@ -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]);
@@ -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, MakeImage), )
83
+ JSI_EXPORT_FUNC(JsiSkImageFactory,
84
+ MakeImageFromPlatformBuffer),
85
+ JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImage))
72
86
 
73
87
  explicit JsiSkImageFactory(std::shared_ptr<RNSkPlatformContext> context)
74
88
  : JsiSkHostObject(std::move(context)) {}
@@ -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, getCanvas),
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 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
+ }
@@ -14,9 +14,18 @@ const createTexture = (texture, picture, size) => {
14
14
  texture.value = (0, _Offscreen.drawAsImageFromPicture)(picture, size);
15
15
  };
16
16
  const useTexture = (element, size) => {
17
+ const {
18
+ width,
19
+ height
20
+ } = size;
17
21
  const picture = (0, _react.useMemo)(() => {
18
- return (0, _Offscreen.drawAsPicture)(element);
19
- }, [element]);
22
+ return (0, _Offscreen.drawAsPicture)(element, {
23
+ x: 0,
24
+ y: 0,
25
+ width,
26
+ height
27
+ });
28
+ }, [element, width, height]);
20
29
  return usePictureAsTexture(picture, size);
21
30
  };
22
31
  exports.useTexture = useTexture;
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_Offscreen","_skia","_moduleWrapper","createTexture","texture","picture","size","value","drawAsImageFromPicture","useTexture","element","useMemo","drawAsPicture","usePictureAsTexture","exports","useTextureAsValue","console","warn","useTextureValueFromPicture","useSharedValue","useEffect","runOnUI","useImageAsTexture","source","image","useImage","width","height","recorder","Skia","PictureRecorder","canvas","beginRecording","x","y","drawImage","finishRecordingAsPicture"],"sources":["textures.tsx"],"sourcesContent":["import { useEffect, useMemo } from \"react\";\nimport type { ReactElement } from \"react\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport type {\n DataSourceParam,\n SkImage,\n SkPicture,\n SkSize,\n} from \"../../skia/types\";\nimport {\n drawAsImageFromPicture,\n drawAsPicture,\n} from \"../../renderer/Offscreen\";\nimport { Skia, useImage } from \"../../skia\";\n\nimport { runOnUI, useSharedValue } from \"./moduleWrapper\";\n\nconst createTexture = (\n texture: SharedValue<SkImage | null>,\n picture: SkPicture,\n size: SkSize\n) => {\n \"worklet\";\n texture.value = drawAsImageFromPicture(picture, size);\n};\n\nexport const useTexture = (element: ReactElement, size: SkSize) => {\n const picture = useMemo(() => {\n return drawAsPicture(element);\n }, [element]);\n return usePictureAsTexture(picture, size);\n};\n\nexport const useTextureAsValue = (element: ReactElement, size: SkSize) => {\n console.warn(\"useTextureAsValue has been renamed to use useTexture\");\n return useTexture(element, size);\n};\n\nexport const useTextureValueFromPicture = (\n picture: SkPicture | null,\n size: SkSize\n) => {\n console.warn(\n \"useTextureValueFromPicture has been renamed to use usePictureAsTexture\"\n );\n return usePictureAsTexture(picture, size);\n};\n\nexport const usePictureAsTexture = (\n picture: SkPicture | null,\n size: SkSize\n) => {\n const texture = useSharedValue<SkImage | null>(null);\n useEffect(() => {\n if (picture !== null) {\n runOnUI(createTexture)(texture, picture, size);\n }\n }, [texture, picture, size]);\n return texture;\n};\n\nexport const useImageAsTexture = (source: DataSourceParam) => {\n const image = useImage(source);\n const size = useMemo(() => {\n if (image) {\n return { width: image.width(), height: image.height() };\n }\n return { width: 0, height: 0 };\n }, [image]);\n const picture = useMemo(() => {\n if (image) {\n const recorder = Skia.PictureRecorder();\n const canvas = recorder.beginRecording({\n x: 0,\n y: 0,\n width: size.width,\n height: size.height,\n });\n canvas.drawImage(image, 0, 0);\n return recorder.finishRecordingAsPicture();\n } else {\n return null;\n }\n }, [size, image]);\n return usePictureAsTexture(picture, size);\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["_react","require","_Offscreen","_skia","_moduleWrapper","createTexture","texture","picture","size","value","drawAsImageFromPicture","useTexture","element","width","height","useMemo","drawAsPicture","x","y","usePictureAsTexture","exports","useTextureAsValue","console","warn","useTextureValueFromPicture","useSharedValue","useEffect","runOnUI","useImageAsTexture","source","image","useImage","recorder","Skia","PictureRecorder","canvas","beginRecording","drawImage","finishRecordingAsPicture"],"sources":["textures.tsx"],"sourcesContent":["import { useEffect, useMemo } from \"react\";\nimport type { ReactElement } from \"react\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport type {\n DataSourceParam,\n SkImage,\n SkPicture,\n SkSize,\n} from \"../../skia/types\";\nimport {\n drawAsImageFromPicture,\n drawAsPicture,\n} from \"../../renderer/Offscreen\";\nimport { Skia, useImage } from \"../../skia\";\n\nimport { runOnUI, useSharedValue } from \"./moduleWrapper\";\n\nconst createTexture = (\n texture: SharedValue<SkImage | null>,\n picture: SkPicture,\n size: SkSize\n) => {\n \"worklet\";\n texture.value = drawAsImageFromPicture(picture, size);\n};\n\nexport const useTexture = (element: ReactElement, size: SkSize) => {\n const { width, height } = size;\n const picture = useMemo(() => {\n return drawAsPicture(element, {\n x: 0,\n y: 0,\n width,\n height,\n });\n }, [element, width, height]);\n return usePictureAsTexture(picture, size);\n};\n\nexport const useTextureAsValue = (element: ReactElement, size: SkSize) => {\n console.warn(\"useTextureAsValue has been renamed to use useTexture\");\n return useTexture(element, size);\n};\n\nexport const useTextureValueFromPicture = (\n picture: SkPicture | null,\n size: SkSize\n) => {\n console.warn(\n \"useTextureValueFromPicture has been renamed to use usePictureAsTexture\"\n );\n return usePictureAsTexture(picture, size);\n};\n\nexport const usePictureAsTexture = (\n picture: SkPicture | null,\n size: SkSize\n) => {\n const texture = useSharedValue<SkImage | null>(null);\n useEffect(() => {\n if (picture !== null) {\n runOnUI(createTexture)(texture, picture, size);\n }\n }, [texture, picture, size]);\n return texture;\n};\n\nexport const useImageAsTexture = (source: DataSourceParam) => {\n const image = useImage(source);\n const size = useMemo(() => {\n if (image) {\n return { width: image.width(), height: image.height() };\n }\n return { width: 0, height: 0 };\n }, [image]);\n const picture = useMemo(() => {\n if (image) {\n const recorder = Skia.PictureRecorder();\n const canvas = recorder.beginRecording({\n x: 0,\n y: 0,\n width: size.width,\n height: size.height,\n });\n canvas.drawImage(image, 0, 0);\n return recorder.finishRecordingAsPicture();\n } else {\n return null;\n }\n }, [size, image]);\n return usePictureAsTexture(picture, size);\n};\n"],"mappings":"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"}
@@ -1,2 +1,3 @@
1
+ import { type SharedValue } from "react-native-reanimated";
1
2
  import type { DataSourceParam, SkImage } from "../../skia/types";
2
- export declare const useAnimatedImageValue: (source: DataSourceParam) => import("react-native-reanimated").SharedValue<SkImage | null>;
3
+ export declare const useAnimatedImageValue: (source: DataSourceParam, paused?: SharedValue<boolean>) => SharedValue<SkImage | null>;