@shopify/react-native-skia 2.0.1 → 2.0.3

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.
Files changed (92) hide show
  1. package/android/CMakeLists.txt +47 -21
  2. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +8 -5
  3. package/apple/MetalWindowContext.mm +4 -2
  4. package/apple/RNSkApplePlatformContext.h +7 -5
  5. package/apple/RNSkApplePlatformContext.mm +30 -29
  6. package/apple/SkiaCVPixelBufferUtils.mm +4 -8
  7. package/apple/SkiaManager.mm +0 -3
  8. package/cpp/api/JsiSkImageFactory.h +14 -1
  9. package/cpp/api/JsiSkSurface.h +7 -1
  10. package/cpp/api/recorder/DrawingCtx.h +19 -2
  11. package/cpp/api/recorder/Paint.h +1 -3
  12. package/cpp/api/recorder/RNRecorder.h +5 -13
  13. package/cpp/rnskia/DawnContext.h +11 -2
  14. package/cpp/rnskia/DawnUtils.h +97 -6
  15. package/cpp/rnskia/DawnWindowContext.h +18 -11
  16. package/cpp/rnskia/RNSkJsiViewApi.h +91 -71
  17. package/cpp/rnskia/RNSkManager.cpp +3 -18
  18. package/cpp/rnskia/RNSkManager.h +0 -6
  19. package/cpp/rnskia/RNSkPlatformContext.h +22 -5
  20. package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +2 -1
  21. package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
  22. package/lib/commonjs/skia/types/Surface/Surface.d.ts +1 -1
  23. package/lib/commonjs/skia/types/Surface/Surface.js.map +1 -1
  24. package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
  25. package/lib/commonjs/skia/web/JsiSkImageFactory.js +3 -0
  26. package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
  27. package/lib/commonjs/skia/web/JsiSkSurface.d.ts +2 -1
  28. package/lib/commonjs/skia/web/JsiSkSurface.js +4 -1
  29. package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
  30. package/lib/commonjs/sksg/HostConfig.js +1 -1
  31. package/lib/commonjs/sksg/HostConfig.js.map +1 -1
  32. package/lib/commonjs/sksg/Recorder/DrawingContext.d.ts +2 -0
  33. package/lib/commonjs/sksg/Recorder/DrawingContext.js +14 -2
  34. package/lib/commonjs/sksg/Recorder/DrawingContext.js.map +1 -1
  35. package/lib/commonjs/sksg/Recorder/Player.js +6 -2
  36. package/lib/commonjs/sksg/Recorder/Player.js.map +1 -1
  37. package/lib/commonjs/sksg/Recorder/commands/Paint.d.ts +3 -2
  38. package/lib/commonjs/sksg/Recorder/commands/Paint.js +5 -4
  39. package/lib/commonjs/sksg/Recorder/commands/Paint.js.map +1 -1
  40. package/lib/commonjs/views/SkiaBaseWebView.js +4 -0
  41. package/lib/commonjs/views/SkiaBaseWebView.js.map +1 -1
  42. package/lib/module/skia/types/Image/ImageFactory.d.ts +2 -1
  43. package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
  44. package/lib/module/skia/types/Surface/Surface.d.ts +1 -1
  45. package/lib/module/skia/types/Surface/Surface.js.map +1 -1
  46. package/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
  47. package/lib/module/skia/web/JsiSkImageFactory.js +3 -0
  48. package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
  49. package/lib/module/skia/web/JsiSkSurface.d.ts +2 -1
  50. package/lib/module/skia/web/JsiSkSurface.js +4 -1
  51. package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
  52. package/lib/module/sksg/HostConfig.js +1 -1
  53. package/lib/module/sksg/HostConfig.js.map +1 -1
  54. package/lib/module/sksg/Recorder/DrawingContext.d.ts +2 -0
  55. package/lib/module/sksg/Recorder/DrawingContext.js +14 -2
  56. package/lib/module/sksg/Recorder/DrawingContext.js.map +1 -1
  57. package/lib/module/sksg/Recorder/Player.js +6 -2
  58. package/lib/module/sksg/Recorder/Player.js.map +1 -1
  59. package/lib/module/sksg/Recorder/commands/Paint.d.ts +3 -2
  60. package/lib/module/sksg/Recorder/commands/Paint.js +5 -4
  61. package/lib/module/sksg/Recorder/commands/Paint.js.map +1 -1
  62. package/lib/module/views/SkiaBaseWebView.js +4 -0
  63. package/lib/module/views/SkiaBaseWebView.js.map +1 -1
  64. package/lib/typescript/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
  65. package/lib/typescript/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -1
  66. package/lib/typescript/lib/commonjs/sksg/HostConfig.d.ts +1 -1
  67. package/lib/typescript/lib/commonjs/sksg/Recorder/DrawingContext.d.ts +2 -0
  68. package/lib/typescript/lib/commonjs/sksg/Recorder/commands/Paint.d.ts +1 -1
  69. package/lib/typescript/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
  70. package/lib/typescript/lib/module/skia/web/JsiSkSurface.d.ts +1 -1
  71. package/lib/typescript/lib/module/sksg/HostConfig.d.ts +1 -1
  72. package/lib/typescript/lib/module/sksg/Recorder/DrawingContext.d.ts +2 -0
  73. package/lib/typescript/lib/module/sksg/Recorder/commands/Paint.d.ts +1 -1
  74. package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +2 -1
  75. package/lib/typescript/src/skia/types/Surface/Surface.d.ts +1 -1
  76. package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +1 -0
  77. package/lib/typescript/src/skia/web/JsiSkSurface.d.ts +2 -1
  78. package/lib/typescript/src/sksg/Recorder/DrawingContext.d.ts +2 -0
  79. package/lib/typescript/src/sksg/Recorder/commands/Paint.d.ts +3 -2
  80. package/package.json +1 -1
  81. package/react-native-skia.podspec +43 -12
  82. package/src/renderer/__tests__/e2e/DataEncoding.spec.tsx +6 -2
  83. package/src/renderer/__tests__/e2e/Paint.spec.tsx +44 -1
  84. package/src/skia/types/Image/ImageFactory.ts +3 -1
  85. package/src/skia/types/Surface/Surface.ts +1 -1
  86. package/src/skia/web/JsiSkImageFactory.ts +4 -0
  87. package/src/skia/web/JsiSkSurface.ts +4 -1
  88. package/src/sksg/HostConfig.ts +2 -4
  89. package/src/sksg/Recorder/DrawingContext.ts +15 -1
  90. package/src/sksg/Recorder/Player.ts +6 -2
  91. package/src/sksg/Recorder/commands/Paint.ts +6 -5
  92. package/src/views/SkiaBaseWebView.tsx +4 -0
@@ -3,7 +3,53 @@ cmake_minimum_required(VERSION 3.4.1)
3
3
 
4
4
  set (CMAKE_VERBOSE_MAKEFILE ON)
5
5
  set (CMAKE_CXX_STANDARD 17)
6
- set(SK_GRAPHITE OFF)
6
+
7
+ # Import prebuilt SKIA libraries path
8
+ set (SKIA_LIBS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../libs/android/${ANDROID_ABI}")
9
+
10
+ # Import libskia first so we can check for symbols
11
+ add_library(skia STATIC IMPORTED)
12
+ set_property(TARGET skia PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libskia.a")
13
+
14
+ # Check if Graphite symbols are available in libskia using nm/objdump
15
+ set(SK_GRAPHITE_AVAILABLE OFF)
16
+
17
+ if(EXISTS "${SKIA_LIBS_PATH}/libskia.a")
18
+ # Look for specific Dawn function symbols that indicate Graphite support
19
+ execute_process(
20
+ COMMAND nm "${SKIA_LIBS_PATH}/libskia.a"
21
+ COMMAND grep "dawn::\\|wgpu\\|_ZN4dawn\\|DawnDevice\\|dawn_native"
22
+ OUTPUT_VARIABLE NM_OUTPUT
23
+ ERROR_QUIET
24
+ RESULT_VARIABLE NM_RESULT
25
+ )
26
+
27
+ if(NM_RESULT EQUAL 0 AND NOT "${NM_OUTPUT}" STREQUAL "")
28
+ set(SK_GRAPHITE_AVAILABLE ON)
29
+ else()
30
+ # Fallback to objdump if nm doesn't work
31
+ execute_process(
32
+ COMMAND objdump -t "${SKIA_LIBS_PATH}/libskia.a"
33
+ COMMAND grep "dawn::\\|wgpu\\|_ZN4dawn\\|DawnDevice\\|dawn_native"
34
+ OUTPUT_VARIABLE OBJDUMP_OUTPUT
35
+ ERROR_QUIET
36
+ RESULT_VARIABLE OBJDUMP_RESULT
37
+ )
38
+
39
+ if(OBJDUMP_RESULT EQUAL 0 AND NOT "${OBJDUMP_OUTPUT}" STREQUAL "")
40
+ set(SK_GRAPHITE_AVAILABLE ON)
41
+ endif()
42
+ endif()
43
+ endif()
44
+
45
+ if(SK_GRAPHITE_AVAILABLE)
46
+ set(SK_GRAPHITE ON)
47
+ message("-- SK_GRAPHITE: ON (Graphite symbols found in libskia)")
48
+ else()
49
+ set(SK_GRAPHITE OFF)
50
+ message("-- SK_GRAPHITE: OFF (Graphite symbols not found in libskia)")
51
+ endif()
52
+
7
53
  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSK_BUILD_FOR_ANDROID -DSK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API -DFOLLY_NO_CONFIG=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -DFOLLY_HAVE_MEMRCHR=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_MOBILE=1 -DON_ANDROID -DONANDROID")
8
54
  set (PACKAGE_NAME "rnskia")
9
55
  set (SKIA_LIB "skia")
@@ -31,26 +77,12 @@ message("-- LIBRN : " ${LIBRN_DIR})
31
77
 
32
78
  link_directories(../libs/android/${ANDROID_ABI}/)
33
79
 
34
- # Import prebuilt SKIA libraries
35
- set (SKIA_LIBS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../libs/android/${ANDROID_ABI}")
36
-
37
80
  if(SK_GRAPHITE)
38
81
  add_definitions(-DSK_GRAPHITE)
39
- set(DAWN_NATIVE_LIB "libdawn_native_static")
40
- set(DAWN_PLATFORM_LIB "libdawn_platform_static")
41
- set(DAWN_PROC_LIB "libdawn_proc_static")
42
82
  set(BACKEND_SOURCES
43
83
  #TODO: is this source needed to be added?
44
84
  "${PROJECT_SOURCE_DIR}/../cpp/rnskia/DawnWindowContext.cpp"
45
85
  )
46
- add_library(libdawn_native_static STATIC IMPORTED)
47
- set_property(TARGET libdawn_native_static PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libdawn_native_static.a")
48
-
49
- add_library(libdawn_platform_static STATIC IMPORTED)
50
- set_property(TARGET libdawn_platform_static PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libdawn_platform_static.a")
51
-
52
- add_library(libdawn_proc_static STATIC IMPORTED)
53
- set_property(TARGET libdawn_proc_static PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libdawn_proc_static.a")
54
86
  else()
55
87
  add_definitions(-DSK_GL -DSK_GANESH)
56
88
  set(BACKEND_SOURCES
@@ -122,9 +154,6 @@ target_include_directories(
122
154
  ${libfbjni_include_DIRS}
123
155
  )
124
156
 
125
- add_library(skia STATIC IMPORTED)
126
- set_property(TARGET skia PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libskia.a")
127
-
128
157
  add_library(svg STATIC IMPORTED)
129
158
  set_property(TARGET svg PROPERTY IMPORTED_LOCATION "${SKIA_LIBS_PATH}/libsvg.a")
130
159
 
@@ -298,9 +327,6 @@ endif()
298
327
  if(SK_GRAPHITE)
299
328
  target_link_libraries(${PACKAGE_NAME}
300
329
  ${COMMON_LIBS}
301
- ${DAWN_NATIVE_LIB}
302
- ${DAWN_PLATFORM_LIB}
303
- ${DAWN_PROC_LIB}
304
330
  )
305
331
  else()
306
332
  target_link_libraries(${PACKAGE_NAME}
@@ -75,6 +75,7 @@ public:
75
75
  #endif
76
76
  }
77
77
 
78
+ #if !defined(SK_GRAPHITE)
78
79
  sk_sp<SkImage> makeImageFromNativeTexture(const TextureInfo &texInfo,
79
80
  int width, int height,
80
81
  bool mipMapped) override {
@@ -99,6 +100,7 @@ public:
99
100
  kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType,
100
101
  nullptr);
101
102
  }
103
+ #endif
102
104
 
103
105
  std::shared_ptr<RNSkVideo> createVideo(const std::string &url) override {
104
106
  auto jniVideo = _jniPlatformContext->createVideo(url);
@@ -171,6 +173,11 @@ public:
171
173
  #endif
172
174
  }
173
175
 
176
+ #if !defined(SK_GRAPHITE)
177
+ GrDirectContext *getDirectContext() override {
178
+ return OpenGLContext::getInstance().getDirectContext();
179
+ }
180
+
174
181
  const TextureInfo getTexture(sk_sp<SkImage> image) override {
175
182
  GrBackendTexture texture;
176
183
  if (!SkImages::GetBackendTextureFromImage(image, &texture, true)) {
@@ -186,6 +193,7 @@ public:
186
193
  }
187
194
 
188
195
  static TextureInfo getTextureInfo(const GrBackendTexture &texture) {
196
+
189
197
  if (!texture.isValid()) {
190
198
  throw std::runtime_error("invalid backend texture");
191
199
  }
@@ -204,11 +212,6 @@ public:
204
212
  texInfo.glTarget = textureInfo.fTarget;
205
213
  return texInfo;
206
214
  }
207
-
208
- #if !defined(SK_GRAPHITE)
209
- GrDirectContext *getDirectContext() override {
210
- return OpenGLContext::getInstance().getDirectContext();
211
- }
212
215
  #endif
213
216
 
214
217
  sk_sp<SkFontMgr> createFontMgr() override {
@@ -25,10 +25,12 @@ MetalWindowContext::MetalWindowContext(GrDirectContext *directContext,
25
25
  _layer.drawableSize = CGSizeMake(width, height);
26
26
  BOOL supportsWideColor = NO;
27
27
  if (@available(iOS 10.0, *)) {
28
- supportsWideColor = [UIScreen mainScreen].traitCollection.displayGamut == UIDisplayGamutP3;
28
+ supportsWideColor =
29
+ [UIScreen mainScreen].traitCollection.displayGamut == UIDisplayGamutP3;
29
30
  }
30
31
  if (supportsWideColor) {
31
- CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3);
32
+ CGColorSpaceRef colorSpace =
33
+ CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3);
32
34
  _layer.colorspace = colorSpace;
33
35
  CGColorSpaceRelease(colorSpace);
34
36
  }
@@ -43,15 +43,19 @@ public:
43
43
 
44
44
  sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) override;
45
45
 
46
+ #if !defined(SK_GRAPHITE)
47
+ GrDirectContext *getDirectContext() override;
48
+
46
49
  sk_sp<SkImage> makeImageFromNativeTexture(const TextureInfo &textureInfo,
47
50
  int width, int height,
48
51
  bool mipMapped) override;
49
52
 
50
- uint64_t makeNativeBuffer(sk_sp<SkImage> image) override;
51
-
52
53
  const TextureInfo getTexture(sk_sp<SkSurface> image) override;
53
54
 
54
55
  const TextureInfo getTexture(sk_sp<SkImage> image) override;
56
+ #endif
57
+
58
+ uint64_t makeNativeBuffer(sk_sp<SkImage> image) override;
55
59
 
56
60
  void releaseNativeBuffer(uint64_t pointer) override;
57
61
 
@@ -66,9 +70,7 @@ public:
66
70
 
67
71
  void raiseError(const std::exception &err) override;
68
72
  sk_sp<SkSurface> makeOffscreenSurface(int width, int height) override;
69
- #if !defined(SK_GRAPHITE)
70
- GrDirectContext *getDirectContext() override;
71
- #endif
73
+
72
74
  sk_sp<SkFontMgr> createFontMgr() override;
73
75
 
74
76
  private:
@@ -156,9 +156,14 @@ uint64_t RNSkApplePlatformContext::makeNativeBuffer(sk_sp<SkImage> image) {
156
156
  return reinterpret_cast<uint64_t>(pixelBuffer);
157
157
  }
158
158
 
159
+ #if !defined(SK_GRAPHITE)
160
+ GrDirectContext *RNSkApplePlatformContext::getDirectContext() {
161
+ return MetalContext::getInstance().getDirectContext();
162
+ }
163
+
159
164
  const TextureInfo RNSkApplePlatformContext::getTexture(sk_sp<SkImage> image) {
160
- GrBackendTexture texture;
161
165
  TextureInfo result;
166
+ GrBackendTexture texture;
162
167
  if (!SkImages::GetBackendTextureFromImage(image, &texture, true)) {
163
168
  throw std::runtime_error("Couldn't get backend texture");
164
169
  }
@@ -175,9 +180,9 @@ const TextureInfo RNSkApplePlatformContext::getTexture(sk_sp<SkImage> image) {
175
180
 
176
181
  const TextureInfo
177
182
  RNSkApplePlatformContext::getTexture(sk_sp<SkSurface> surface) {
183
+ TextureInfo result;
178
184
  GrBackendTexture texture = SkSurfaces::GetBackendTexture(
179
185
  surface.get(), SkSurfaces::BackendHandleAccess::kFlushRead);
180
- TextureInfo result;
181
186
  if (!texture.isValid()) {
182
187
  throw std::runtime_error("Invalid backend texture");
183
188
  }
@@ -189,6 +194,29 @@ RNSkApplePlatformContext::getTexture(sk_sp<SkSurface> surface) {
189
194
  return result;
190
195
  }
191
196
 
197
+ sk_sp<SkImage> RNSkApplePlatformContext::makeImageFromNativeTexture(
198
+ const TextureInfo &texInfo, int width, int height, bool mipMapped) {
199
+ id<MTLTexture> mtlTexture = (__bridge id<MTLTexture>)(texInfo.mtlTexture);
200
+
201
+ SkColorType colorType = mtlPixelFormatToSkColorType(mtlTexture.pixelFormat);
202
+ if (colorType == SkColorType::kUnknown_SkColorType) {
203
+ throw std::runtime_error("Unsupported pixelFormat");
204
+ }
205
+
206
+ GrMtlTextureInfo textureInfo;
207
+ textureInfo.fTexture.retain((__bridge const void *)mtlTexture);
208
+
209
+ GrBackendTexture texture = GrBackendTextures::MakeMtl(
210
+ width, height, mipMapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo,
211
+ textureInfo);
212
+
213
+ return SkImages::BorrowTextureFrom(getDirectContext(), texture,
214
+ kTopLeft_GrSurfaceOrigin, colorType,
215
+ kPremul_SkAlphaType, nullptr);
216
+ return nullptr;
217
+ }
218
+ #endif
219
+
192
220
  std::shared_ptr<RNSkVideo>
193
221
  RNSkApplePlatformContext::createVideo(const std::string &url) {
194
222
  return std::make_shared<RNSkAppleVideo>(url, this);
@@ -227,27 +255,6 @@ RNSkApplePlatformContext::makeImageFromNativeBuffer(void *buffer) {
227
255
  #endif
228
256
  }
229
257
 
230
- sk_sp<SkImage> RNSkApplePlatformContext::makeImageFromNativeTexture(
231
- const TextureInfo &texInfo, int width, int height, bool mipMapped) {
232
- id<MTLTexture> mtlTexture = (__bridge id<MTLTexture>)(texInfo.mtlTexture);
233
-
234
- SkColorType colorType = mtlPixelFormatToSkColorType(mtlTexture.pixelFormat);
235
- if (colorType == SkColorType::kUnknown_SkColorType) {
236
- throw std::runtime_error("Unsupported pixelFormat");
237
- }
238
-
239
- GrMtlTextureInfo textureInfo;
240
- textureInfo.fTexture.retain((__bridge const void *)mtlTexture);
241
-
242
- GrBackendTexture texture = GrBackendTextures::MakeMtl(
243
- width, height, mipMapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo,
244
- textureInfo);
245
-
246
- return SkImages::BorrowTextureFrom(getDirectContext(), texture,
247
- kTopLeft_GrSurfaceOrigin, colorType,
248
- kPremul_SkAlphaType, nullptr);
249
- }
250
-
251
258
  SkColorType RNSkApplePlatformContext::mtlPixelFormatToSkColorType(
252
259
  MTLPixelFormat pixelFormat) {
253
260
  switch (pixelFormat) {
@@ -280,12 +287,6 @@ SkColorType RNSkApplePlatformContext::mtlPixelFormatToSkColorType(
280
287
  }
281
288
  }
282
289
 
283
- #if !defined(SK_GRAPHITE)
284
- GrDirectContext *RNSkApplePlatformContext::getDirectContext() {
285
- return MetalContext::getInstance().getDirectContext();
286
- }
287
- #endif
288
-
289
290
  sk_sp<SkFontMgr> RNSkApplePlatformContext::createFontMgr() {
290
291
  return SkFontMgr_New_CoreText(nullptr);
291
292
  }
@@ -30,16 +30,12 @@
30
30
  #include <TargetConditionals.h>
31
31
  #if TARGET_RT_BIG_ENDIAN
32
32
  #define FourCC2Str(fourcc) \
33
- (const char[]) { \
34
- *((char *)&fourcc), *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 2), \
35
- *(((char *)&fourcc) + 3), 0 \
36
- }
33
+ (const char[]){*((char *)&fourcc), *(((char *)&fourcc) + 1), \
34
+ *(((char *)&fourcc) + 2), *(((char *)&fourcc) + 3), 0}
37
35
  #else
38
36
  #define FourCC2Str(fourcc) \
39
- (const char[]) { \
40
- *(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
41
- *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0 \
42
- }
37
+ (const char[]){*(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
38
+ *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0}
43
39
  #endif
44
40
 
45
41
  // pragma MARK: TextureHolder
@@ -20,9 +20,6 @@ static __weak SkiaManager *sharedInstance = nil;
20
20
  }
21
21
 
22
22
  - (void)invalidate {
23
- if (_skManager != nullptr) {
24
- _skManager->invalidate();
25
- }
26
23
  _skManager = nullptr;
27
24
  }
28
25
 
@@ -17,6 +17,11 @@ namespace jsi = facebook::jsi;
17
17
 
18
18
  class JsiSkImageFactory : public JsiSkHostObject {
19
19
  public:
20
+ JSI_HOST_FUNCTION(MakeNull) {
21
+ return jsi::Object::createFromHostObject(
22
+ runtime, std::make_shared<JsiSkImage>(getContext(), nullptr));
23
+ }
24
+
20
25
  JSI_HOST_FUNCTION(MakeImageFromEncoded) {
21
26
  auto data = JsiSkData::fromValue(runtime, arguments[0]);
22
27
  auto image = SkImages::DeferredFromEncodedData(data);
@@ -86,6 +91,13 @@ public:
86
91
  if (image == nullptr) {
87
92
  throw std::runtime_error("Failed to convert native texture to SkImage!");
88
93
  }
94
+ if (count > 4 && arguments[4].isObject() &&
95
+ arguments[4].asObject(runtime).isHostObject(runtime)) {
96
+ auto jsiImage =
97
+ arguments[4].asObject(runtime).asHostObject<JsiSkImage>(runtime);
98
+ jsiImage->setObject(image);
99
+ return jsi::Value(runtime, arguments[4]);
100
+ }
89
101
  return jsi::Object::createFromHostObject(
90
102
  runtime, std::make_shared<JsiSkImage>(getContext(), std::move(image)));
91
103
  }
@@ -96,7 +108,8 @@ public:
96
108
  MakeImageFromNativeBuffer),
97
109
  JSI_EXPORT_FUNC(JsiSkImageFactory,
98
110
  MakeImageFromNativeTextureUnstable),
99
- JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImage))
111
+ JSI_EXPORT_FUNC(JsiSkImageFactory, MakeImage),
112
+ JSI_EXPORT_FUNC(JsiSkImageFactory, MakeNull))
100
113
 
101
114
  explicit JsiSkImageFactory(std::shared_ptr<RNSkPlatformContext> context)
102
115
  : JsiSkHostObject(std::move(context)) {}
@@ -64,7 +64,7 @@ public:
64
64
  JSI_HOST_FUNCTION(makeImageSnapshot) {
65
65
  auto surface = getObject();
66
66
  sk_sp<SkImage> image;
67
- if (count == 1) {
67
+ if (count > 0 && arguments[0].isObject()) {
68
68
  auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
69
69
  image = surface->makeImageSnapshot(SkIRect::MakeXYWH(
70
70
  rect->x(), rect->y(), rect->width(), rect->height()));
@@ -75,6 +75,12 @@ public:
75
75
  auto recording = surface->recorder()->snap();
76
76
  DawnContext::getInstance().submitRecording(recording.get());
77
77
  #endif
78
+ if (count > 1 && arguments[1].isObject()) {
79
+ auto jsiImage =
80
+ arguments[1].asObject(runtime).asHostObject<JsiSkImage>(runtime);
81
+ jsiImage->setObject(image);
82
+ return jsi::Value(runtime, arguments[1]);
83
+ }
78
84
  return jsi::Object::createFromHostObject(
79
85
  runtime, std::make_shared<JsiSkImage>(getContext(), std::move(image)));
80
86
  }
@@ -56,11 +56,24 @@ public:
56
56
  SkPaint paint;
57
57
  paint.setAntiAlias(true);
58
58
  paints.push_back(paint);
59
+ opacities.push_back(1.0f);
59
60
  }
60
61
 
61
- void pushPaint(SkPaint &paint) { paints.push_back(paint); }
62
+ float getOpacity() const { return opacities.back(); }
63
+
64
+ void setOpacity(float newOpacity) {
65
+ opacities.back() = std::clamp(newOpacity, 0.0f, 1.0f);
66
+ }
67
+
68
+ void pushPaint(SkPaint &paint) {
69
+ paints.push_back(paint);
70
+ opacities.push_back(opacities.back());
71
+ }
62
72
 
63
- void savePaint() { paints.push_back(SkPaint(getPaint())); }
73
+ void savePaint() {
74
+ paints.push_back(SkPaint(getPaint()));
75
+ opacities.push_back(opacities.back());
76
+ }
64
77
 
65
78
  void saveBackdropFilter() {
66
79
  // Initialize image filter as nullptr
@@ -96,6 +109,7 @@ public:
96
109
  }
97
110
  auto paint = paints.back();
98
111
  paints.pop_back();
112
+ opacities.pop_back();
99
113
  return paint;
100
114
  }
101
115
 
@@ -182,6 +196,9 @@ public:
182
196
  std::vector<sk_sp<SkImageFilter>> imageFilters;
183
197
  std::vector<sk_sp<SkPathEffect>> pathEffects;
184
198
  std::vector<SkPaint> paintDeclarations;
199
+
200
+ private:
201
+ std::vector<float> opacities;
185
202
  };
186
203
 
187
204
  } // namespace RNSkia
@@ -153,13 +153,11 @@ public:
153
153
  ctx->savePaint();
154
154
  auto &paint = ctx->getPaint();
155
155
  if (props.opacity.has_value()) {
156
- paint.setAlphaf(paint.getAlphaf() * props.opacity.value());
156
+ ctx->setOpacity(ctx->getOpacity() * props.opacity.value());
157
157
  }
158
158
  if (props.color.has_value()) {
159
- auto currentOpacity = paint.getAlphaf();
160
159
  paint.setShader(nullptr);
161
160
  paint.setColor(props.color.value());
162
- paint.setAlphaf(currentOpacity * paint.getAlphaf());
163
161
  }
164
162
  if (props.blendMode.has_value()) {
165
163
  paint.setBlendMode(props.blendMode.value());
@@ -294,7 +294,7 @@ public:
294
294
  void play(DrawingCtx *ctx) {
295
295
  for (const auto &cmd : commands) {
296
296
  switch (cmd->type) {
297
-
297
+
298
298
  case Group: {
299
299
  // Do nothing here for now
300
300
  break;
@@ -483,17 +483,6 @@ public:
483
483
  break;
484
484
  }
485
485
 
486
- case CommandType::DrawPaint: {
487
- ctx->canvas->drawPaint(ctx->getPaint());
488
- break;
489
- }
490
-
491
- case CommandType::DrawText: {
492
- auto *textCmd = static_cast<TextCmd *>(cmd.get());
493
- textCmd->draw(ctx);
494
- break;
495
- }
496
-
497
486
  case CommandType::RestorePaint: {
498
487
  ctx->restorePaint();
499
488
  break;
@@ -512,7 +501,10 @@ public:
512
501
  default: {
513
502
  // Handle all drawing commands
514
503
  auto currentPaints = ctx->paintDeclarations;
515
- currentPaints.push_back(ctx->getPaint()); // Add current paint
504
+ // apply alpha to the current paint.
505
+ SkPaint paint(ctx->getPaint());
506
+ paint.setAlphaf(paint.getAlphaf() * ctx->getOpacity());
507
+ currentPaints.push_back(paint);
516
508
  ctx->paintDeclarations.clear();
517
509
 
518
510
  for (auto &paint : currentPaints) {
@@ -204,7 +204,7 @@ private:
204
204
  DawnProcTable backendProcs = dawn::native::GetProcs();
205
205
  dawnProcSetProcs(&backendProcs);
206
206
  WGPUInstanceDescriptor desc{};
207
- desc.features.timedWaitAnyEnable = true;
207
+ desc.capabilities.timedWaitAnyEnable = true;
208
208
  instance = std::make_unique<dawn::native::Instance>(&desc);
209
209
 
210
210
  backendContext = DawnUtils::createDawnBackendContext(instance.get());
@@ -221,7 +221,16 @@ private:
221
221
  }
222
222
  }
223
223
 
224
- void tick() { backendContext.fTick(backendContext.fInstance); }
224
+ ~DawnContext() {
225
+ backendContext.fDevice = nullptr;
226
+ tick();
227
+ }
228
+
229
+ void tick() {
230
+ if (backendContext.fTick) {
231
+ backendContext.fTick(backendContext.fInstance);
232
+ }
233
+ }
225
234
 
226
235
  skgpu::graphite::Recorder *getRecorder() {
227
236
  static thread_local skgpu::graphite::RecorderOptions recorderOptions;
@@ -5,6 +5,7 @@
5
5
  #include "dawn/dawn_proc.h"
6
6
  #include "dawn/native/DawnNative.h"
7
7
 
8
+ #include "RNSkLog.h"
8
9
  #include "include/core/SkColorType.h"
9
10
  #include "include/gpu/graphite/dawn/DawnBackendContext.h"
10
11
 
@@ -25,6 +26,10 @@ createDawnBackendContext(dawn::native::Instance *instance) {
25
26
 
26
27
  auto useTintIR = false;
27
28
  static constexpr const char *kToggles[] = {
29
+ #if !defined(SK_DEBUG)
30
+ "skip_validation",
31
+ #endif
32
+ "disable_lazy_clear_for_mapped_at_creation_buffer",
28
33
  "allow_unsafe_apis",
29
34
  "use_user_defined_labels_in_backend",
30
35
  "disable_robustness",
@@ -34,6 +39,8 @@ createDawnBackendContext(dawn::native::Instance *instance) {
34
39
  togglesDesc.enabledToggleCount = std::size(kToggles) - (useTintIR ? 0 : 1);
35
40
  togglesDesc.enabledToggles = kToggles;
36
41
 
42
+ dawn::native::Adapter matchedAdaptor;
43
+
37
44
  wgpu::RequestAdapterOptions options;
38
45
  #ifdef __APPLE__
39
46
  constexpr auto kDefaultBackendType = wgpu::BackendType::Metal;
@@ -41,6 +48,7 @@ createDawnBackendContext(dawn::native::Instance *instance) {
41
48
  constexpr auto kDefaultBackendType = wgpu::BackendType::Vulkan;
42
49
  #endif
43
50
  options.backendType = kDefaultBackendType;
51
+ options.featureLevel = wgpu::FeatureLevel::Core;
44
52
  options.nextInChain = &togglesDesc;
45
53
 
46
54
  std::vector<dawn::native::Adapter> adapters =
@@ -49,7 +57,78 @@ createDawnBackendContext(dawn::native::Instance *instance) {
49
57
  throw std::runtime_error("No matching adapter found");
50
58
  }
51
59
 
52
- wgpu::Adapter adapter = adapters[0].Get();
60
+ // Sort adapters by adapterType(DiscreteGPU, IntegratedGPU, CPU) and
61
+ // backendType(Metal, Vulkan, OpenGL, OpenGLES, WebGPU).
62
+ std::sort(adapters.begin(), adapters.end(),
63
+ [](dawn::native::Adapter a, dawn::native::Adapter b) {
64
+ wgpu::Adapter wgpuA = a.Get();
65
+ wgpu::Adapter wgpuB = b.Get();
66
+ wgpu::AdapterInfo infoA;
67
+ wgpu::AdapterInfo infoB;
68
+ wgpuA.GetInfo(&infoA);
69
+ wgpuB.GetInfo(&infoB);
70
+ return std::tuple(infoA.adapterType, infoA.backendType) <
71
+ std::tuple(infoB.adapterType, infoB.backendType);
72
+ });
73
+
74
+ for (const auto &adapter : adapters) {
75
+ wgpu::Adapter wgpuAdapter = adapter.Get();
76
+ wgpu::AdapterInfo props;
77
+ wgpuAdapter.GetInfo(&props);
78
+ if (kDefaultBackendType == props.backendType) {
79
+ matchedAdaptor = adapter;
80
+ break;
81
+ }
82
+ }
83
+
84
+ if (!matchedAdaptor) {
85
+ throw std::runtime_error("No matching adapter found");
86
+ }
87
+
88
+ wgpu::Adapter adapter = matchedAdaptor.Get();
89
+
90
+ // Log selected adapter info
91
+ wgpu::AdapterInfo adapterInfo;
92
+ adapter.GetInfo(&adapterInfo);
93
+ std::string deviceName =
94
+ adapterInfo.device.data
95
+ ? std::string(adapterInfo.device.data, adapterInfo.device.length)
96
+ : "Unknown";
97
+ std::string description = adapterInfo.description.data
98
+ ? std::string(adapterInfo.description.data,
99
+ adapterInfo.description.length)
100
+ : "Unknown";
101
+
102
+ std::string backendName;
103
+ switch (adapterInfo.backendType) {
104
+ case wgpu::BackendType::Metal:
105
+ backendName = "Metal";
106
+ break;
107
+ case wgpu::BackendType::Vulkan:
108
+ backendName = "Vulkan";
109
+ break;
110
+ case wgpu::BackendType::OpenGL:
111
+ backendName = "OpenGL";
112
+ break;
113
+ case wgpu::BackendType::OpenGLES:
114
+ backendName = "OpenGLES";
115
+ break;
116
+ case wgpu::BackendType::WebGPU:
117
+ backendName = "WebGPU";
118
+ break;
119
+ case wgpu::BackendType::Null:
120
+ backendName = "Null";
121
+ break;
122
+ default:
123
+ backendName = "Undefined (" +
124
+ std::to_string(static_cast<int>(adapterInfo.backendType)) +
125
+ ")";
126
+ break;
127
+ }
128
+
129
+ RNSkia::RNSkLogger::logToConsole(
130
+ "Selected Dawn adapter - Backend: %s, Device: %s, Description: %s",
131
+ backendName.c_str(), deviceName.c_str(), description.c_str());
53
132
 
54
133
  std::vector<wgpu::FeatureName> features;
55
134
  if (adapter.HasFeature(wgpu::FeatureName::MSAARenderToSingleSampled)) {
@@ -85,6 +164,15 @@ createDawnBackendContext(dawn::native::Instance *instance) {
85
164
  if (adapter.HasFeature(wgpu::FeatureName::DawnPartialLoadResolveTexture)) {
86
165
  features.push_back(wgpu::FeatureName::DawnPartialLoadResolveTexture);
87
166
  }
167
+ if (adapter.HasFeature(wgpu::FeatureName::TimestampQuery)) {
168
+ features.push_back(wgpu::FeatureName::TimestampQuery);
169
+ }
170
+ if (adapter.HasFeature(wgpu::FeatureName::DawnTexelCopyBufferRowAlignment)) {
171
+ features.push_back(wgpu::FeatureName::DawnTexelCopyBufferRowAlignment);
172
+ }
173
+ if (adapter.HasFeature(wgpu::FeatureName::ImplicitDeviceSynchronization)) {
174
+ features.push_back(wgpu::FeatureName::ImplicitDeviceSynchronization);
175
+ }
88
176
  #ifdef __APPLE__
89
177
  if (adapter.HasFeature(wgpu::FeatureName::SharedTextureMemoryIOSurface)) {
90
178
  features.push_back(wgpu::FeatureName::SharedTextureMemoryIOSurface);
@@ -103,17 +191,20 @@ createDawnBackendContext(dawn::native::Instance *instance) {
103
191
  desc.SetDeviceLostCallback(
104
192
  wgpu::CallbackMode::AllowSpontaneous,
105
193
  [](const wgpu::Device &, wgpu::DeviceLostReason reason,
106
- const char *message) {
194
+ wgpu::StringView message) {
107
195
  if (reason != wgpu::DeviceLostReason::Destroyed) {
108
- SK_ABORT("Device lost: %s\n", message);
196
+ SK_ABORT("Device lost: %.*s\n", static_cast<int>(message.length),
197
+ message.data);
109
198
  }
110
199
  });
111
200
  desc.SetUncapturedErrorCallback(
112
- [](const wgpu::Device &, wgpu::ErrorType, const char *message) {
113
- SkDebugf("Device error: %s\n", message);
201
+ [](const wgpu::Device &, wgpu::ErrorType, wgpu::StringView message) {
202
+ SkDebugf("Device error: %.*s\n", static_cast<int>(message.length),
203
+ message.data);
114
204
  });
115
205
 
116
- wgpu::Device device = adapter.CreateDevice(&desc);
206
+ wgpu::Device device =
207
+ wgpu::Device::Acquire(matchedAdaptor.CreateDevice(&desc));
117
208
  SkASSERT(device);
118
209
 
119
210
  skgpu::graphite::DawnBackendContext backendContext;