@shopify/react-native-skia 2.3.9 → 2.3.11

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 (57) hide show
  1. package/android/cpp/jni/include/JniSkiaBaseView.h +9 -2
  2. package/android/cpp/jni/include/JniSkiaPictureView.h +97 -2
  3. package/android/cpp/rnskia-android/OpenGLContext.h +1 -0
  4. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +3 -1
  5. package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java +42 -0
  6. package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureViewManager.java +5 -0
  7. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerDelegate.java +8 -2
  8. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerInterface.java +1 -0
  9. package/apple/SkiaCVPixelBufferUtils.mm +8 -4
  10. package/cpp/api/JsiSkAnimatedImage.h +3 -4
  11. package/cpp/api/JsiSkSurface.h +4 -3
  12. package/cpp/api/recorder/Drawings.h +10 -2
  13. package/cpp/api/recorder/JsiRecorder.h +1 -1
  14. package/cpp/jsi/ViewProperty.h +2 -36
  15. package/cpp/rnskia/RNSkJsiViewApi.h +2 -5
  16. package/cpp/rnskia/RNSkPictureView.h +2 -23
  17. package/cpp/rnskia/RNSkView.h +0 -7
  18. package/lib/commonjs/renderer/Canvas.js +21 -15
  19. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  20. package/lib/commonjs/sksg/Container.native.d.ts +0 -3
  21. package/lib/commonjs/sksg/Container.native.js +8 -14
  22. package/lib/commonjs/sksg/Container.native.js.map +1 -1
  23. package/lib/commonjs/sksg/Reconciler.js +2 -2
  24. package/lib/commonjs/sksg/Reconciler.js.map +1 -1
  25. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  26. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  27. package/lib/commonjs/views/SkiaPictureView.d.ts +1 -0
  28. package/lib/commonjs/views/SkiaPictureView.js +3 -1
  29. package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
  30. package/lib/commonjs/views/SkiaPictureView.web.js +13 -2
  31. package/lib/commonjs/views/SkiaPictureView.web.js.map +1 -1
  32. package/lib/module/renderer/Canvas.js +21 -15
  33. package/lib/module/renderer/Canvas.js.map +1 -1
  34. package/lib/module/sksg/Container.native.d.ts +0 -3
  35. package/lib/module/sksg/Container.native.js +8 -14
  36. package/lib/module/sksg/Container.native.js.map +1 -1
  37. package/lib/module/sksg/Reconciler.js +2 -2
  38. package/lib/module/sksg/Reconciler.js.map +1 -1
  39. package/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  40. package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  41. package/lib/module/views/SkiaPictureView.d.ts +1 -0
  42. package/lib/module/views/SkiaPictureView.js +3 -1
  43. package/lib/module/views/SkiaPictureView.js.map +1 -1
  44. package/lib/module/views/SkiaPictureView.web.js +13 -2
  45. package/lib/module/views/SkiaPictureView.web.js.map +1 -1
  46. package/lib/typescript/lib/commonjs/sksg/Container.native.d.ts +0 -4
  47. package/lib/typescript/lib/module/sksg/Container.native.d.ts +0 -4
  48. package/lib/typescript/src/sksg/Container.native.d.ts +0 -3
  49. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  50. package/lib/typescript/src/views/SkiaPictureView.d.ts +1 -0
  51. package/package.json +1 -1
  52. package/src/renderer/Canvas.tsx +20 -17
  53. package/src/sksg/Container.native.ts +7 -16
  54. package/src/sksg/Reconciler.ts +2 -2
  55. package/src/specs/SkiaPictureViewNativeComponent.ts +1 -0
  56. package/src/views/SkiaPictureView.tsx +3 -1
  57. package/src/views/SkiaPictureView.web.tsx +14 -2
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include <memory>
4
4
  #include <string>
5
+ #include <vector>
5
6
 
6
7
  #include <fbjni/fbjni.h>
7
8
  #include <jni.h>
@@ -20,7 +21,7 @@ class JniSkiaBaseView {
20
21
  public:
21
22
  JniSkiaBaseView(jni::alias_ref<JniSkiaManager::javaobject> skiaManager,
22
23
  std::shared_ptr<RNSkBaseAndroidView> skiaView)
23
- : _manager(skiaManager->cthis()), _skiaAndroidView(std::move(skiaView)) {}
24
+ : _skiaAndroidView(std::move(skiaView)), _manager(skiaManager->cthis()) {}
24
25
 
25
26
  ~JniSkiaBaseView() = default;
26
27
 
@@ -57,9 +58,15 @@ protected:
57
58
  _skiaAndroidView->getSkiaView()->getNativeId());
58
59
  }
59
60
 
61
+ virtual jni::local_ref<jni::JArrayInt> getBitmap(int width, int height) {
62
+ return jni::JArrayInt::newArray(0);
63
+ }
64
+
65
+ protected:
66
+ std::shared_ptr<RNSkBaseAndroidView> _skiaAndroidView;
67
+
60
68
  private:
61
69
  JniSkiaManager *_manager;
62
- std::shared_ptr<RNSkBaseAndroidView> _skiaAndroidView;
63
70
  };
64
71
 
65
72
  } // namespace RNSkia
@@ -1,7 +1,9 @@
1
1
  #pragma once
2
2
 
3
+ #include <cstdint>
3
4
  #include <memory>
4
5
  #include <string>
6
+ #include <vector>
5
7
 
6
8
  #include <fbjni/fbjni.h>
7
9
  #include <jni.h>
@@ -16,6 +18,19 @@
16
18
  #include <android/native_window_jni.h>
17
19
  #include <fbjni/detail/Hybrid.h>
18
20
 
21
+ #if defined(SK_GRAPHITE)
22
+ #include "RNDawnContext.h"
23
+ #else
24
+ #include "OpenGLContext.h"
25
+ #endif
26
+ #include "include/core/SkBitmap.h"
27
+ #include "include/core/SkCanvas.h"
28
+ #include "include/core/SkImage.h"
29
+ #include "include/core/SkPaint.h"
30
+ #include "include/core/SkPicture.h"
31
+ #include "include/core/SkPictureRecorder.h"
32
+ #include "include/core/SkSurface.h"
33
+
19
34
  namespace RNSkia {
20
35
  namespace jsi = facebook::jsi;
21
36
  namespace jni = facebook::jni;
@@ -43,8 +58,8 @@ public:
43
58
  JniSkiaPictureView::surfaceSizeChanged),
44
59
  makeNativeMethod("setDebugMode", JniSkiaPictureView::setDebugMode),
45
60
  makeNativeMethod("registerView", JniSkiaPictureView::registerView),
46
- makeNativeMethod("unregisterView",
47
- JniSkiaPictureView::unregisterView)});
61
+ makeNativeMethod("unregisterView", JniSkiaPictureView::unregisterView),
62
+ makeNativeMethod("getBitmap", JniSkiaPictureView::getBitmap)});
48
63
  }
49
64
 
50
65
  protected:
@@ -68,6 +83,86 @@ protected:
68
83
 
69
84
  void unregisterView() override { JniSkiaBaseView::unregisterView(); }
70
85
 
86
+ jni::local_ref<jni::JArrayInt> getBitmap(int width, int height) override {
87
+ // Get the RNSkPictureView from the android view
88
+ auto pictureView =
89
+ std::static_pointer_cast<RNSkAndroidView<RNSkia::RNSkPictureView>>(
90
+ _skiaAndroidView);
91
+ if (!pictureView) {
92
+ return JniSkiaBaseView::getBitmap(width, height);
93
+ }
94
+
95
+ // Get the renderer and cast it to RNSkPictureRenderer
96
+ auto renderer = std::static_pointer_cast<RNSkia::RNSkPictureRenderer>(
97
+ pictureView->getRenderer());
98
+ if (!renderer) {
99
+ return jni::JArrayInt::newArray(0);
100
+ }
101
+
102
+ // Get the SkPicture from the renderer
103
+ sk_sp<SkPicture> picture = renderer->getPicture();
104
+
105
+ const size_t pixelCount =
106
+ static_cast<size_t>(width) * static_cast<size_t>(height);
107
+ if (pixelCount == 0) {
108
+ return jni::JArrayInt::newArray(0);
109
+ }
110
+
111
+ sk_sp<SkSurface> surface;
112
+ #if defined(SK_GRAPHITE)
113
+ surface = DawnContext::getInstance().MakeOffscreen(width, height);
114
+ #else
115
+ surface = OpenGLContext::getInstance().MakeOffscreen(width, height);
116
+ #endif
117
+
118
+ if (!surface) {
119
+ return jni::JArrayInt::newArray(0);
120
+ }
121
+
122
+ SkCanvas *canvas = surface->getCanvas();
123
+ if (canvas == nullptr) {
124
+ return jni::JArrayInt::newArray(0);
125
+ }
126
+
127
+ canvas->clear(SK_ColorTRANSPARENT);
128
+
129
+ if (picture) {
130
+ auto pd = pictureView->getPixelDensity();
131
+ canvas->save();
132
+ canvas->scale(pd, pd);
133
+ canvas->drawPicture(picture);
134
+ canvas->restore();
135
+ }
136
+
137
+ sk_sp<SkImage> snapshot = surface->makeImageSnapshot();
138
+ if (!snapshot) {
139
+ return jni::JArrayInt::newArray(0);
140
+ }
141
+
142
+ sk_sp<SkImage> image = snapshot->makeNonTextureImage();
143
+ if (!image) {
144
+ image = snapshot;
145
+ }
146
+
147
+ if (!image) {
148
+ return jni::JArrayInt::newArray(0);
149
+ }
150
+
151
+ std::vector<int32_t> pixels(pixelCount);
152
+ SkImageInfo readInfo = SkImageInfo::Make(
153
+ width, height, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
154
+ size_t rowBytes = static_cast<size_t>(width) * sizeof(int32_t);
155
+ if (!image->readPixels(nullptr, readInfo, pixels.data(), rowBytes, 0, 0)) {
156
+ return jni::JArrayInt::newArray(0);
157
+ }
158
+
159
+ auto intArray = jni::JArrayInt::newArray(pixelCount);
160
+ intArray->setRegion(0, pixelCount,
161
+ reinterpret_cast<const jint *>(pixels.data()));
162
+
163
+ return intArray;
164
+ }
165
+
71
166
  private:
72
167
  friend HybridBase;
73
168
 
@@ -78,6 +78,7 @@ public:
78
78
  if (!texture.isValid()) {
79
79
  RNSkLogger::logToConsole("couldn't create offscreen texture %dx%d", width,
80
80
  height);
81
+ return nullptr;
81
82
  }
82
83
 
83
84
  struct ReleaseContext {
@@ -80,4 +80,6 @@ public abstract class SkiaBaseView extends ReactViewGroup implements SkiaViewAPI
80
80
  protected abstract void registerView(int nativeId);
81
81
 
82
82
  protected abstract void unregisterView();
83
- }
83
+
84
+ protected abstract int[] getBitmap(int width, int height);
85
+ }
@@ -1,6 +1,9 @@
1
1
  package com.shopify.reactnative.skia;
2
2
 
3
3
  import android.content.Context;
4
+ import android.graphics.Bitmap;
5
+ import android.graphics.Canvas;
6
+ import android.graphics.Paint;
4
7
 
5
8
  import com.facebook.jni.HybridData;
6
9
  import com.facebook.jni.annotations.DoNotStrip;
@@ -9,6 +12,9 @@ import com.facebook.react.bridge.ReactContext;
9
12
  public class SkiaPictureView extends SkiaBaseView {
10
13
  @DoNotStrip
11
14
  private HybridData mHybridData;
15
+ private Paint paint = new Paint();
16
+
17
+ private boolean coldStart = false;
12
18
 
13
19
  public SkiaPictureView(Context context) {
14
20
  super(context);
@@ -16,12 +22,46 @@ public class SkiaPictureView extends SkiaBaseView {
16
22
  mHybridData = initHybrid(skiaModule.getSkiaManager());
17
23
  }
18
24
 
25
+ public void setColdStart(boolean coldStart) {
26
+ this.coldStart = coldStart;
27
+ setWillNotDraw(coldStart);
28
+ }
29
+
19
30
  @Override
20
31
  protected void finalize() throws Throwable {
21
32
  super.finalize();
22
33
  mHybridData.resetNative();
23
34
  }
24
35
 
36
+ @Override
37
+ protected void onDraw(Canvas canvas) {
38
+ super.onDraw(canvas);
39
+
40
+ // Skip the warming up feature if coldStart is true or running on software renderer
41
+ if (coldStart || !canvas.isHardwareAccelerated()) {
42
+ return; // Skip warmup on cold start or software rendering
43
+ }
44
+
45
+ // Get the view dimensions
46
+ int width = getWidth();
47
+ int height = getHeight();
48
+
49
+ if (width > 0 && height > 0) {
50
+ // Get the bitmap data from native
51
+ int[] pixels = getBitmap(width, height);
52
+
53
+ if (pixels != null && pixels.length == width * height) {
54
+ // Create bitmap from pixels
55
+ Bitmap bitmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
56
+
57
+ // Draw the bitmap on the canvas
58
+ paint.setFilterBitmap(true);
59
+ canvas.drawBitmap(bitmap, 0, 0, paint);
60
+ // Let GC release the bitmap; recycling immediately breaks hardware-accelerated draws.
61
+ }
62
+ }
63
+ }
64
+
25
65
  private native HybridData initHybrid(SkiaManager skiaManager);
26
66
 
27
67
  protected native void surfaceAvailable(Object surface, int width, int height, boolean opaque);
@@ -37,4 +77,6 @@ public class SkiaPictureView extends SkiaBaseView {
37
77
  protected native void registerView(int nativeId);
38
78
 
39
79
  protected native void unregisterView();
80
+
81
+ protected native int[] getBitmap(int width, int height);
40
82
  }
@@ -36,4 +36,9 @@ public class SkiaPictureViewManager extends SkiaBaseViewManager<SkiaPictureView>
36
36
  public void setColorSpace(SkiaPictureView view, @Nullable String value) {
37
37
  // nothing to do here at the moment
38
38
  }
39
+
40
+ @Override
41
+ public void setColdStart(SkiaPictureView view, boolean value) {
42
+ view.setColdStart(value);
43
+ }
39
44
  }
@@ -22,11 +22,17 @@ public class SkiaPictureViewManagerDelegate<T extends View, U extends BaseViewMa
22
22
  @Override
23
23
  public void setProperty(T view, String propName, @Nullable Object value) {
24
24
  switch (propName) {
25
+ case "debug":
26
+ mViewManager.setDebug(view, value != null && (boolean) value);
27
+ break;
25
28
  case "opaque":
26
29
  mViewManager.setOpaque(view, value != null && (boolean) value);
27
30
  break;
28
- case "debug":
29
- mViewManager.setDebug(view, value != null && (boolean) value);
31
+ case "colorSpace":
32
+ mViewManager.setColorSpace(view, value == null ? null : (String) value);
33
+ break;
34
+ case "coldStart":
35
+ mViewManager.setColdStart(view, value != null && (boolean) value);
30
36
  break;
31
37
  default:
32
38
  super.setProperty(view, propName, value);
@@ -18,4 +18,5 @@ public interface SkiaPictureViewManagerInterface<T extends View> {
18
18
  void setDebug(T view, boolean value);
19
19
  void setOpaque(T view, boolean value);
20
20
  void setColorSpace(SkiaPictureView view, @Nullable String value);
21
+ void setColdStart(T view, boolean value);
21
22
  }
@@ -30,12 +30,16 @@
30
30
  #include <TargetConditionals.h>
31
31
  #if TARGET_RT_BIG_ENDIAN
32
32
  #define FourCC2Str(fourcc) \
33
- (const char[]){*((char *)&fourcc), *(((char *)&fourcc) + 1), \
34
- *(((char *)&fourcc) + 2), *(((char *)&fourcc) + 3), 0}
33
+ (const char[]) { \
34
+ *((char *)&fourcc), *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 2), \
35
+ *(((char *)&fourcc) + 3), 0 \
36
+ }
35
37
  #else
36
38
  #define FourCC2Str(fourcc) \
37
- (const char[]){*(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
38
- *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0}
39
+ (const char[]) { \
40
+ *(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
41
+ *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0 \
42
+ }
39
43
  #endif
40
44
 
41
45
  // pragma MARK: TextureHolder
@@ -106,10 +106,9 @@ public:
106
106
  if (bytesPerPixel == 0) {
107
107
  bytesPerPixel = 4;
108
108
  }
109
- frameBytes =
110
- safeMul(safeMul(static_cast<size_t>(frame->width()),
111
- static_cast<size_t>(frame->height())),
112
- bytesPerPixel);
109
+ frameBytes = safeMul(safeMul(static_cast<size_t>(frame->width()),
110
+ static_cast<size_t>(frame->height())),
111
+ bytesPerPixel);
113
112
  }
114
113
  }
115
114
 
@@ -152,14 +152,15 @@ public:
152
152
 
153
153
  auto canvas = surface->getCanvas();
154
154
  const bool isGpuBacked =
155
- surface->recordingContext() != nullptr || surface->recorder() != nullptr ||
155
+ surface->recordingContext() != nullptr ||
156
+ surface->recorder() != nullptr ||
156
157
  (canvas && (canvas->recordingContext() != nullptr ||
157
158
  canvas->recorder() != nullptr));
158
159
 
159
160
  if (isGpuBacked) {
160
161
  // Account for a resolved texture and depth/stencil attachments.
161
- estimated = safeAdd(estimated, pixelBytes); // resolve/texture copy
162
- estimated = safeAdd(estimated, pixelBytes / 2); // depth-stencil buffers
162
+ estimated = safeAdd(estimated, pixelBytes); // resolve/texture copy
163
+ estimated = safeAdd(estimated, pixelBytes / 2); // depth-stencil buffers
163
164
  }
164
165
 
165
166
  // Add a small overhead buffer for bookkeeping allocations.
@@ -246,10 +246,18 @@ public:
246
246
 
247
247
  // Get glyph widths
248
248
  int glyphsSize = static_cast<int>(ids);
249
+
250
+ // Validate glyph count
251
+ if (glyphsSize > numGlyphIds) {
252
+ throw std::runtime_error(
253
+ "Glyph count mismatch: got " + std::to_string(glyphsSize) +
254
+ " glyphs but expected " + std::to_string(numGlyphIds));
255
+ }
256
+
249
257
  std::vector<SkScalar> widthPtrs;
250
258
  widthPtrs.resize(glyphsSize);
251
259
  font->getWidthsBounds(
252
- SkSpan(glyphIds.data(), numGlyphIds),
260
+ SkSpan(glyphIds.data(), glyphsSize),
253
261
  SkSpan(static_cast<SkScalar *>(widthPtrs.data()), widthPtrs.size()),
254
262
  {},
255
263
  nullptr); // TODO: Should we use paint somehow here?
@@ -260,7 +268,7 @@ public:
260
268
  auto cont = meas.next();
261
269
  auto dist = initialOffset;
262
270
 
263
- for (size_t i = 0; i < text.length() && cont != nullptr; ++i) {
271
+ for (int i = 0; i < glyphsSize && cont != nullptr; ++i) {
264
272
  auto width = widthPtrs[i];
265
273
  dist += width / 2;
266
274
  if (dist > cont->length()) {
@@ -349,7 +349,7 @@ public:
349
349
 
350
350
  // This has no basis in reality but since since these are private long-lived
351
351
  // objects, we think it is more than fine.
352
- size_t getMemoryPressure() const override { return 10 * 1024 * 1024; }
352
+ size_t getMemoryPressure() const override { return 5 * 1024 * 1024; }
353
353
 
354
354
  std::string getObjectType() const override { return "JsiRecorder"; }
355
355
 
@@ -53,47 +53,13 @@ public:
53
53
 
54
54
  template <typename PlatformContext>
55
55
  ViewProperty(jsi::Runtime &runtime, const jsi::Value &value,
56
- PlatformContext platformContext, size_t nativeId) {
57
- // Set the onSize callback with all the necessary context
58
- auto runtimeGuard = std::make_shared<RuntimeAwareRuntimeGuard>(runtime);
59
- _value = std::function<void(int, int)>(
60
- [runtimeGuard, platformContext, nativeId](int width, int height) {
61
- auto runtimePtr = runtimeGuard->getRuntime();
62
- if (runtimePtr == nullptr) {
63
- return;
64
- }
65
-
66
- jsi::Runtime &runtime = *runtimePtr;
67
- jsi::Object size(runtime);
68
- auto pd = platformContext->getPixelDensity();
69
- size.setProperty(runtime, "width", jsi::Value(width / pd));
70
- size.setProperty(runtime, "height", jsi::Value(height / pd));
71
-
72
- // Get the stored shared value from global
73
- std::string globalKey =
74
- "__onSize_" + std::to_string(static_cast<int>(nativeId));
75
- auto globalProp =
76
- runtime.global().getProperty(runtime, globalKey.c_str());
77
- if (!globalProp.isUndefined()) {
78
- globalProp.asObject(runtime).setProperty(runtime, "value", size);
79
- }
80
- });
81
- }
56
+ PlatformContext platformContext, size_t nativeId) {}
82
57
 
83
58
  bool isNull() { return std::holds_alternative<std::nullptr_t>(_value); }
84
59
 
85
60
  sk_sp<SkPicture> getPicture() { return std::get<sk_sp<SkPicture>>(_value); }
86
61
 
87
- std::variant<std::nullptr_t, std::function<void(int, int)>>
88
- getOnSize() const {
89
- if (std::holds_alternative<std::function<void(int, int)>>(_value)) {
90
- return std::get<std::function<void(int, int)>>(_value);
91
- }
92
- return nullptr;
93
- }
94
-
95
62
  private:
96
- std::variant<std::nullptr_t, sk_sp<SkPicture>, std::function<void(int, int)>>
97
- _value = nullptr;
63
+ std::variant<std::nullptr_t, sk_sp<SkPicture>> _value = nullptr;
98
64
  };
99
65
  } // namespace RNJsi
@@ -106,11 +106,6 @@ public:
106
106
  info->props.insert_or_assign(
107
107
  arguments[1].asString(runtime).utf8(runtime),
108
108
  RNJsi::ViewProperty(runtime, arguments[2]));
109
- if (info->props.find("onSize") == info->props.end()) {
110
- info->props.insert_or_assign(
111
- "onSize", RNJsi::ViewProperty(runtime, arguments[2],
112
- _platformContext, nativeId));
113
- }
114
109
  // Now let's see if we have a view that we can update
115
110
  if (info->view != nullptr) {
116
111
  // Update view!
@@ -301,8 +296,10 @@ public:
301
296
  nativeId, [&](std::shared_ptr<RNSkViewInfo> info) {
302
297
  info->view = view;
303
298
  info->view->setNativeId(nativeId);
299
+
304
300
  info->view->setJsiProperties(info->props);
305
301
  info->props.clear();
302
+
306
303
  return nullptr;
307
304
  });
308
305
  }
@@ -56,25 +56,10 @@ public:
56
56
  _requestRedraw();
57
57
  }
58
58
 
59
- void setOnSize(
60
- std::variant<std::nullptr_t, std::function<void(int, int)>> onSize) {
61
- _onSize = onSize;
62
- }
59
+ sk_sp<SkPicture> getPicture() const { return _picture; }
63
60
 
64
61
  private:
65
62
  bool performDraw(std::shared_ptr<RNSkCanvasProvider> canvasProvider) {
66
- // Call onSize callback only if the size has changed
67
- int currentWidth = canvasProvider->getWidth();
68
- int currentHeight = canvasProvider->getHeight();
69
-
70
- if (std::holds_alternative<std::function<void(int, int)>>(_onSize)) {
71
- if (_lastWidth != currentWidth || _lastHeight != currentHeight) {
72
- _lastWidth = currentWidth;
73
- _lastHeight = currentHeight;
74
- std::get<std::function<void(int, int)>>(_onSize)(currentWidth,
75
- currentHeight);
76
- }
77
- }
78
63
  return canvasProvider->renderToCanvas([=, this](SkCanvas *canvas) {
79
64
  // Make sure to scale correctly
80
65
  auto pd = _platformContext->getPixelDensity();
@@ -90,9 +75,6 @@ private:
90
75
 
91
76
  std::shared_ptr<RNSkPlatformContext> _platformContext;
92
77
  sk_sp<SkPicture> _picture;
93
- std::variant<std::nullptr_t, std::function<void(int, int)>> _onSize = nullptr;
94
- int _lastWidth = -1;
95
- int _lastHeight = -1;
96
78
  };
97
79
 
98
80
  class RNSkPictureView : public RNSkView {
@@ -109,7 +91,7 @@ public:
109
91
 
110
92
  void setJsiProperties(
111
93
  std::unordered_map<std::string, RNJsi::ViewProperty> &props) override {
112
- // Base implementation - no onSize callback
94
+ // Base implementation
113
95
  for (auto &prop : props) {
114
96
  if (prop.first == "picture") {
115
97
  if (prop.second.isNull()) {
@@ -121,9 +103,6 @@ public:
121
103
  // Save picture
122
104
  std::static_pointer_cast<RNSkPictureRenderer>(getRenderer())
123
105
  ->setPicture(prop.second.getPicture());
124
- } else if (prop.first == "onSize") {
125
- std::static_pointer_cast<RNSkPictureRenderer>(getRenderer())
126
- ->setOnSize(prop.second.getOnSize());
127
106
  }
128
107
  }
129
108
  }
@@ -148,13 +148,6 @@ public:
148
148
  virtual void setJsiProperties(
149
149
  std::unordered_map<std::string, RNJsi::ViewProperty> &props) = 0;
150
150
 
151
- virtual void
152
- setJsiProperties(std::unordered_map<std::string, RNJsi::ViewProperty> &props,
153
- std::function<jsi::Object(int, int)> onSize) {
154
- // Default implementation just calls the base method, ignoring onSize
155
- setJsiProperties(props);
156
- }
157
-
158
151
  void requestRedraw() {
159
152
  if (!_redrawRequested) {
160
153
  _redrawRequested = true;
@@ -20,6 +20,8 @@ function _extends() { return _extends = Object.assign ? Object.assign.bind() : f
20
20
  const useCanvasRef = () => (0, _react.useRef)(null);
21
21
  exports.useCanvasRef = useCanvasRef;
22
22
  const useReanimatedFrame = !_external.HAS_REANIMATED_3 ? () => {} : _ReanimatedProxy.default.useFrameCallback;
23
+ const measure = !_external.HAS_REANIMATED_3 ? null : _ReanimatedProxy.default.measure;
24
+ const useCanvasRefPriv = !_external.HAS_REANIMATED_3 ? _react.useRef : _ReanimatedProxy.default.useAnimatedRef;
23
25
  const useCanvasSize = userRef => {
24
26
  const ourRef = useCanvasRef();
25
27
  const ref = userRef !== null && userRef !== void 0 ? userRef : ourRef;
@@ -63,7 +65,7 @@ const Canvas = ({
63
65
  if (onLayout && isFabric) {
64
66
  console.error("<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size");
65
67
  }
66
- const viewRef = (0, _react.useRef)(null);
68
+ const viewRef = useCanvasRefPriv(null);
67
69
  // Native ID
68
70
  const nativeId = (0, _react.useMemo)(() => {
69
71
  return _SkiaViewNativeId.SkiaViewNativeId.current++;
@@ -73,20 +75,23 @@ const Canvas = ({
73
75
  const root = (0, _react.useMemo)(() => new _Reconciler.SkiaSGRoot(_skia.Skia, nativeId), [nativeId]);
74
76
  useReanimatedFrame(() => {
75
77
  "worklet";
76
- }, !!onSize);
77
- (0, _react.useEffect)(() => {
78
- if (onSize) {
79
- _ReanimatedProxy.default.runOnUI(() => {
80
- global[`__onSize_${nativeId}`] = onSize;
81
- })();
82
- return () => {
83
- _ReanimatedProxy.default.runOnUI(() => {
84
- delete global[`__onSize_${nativeId}`];
85
- })();
86
- };
78
+
79
+ if (onSize && measure) {
80
+ const result = measure(viewRef);
81
+ if (result) {
82
+ const {
83
+ width,
84
+ height
85
+ } = result;
86
+ if (onSize.value.width !== width || onSize.value.height !== height) {
87
+ onSize.value = {
88
+ width,
89
+ height
90
+ };
91
+ }
92
+ }
87
93
  }
88
- return undefined;
89
- }, [onSize, nativeId]);
94
+ }, !!onSize);
90
95
 
91
96
  // Render effects
92
97
  (0, _react.useLayoutEffect)(() => {
@@ -143,7 +148,8 @@ const Canvas = ({
143
148
  debug: debug,
144
149
  opaque: opaque,
145
150
  colorSpace: colorSpace,
146
- onLayout: onLayoutWeb
151
+ coldStart: false,
152
+ onLayout: _Platform.Platform.OS === "web" && (onSize || onLayout) ? onLayoutWeb : onLayout
147
153
  }, viewProps));
148
154
  };
149
155
  exports.Canvas = Canvas;
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_ReanimatedProxy","_interopRequireDefault","_SkiaViewNativeId","_SkiaPictureViewNativeComponent","_Reconciler","_skia","_Platform","_external","_global","e","__esModule","default","_getRequireWildcardCache","WeakMap","r","t","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","_extends","assign","bind","arguments","length","apply","useCanvasRef","useRef","exports","useReanimatedFrame","HAS_REANIMATED_3","Rea","useFrameCallback","useCanvasSize","userRef","ourRef","ref","size","setSize","useState","width","height","useLayoutEffect","current","measure","_x","_y","isFabric","Boolean","global","nativeFabricUIManager","Canvas","debug","opaque","children","onSize","colorSpace","onLayout","viewProps","console","error","viewRef","nativeId","useMemo","SkiaViewNativeId","root","SkiaSGRoot","Skia","useEffect","runOnUI","undefined","render","unmount","useImperativeHandle","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current","measureInWindow","_viewRef$current2","onLayoutWeb","useCallback","Platform","OS","nativeEvent","layout","value","createElement","collapsable","nativeID"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport SkiaPictureViewNativeComponent from \"../specs/SkiaPictureViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\nimport { HAS_REANIMATED_3 } from \"../external\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nconst useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isFabric = Boolean((global as any)?.nativeFabricUIManager);\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n debug?: boolean;\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n colorSpace?: \"p3\" | \"srgb\";\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\nexport const Canvas = ({\n debug,\n opaque,\n children,\n onSize,\n colorSpace = \"p3\",\n ref,\n // Here know this is a type error but this is done on purpose to check it at runtime\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n if (onLayout && isFabric) {\n console.error(\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size\"\n );\n }\n const viewRef = useRef<View>(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n useReanimatedFrame(() => {\n \"worklet\";\n }, !!onSize);\n useEffect(() => {\n if (onSize) {\n Rea.runOnUI(() => {\n (global as Record<string, unknown>)[`__onSize_${nativeId}`] = onSize;\n })();\n return () => {\n Rea.runOnUI(() => {\n delete (global as Record<string, unknown>)[`__onSize_${nativeId}`];\n })();\n };\n }\n return undefined;\n }, [onSize, nativeId]);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n }) as CanvasRef\n );\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n\n return (\n <SkiaPictureViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n debug={debug}\n opaque={opaque}\n colorSpace={colorSpace}\n onLayout={onLayoutWeb}\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_ReanimatedProxy","_interopRequireDefault","_SkiaViewNativeId","_SkiaPictureViewNativeComponent","_Reconciler","_skia","_Platform","_external","_global","e","__esModule","default","_getRequireWildcardCache","WeakMap","r","t","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","_extends","assign","bind","arguments","length","apply","useCanvasRef","useRef","exports","useReanimatedFrame","HAS_REANIMATED_3","Rea","useFrameCallback","measure","useCanvasRefPriv","useAnimatedRef","useCanvasSize","userRef","ourRef","ref","size","setSize","useState","width","height","useLayoutEffect","current","_x","_y","isFabric","Boolean","global","nativeFabricUIManager","Canvas","debug","opaque","children","onSize","colorSpace","onLayout","viewProps","console","error","viewRef","nativeId","useMemo","SkiaViewNativeId","root","SkiaSGRoot","Skia","result","value","render","useEffect","unmount","useImperativeHandle","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current","measureInWindow","_viewRef$current2","onLayoutWeb","useCallback","Platform","OS","nativeEvent","layout","createElement","collapsable","nativeID","coldStart"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport type { AnimatedRef, SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport SkiaPictureViewNativeComponent from \"../specs/SkiaPictureViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\nimport { HAS_REANIMATED_3 } from \"../external\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nconst useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;\nconst measure = !HAS_REANIMATED_3 ? null : Rea.measure;\n\nconst useCanvasRefPriv: typeof useRef<View> = !HAS_REANIMATED_3\n ? useRef\n : Rea.useAnimatedRef;\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isFabric = Boolean((global as any)?.nativeFabricUIManager);\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n debug?: boolean;\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n colorSpace?: \"p3\" | \"srgb\";\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\nexport const Canvas = ({\n debug,\n opaque,\n children,\n onSize,\n colorSpace = \"p3\",\n ref,\n // Here know this is a type error but this is done on purpose to check it at runtime\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n if (onLayout && isFabric) {\n console.error(\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size\"\n );\n }\n const viewRef = useCanvasRefPriv(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n useReanimatedFrame(() => {\n \"worklet\";\n if (onSize && measure) {\n const result = measure(viewRef as AnimatedRef<View>);\n if (result) {\n const { width, height } = result;\n if (onSize.value.width !== width || onSize.value.height !== height) {\n onSize.value = { width, height };\n }\n }\n }\n }, !!onSize);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n }) as CanvasRef\n );\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n return (\n <SkiaPictureViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n debug={debug}\n opaque={opaque}\n colorSpace={colorSpace}\n coldStart={false}\n onLayout={\n Platform.OS === \"web\" && (onSize || onLayout) ? onLayoutWeb : onLayout\n }\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}