@shopify/react-native-skia 1.5.0 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. package/android/cpp/jni/include/JniSkiaBaseView.h +0 -1
  2. package/android/cpp/jni/include/JniSkiaPictureView.h +0 -1
  3. package/android/cpp/rnskia-android/OpenGLContext.h +40 -0
  4. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +5 -5
  5. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +2 -2
  6. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +49 -14
  7. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +5 -2
  8. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +19 -133
  9. package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +30 -138
  10. package/cpp/api/JsiSkTypefaceFontProvider.h +1 -1
  11. package/cpp/api/JsiSkiaContext.h +6 -3
  12. package/cpp/jsi/JsiValue.cpp +1 -2
  13. package/cpp/rnskia/RNSkPlatformContext.h +2 -2
  14. package/cpp/rnskia/{SkiaContext.h → WindowContext.h} +5 -2
  15. package/ios/RNSkia-iOS/DisplayLink.mm +7 -0
  16. package/ios/RNSkia-iOS/MetalContext.h +46 -0
  17. package/ios/RNSkia-iOS/MetalContext.mm +33 -0
  18. package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm +8 -28
  19. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +1 -1
  20. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +8 -9
  21. package/ios/RNSkia-iOS/RNSkiOSView.mm +0 -2
  22. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +28 -32
  23. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +18 -60
  24. package/ios/RNSkia-iOS/SkiaUIView.h +0 -2
  25. package/ios/RNSkia-iOS/ViewScreenshotService.mm +1 -8
  26. package/lib/commonjs/web/WithSkiaWeb.js +4 -1
  27. package/lib/commonjs/web/WithSkiaWeb.js.map +1 -1
  28. package/lib/module/web/WithSkiaWeb.js +4 -1
  29. package/lib/module/web/WithSkiaWeb.js.map +1 -1
  30. package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
  31. package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  32. package/libs/ios/libskottie.xcframework/Info.plist +5 -5
  33. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
  34. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
  35. package/libs/ios/libskparagraph.xcframework/Info.plist +5 -5
  36. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
  37. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
  38. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
  39. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
  40. package/libs/ios/libskshaper.xcframework/Info.plist +5 -5
  41. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
  42. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
  43. package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e/libskunicode_core.a +0 -0
  44. package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_core.a +0 -0
  45. package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e/libskunicode_libgrapheme.a +0 -0
  46. package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_libgrapheme.a +0 -0
  47. package/libs/ios/libsvg.xcframework/Info.plist +5 -5
  48. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
  49. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
  50. package/package.json +3 -6
  51. package/src/web/WithSkiaWeb.tsx +3 -1
@@ -40,7 +40,7 @@ public:
40
40
  sk_sp<SkTypeface> typeface =
41
41
  JsiSkTypeface::fromValue(runtime, arguments[0]);
42
42
  SkString familyName(arguments[1].asString(runtime).utf8(runtime).c_str());
43
- auto result = getObject()->registerTypeface(typeface, familyName);
43
+ getObject()->registerTypeface(typeface, familyName);
44
44
  return jsi::Value::undefined();
45
45
  }
46
46
 
@@ -14,7 +14,7 @@
14
14
  #include "JsiSkRect.h"
15
15
  #include "JsiSkTypeface.h"
16
16
 
17
- #include "SkiaContext.h"
17
+ #include "WindowContext.h"
18
18
 
19
19
  #pragma clang diagnostic push
20
20
  #pragma clang diagnostic ignored "-Wdocumentation"
@@ -28,12 +28,15 @@ namespace RNSkia {
28
28
 
29
29
  namespace jsi = facebook::jsi;
30
30
 
31
- class JsiSkiaContext : public JsiSkWrappingSharedPtrHostObject<SkiaContext> {
31
+ class JsiSkiaContext : public JsiSkWrappingSharedPtrHostObject<WindowContext> {
32
32
  public:
33
33
  EXPORT_JSI_API_TYPENAME(JsiSkiaContext, SkiaContext)
34
34
 
35
35
  JSI_HOST_FUNCTION(getSurface) {
36
36
  auto surface = getObject()->getSurface();
37
+ if (surface == nullptr) {
38
+ return jsi::Value::null();
39
+ }
37
40
  return jsi::Object::createFromHostObject(
38
41
  runtime,
39
42
  std::make_shared<JsiSkSurface>(getContext(), std::move(surface)));
@@ -48,7 +51,7 @@ public:
48
51
  JSI_EXPORT_FUNC(JsiSkiaContext, present))
49
52
 
50
53
  JsiSkiaContext(std::shared_ptr<RNSkPlatformContext> context,
51
- std::shared_ptr<SkiaContext> ctx)
54
+ std::shared_ptr<WindowContext> ctx)
52
55
  : JsiSkWrappingSharedPtrHostObject(std::move(context), std::move(ctx)) {}
53
56
 
54
57
  /**
@@ -55,9 +55,8 @@ double JsiValue::getAsNumber() const {
55
55
 
56
56
  const std::string &JsiValue::getAsString() const {
57
57
  if (_type == PropType::Number) {
58
- return std::move(std::to_string(_numberValue));
58
+ return std::to_string(_numberValue);
59
59
  }
60
-
61
60
  if (_type != PropType::String) {
62
61
  throw std::runtime_error("Expected type string, got " +
63
62
  getTypeAsString(_type));
@@ -11,7 +11,7 @@
11
11
 
12
12
  #include "RNSkDispatchQueue.h"
13
13
  #include "RNSkVideo.h"
14
- #include "SkiaContext.h"
14
+ #include "WindowContext.h"
15
15
 
16
16
  #pragma clang diagnostic push
17
17
  #pragma clang diagnostic ignored "-Wdocumentation"
@@ -135,7 +135,7 @@ public:
135
135
  */
136
136
  virtual sk_sp<SkSurface> makeOffscreenSurface(int width, int height) = 0;
137
137
 
138
- virtual std::shared_ptr<SkiaContext>
138
+ virtual std::shared_ptr<WindowContext>
139
139
  makeContextFromNativeSurface(void *surface, int width, int height) = 0;
140
140
 
141
141
  /**
@@ -12,11 +12,14 @@
12
12
 
13
13
  namespace RNSkia {
14
14
 
15
- class SkiaContext {
15
+ class WindowContext {
16
16
  public:
17
- virtual ~SkiaContext() = default;
17
+ virtual ~WindowContext() = default;
18
18
  virtual sk_sp<SkSurface> getSurface() = 0;
19
19
  virtual void present() = 0;
20
+ virtual void resize(int width, int height) = 0;
21
+ virtual int getWidth() = 0;
22
+ virtual int getHeight() = 0;
20
23
  };
21
24
 
22
25
  } // namespace RNSkia
@@ -10,6 +10,13 @@
10
10
  _displayLink = [CADisplayLink displayLinkWithTarget:self
11
11
  selector:@selector(update:)];
12
12
 
13
+ if (@available(iOS 15.0, *)) {
14
+ CAFrameRateRange rate = CAFrameRateRangeMake(60, 120, 120);
15
+ _displayLink.preferredFrameRateRange = rate;
16
+ } else {
17
+ _displayLink.preferredFramesPerSecond = 60;
18
+ }
19
+
13
20
  // add the display link to the main run loop
14
21
  [_displayLink addToRunLoop:[NSRunLoop mainRunLoop]
15
22
  forMode:NSRunLoopCommonModes];
@@ -0,0 +1,46 @@
1
+ #pragma once
2
+
3
+ #include "SkiaMetalSurfaceFactory.h"
4
+ #include "WindowContext.h"
5
+
6
+ #include "include/core/SkSurface.h"
7
+
8
+ namespace RNSkia {
9
+ class RNSkiOSPlatformContext;
10
+ }
11
+
12
+ class MetalContext {
13
+
14
+ public:
15
+ MetalContext(const MetalContext &) = delete;
16
+ MetalContext &operator=(const MetalContext &) = delete;
17
+
18
+ static MetalContext &getInstance() {
19
+ static thread_local MetalContext instance;
20
+ return instance;
21
+ }
22
+
23
+ sk_sp<SkSurface> MakeOffscreen(int width, int height) {
24
+ return SkiaMetalSurfaceFactory::makeOffscreenSurface(_device, &_context,
25
+ width, height);
26
+ }
27
+
28
+ sk_sp<SkImage> MakeImageFromBuffer(void *buffer) {
29
+ CVPixelBufferRef sampleBuffer = (CVPixelBufferRef)buffer;
30
+ return SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer(&_context,
31
+ sampleBuffer);
32
+ }
33
+
34
+ std::unique_ptr<RNSkia::WindowContext> MakeWindow(CALayer *window, int width,
35
+ int height) {
36
+ return SkiaMetalSurfaceFactory::makeContext(&_context, window, width,
37
+ height);
38
+ }
39
+
40
+ private:
41
+ friend class RNSkia::RNSkiOSPlatformContext;
42
+ id<MTLDevice> _device;
43
+ SkiaMetalContext _context;
44
+
45
+ MetalContext();
46
+ };
@@ -0,0 +1,33 @@
1
+ #include "MetalContext.h"
2
+
3
+ #import <MetalKit/MetalKit.h>
4
+
5
+ #pragma clang diagnostic push
6
+ #pragma clang diagnostic ignored "-Wdocumentation"
7
+
8
+ #import <include/gpu/ganesh/GrBackendSurface.h>
9
+ #import <include/gpu/ganesh/SkImageGanesh.h>
10
+ #import <include/gpu/ganesh/mtl/GrMtlBackendContext.h>
11
+ #import <include/gpu/ganesh/mtl/GrMtlBackendSurface.h>
12
+ #import <include/gpu/ganesh/mtl/GrMtlDirectContext.h>
13
+ #import <include/gpu/ganesh/mtl/GrMtlTypes.h>
14
+ #import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>
15
+
16
+ #pragma clang diagnostic pop
17
+
18
+ MetalContext::MetalContext() {
19
+ _device = MTLCreateSystemDefaultDevice();
20
+ _context.commandQueue =
21
+ id<MTLCommandQueue>(CFRetain((GrMTLHandle)[_device newCommandQueue]));
22
+
23
+ GrMtlBackendContext backendContext = {};
24
+ backendContext.fDevice.reset((__bridge void *)_device);
25
+ backendContext.fQueue.reset((__bridge void *)_context.commandQueue);
26
+ GrContextOptions grContextOptions; // set different options here.
27
+
28
+ // Create the Skia Direct Context
29
+ _context.skContext = GrDirectContexts::MakeMetal(backendContext);
30
+ if (_context.skContext == nullptr) {
31
+ RNSkia::RNSkLogger::logToConsole("Couldn't create a Skia Metal Context");
32
+ }
33
+ }
@@ -1,6 +1,6 @@
1
1
  #import "RNSkMetalCanvasProvider.h"
2
+ #include "MetalContext.h"
2
3
  #import "RNSkLog.h"
3
- #import "SkiaMetalSurfaceFactory.h"
4
4
 
5
5
  #pragma clang diagnostic push
6
6
  #pragma clang diagnostic ignored "-Wdocumentation"
@@ -23,12 +23,6 @@ RNSkMetalCanvasProvider::RNSkMetalCanvasProvider(
23
23
  #pragma clang diagnostic ignored "-Wunguarded-availability-new"
24
24
  _layer = [CAMetalLayer layer];
25
25
  #pragma clang diagnostic pop
26
- _layer.framebufferOnly = NO;
27
- _layer.device = MTLCreateSystemDefaultDevice();
28
- _layer.opaque = false;
29
- _layer.contentsScale = _context->getPixelDensity();
30
- _layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
31
- _layer.contentsGravity = kCAGravityBottomLeft;
32
26
  }
33
27
 
34
28
  RNSkMetalCanvasProvider::~RNSkMetalCanvasProvider() {}
@@ -36,16 +30,12 @@ RNSkMetalCanvasProvider::~RNSkMetalCanvasProvider() {}
36
30
  /**
37
31
  Returns the scaled width of the view
38
32
  */
39
- float RNSkMetalCanvasProvider::getScaledWidth() {
40
- return _width * _context->getPixelDensity();
41
- };
33
+ float RNSkMetalCanvasProvider::getScaledWidth() { return _width; };
42
34
 
43
35
  /**
44
36
  Returns the scaled height of the view
45
37
  */
46
- float RNSkMetalCanvasProvider::getScaledHeight() {
47
- return _height * _context->getPixelDensity();
48
- };
38
+ float RNSkMetalCanvasProvider::getScaledHeight() { return _height; };
49
39
 
50
40
  /**
51
41
  Render to a canvas
@@ -80,11 +70,8 @@ bool RNSkMetalCanvasProvider::renderToCanvas(
80
70
  if (currentDrawable == nullptr) {
81
71
  return false;
82
72
  }
83
-
84
- auto skSurface = SkiaMetalSurfaceFactory::makeWindowedSurface(
85
- currentDrawable.texture, _layer.drawableSize.width,
86
- _layer.drawableSize.height);
87
-
73
+ auto ctx = MetalContext::getInstance().MakeWindow(_layer, _width, _height);
74
+ auto skSurface = ctx->getSurface();
88
75
  SkCanvas *canvas = skSurface->getCanvas();
89
76
  cb(canvas);
90
77
 
@@ -92,22 +79,15 @@ bool RNSkMetalCanvasProvider::renderToCanvas(
92
79
  dContext->flushAndSubmit();
93
80
  }
94
81
 
95
- id<MTLCommandBuffer> commandBuffer(
96
- [ThreadContextHolder::ThreadSkiaMetalContext
97
- .commandQueue commandBuffer]);
98
- [commandBuffer presentDrawable:currentDrawable];
99
- [commandBuffer commit];
82
+ ctx->present();
100
83
  }
101
84
  return true;
102
85
  };
103
86
 
104
87
  void RNSkMetalCanvasProvider::setSize(int width, int height) {
105
- _width = width;
106
- _height = height;
107
88
  _layer.frame = CGRectMake(0, 0, width, height);
108
- _layer.drawableSize = CGSizeMake(width * _context->getPixelDensity(),
109
- height * _context->getPixelDensity());
110
-
89
+ _width = width * _context->getPixelDensity();
90
+ _height = height * _context->getPixelDensity();
111
91
  _requestRedraw();
112
92
  }
113
93
 
@@ -67,7 +67,7 @@ public:
67
67
 
68
68
  std::shared_ptr<RNSkVideo> createVideo(const std::string &url) override;
69
69
 
70
- std::shared_ptr<SkiaContext>
70
+ std::shared_ptr<WindowContext>
71
71
  makeContextFromNativeSurface(void *surface, int width, int height) override;
72
72
 
73
73
  virtual void performStreamOperation(
@@ -5,13 +5,13 @@
5
5
  #include <thread>
6
6
  #include <utility>
7
7
 
8
+ #include "MetalContext.h"
8
9
  #include "RNSkiOSVideo.h"
9
- #import "SkiaCVPixelBufferUtils.h"
10
- #import "SkiaMetalSurfaceFactory.h"
11
10
 
12
11
  #pragma clang diagnostic push
13
12
  #pragma clang diagnostic ignored "-Wdocumentation"
14
13
 
14
+ #import "include/core/SkColorSpace.h"
15
15
  #include "include/core/SkFontMgr.h"
16
16
  #include "include/core/SkSurface.h"
17
17
 
@@ -71,7 +71,7 @@ uint64_t RNSkiOSPlatformContext::makeNativeBuffer(sk_sp<SkImage> image) {
71
71
  if (image->colorType() != kBGRA_8888_SkColorType) {
72
72
  // on iOS, 32_BGRA is the only supported RGB format for CVPixelBuffers.
73
73
  image = image->makeColorTypeAndColorSpace(
74
- ThreadContextHolder::ThreadSkiaMetalContext.skContext.get(),
74
+ MetalContext::getInstance()._context.skContext.get(),
75
75
  kBGRA_8888_SkColorType, SkColorSpace::MakeSRGB());
76
76
  if (image == nullptr) {
77
77
  throw std::runtime_error(
@@ -149,11 +149,11 @@ RNSkiOSPlatformContext::createVideo(const std::string &url) {
149
149
  return std::make_shared<RNSkiOSVideo>(url, this);
150
150
  }
151
151
 
152
- std::shared_ptr<SkiaContext>
152
+ std::shared_ptr<WindowContext>
153
153
  RNSkiOSPlatformContext::makeContextFromNativeSurface(void *surface, int width,
154
154
  int height) {
155
- return SkiaMetalSurfaceFactory::makeContext((__bridge CALayer *)surface,
156
- width, height);
155
+ return MetalContext::getInstance().MakeWindow((__bridge CALayer *)surface,
156
+ width, height);
157
157
  }
158
158
 
159
159
  void RNSkiOSPlatformContext::raiseError(const std::exception &err) {
@@ -162,12 +162,11 @@ void RNSkiOSPlatformContext::raiseError(const std::exception &err) {
162
162
 
163
163
  sk_sp<SkSurface> RNSkiOSPlatformContext::makeOffscreenSurface(int width,
164
164
  int height) {
165
- return SkiaMetalSurfaceFactory::makeOffscreenSurface(width, height);
165
+ return MetalContext::getInstance().MakeOffscreen(width, height);
166
166
  }
167
167
 
168
168
  sk_sp<SkImage> RNSkiOSPlatformContext::makeImageFromNativeBuffer(void *buffer) {
169
- CVPixelBufferRef sampleBuffer = (CVPixelBufferRef)buffer;
170
- return SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer(sampleBuffer);
169
+ return MetalContext::getInstance().MakeImageFromBuffer(buffer);
171
170
  }
172
171
 
173
172
  sk_sp<SkFontMgr> RNSkiOSPlatformContext::createFontMgr() {
@@ -1,5 +1,3 @@
1
- #pragma once
2
-
3
1
  #import <memory>
4
2
 
5
3
  #import "RNSkMetalCanvasProvider.h"
@@ -1,9 +1,11 @@
1
+ #pragma once
2
+
1
3
  #import <MetalKit/MetalKit.h>
2
4
 
3
5
  #include <memory>
4
6
 
5
7
  #include "RNSkLog.h"
6
- #include "SkiaContext.h"
8
+ #include "WindowContext.h"
7
9
 
8
10
  #pragma clang diagnostic push
9
11
  #pragma clang diagnostic ignored "-Wdocumentation"
@@ -20,35 +22,31 @@ using SkiaMetalContext = struct SkiaMetalContext {
20
22
  sk_sp<GrDirectContext> skContext = nullptr;
21
23
  };
22
24
 
23
- class ThreadContextHolder {
24
- public:
25
- static thread_local SkiaMetalContext ThreadSkiaMetalContext;
26
- };
27
-
28
25
  class SkiaMetalSurfaceFactory {
29
26
  friend class IOSSkiaContext;
30
27
 
31
28
  public:
32
- static sk_sp<SkSurface> makeWindowedSurface(id<MTLTexture> texture, int width,
29
+ static sk_sp<SkSurface> makeWindowedSurface(SkiaMetalContext *context,
30
+ id<MTLTexture> texture, int width,
33
31
  int height);
34
- static sk_sp<SkSurface> makeOffscreenSurface(int width, int height);
32
+ static sk_sp<SkSurface> makeOffscreenSurface(id<MTLDevice> device,
33
+ SkiaMetalContext *context,
34
+ int width, int height);
35
35
 
36
36
  static sk_sp<SkImage>
37
- makeTextureFromCVPixelBuffer(CVPixelBufferRef pixelBuffer);
38
-
39
- static std::shared_ptr<RNSkia::SkiaContext>
40
- makeContext(CALayer *texture, int width, int height);
37
+ makeTextureFromCVPixelBuffer(SkiaMetalContext *context,
38
+ CVPixelBufferRef pixelBuffer);
41
39
 
42
- private:
43
- static id<MTLDevice> device;
44
- static bool
45
- createSkiaDirectContextIfNecessary(SkiaMetalContext *threadContext);
40
+ static std::unique_ptr<RNSkia::WindowContext>
41
+ makeContext(SkiaMetalContext *context, CALayer *texture, int width,
42
+ int height);
46
43
  };
47
44
 
48
- class IOSSkiaContext : public RNSkia::SkiaContext {
45
+ class IOSSkiaContext : public RNSkia::WindowContext {
49
46
  public:
50
- IOSSkiaContext(CALayer *layer, int width, int height) {
51
- auto pd = 3;
47
+ IOSSkiaContext(SkiaMetalContext *context, CALayer *layer, int width,
48
+ int height)
49
+ : _context(context) {
52
50
  #pragma clang diagnostic push
53
51
  #pragma clang diagnostic ignored "-Wunguarded-availability-new"
54
52
  _layer = (CAMetalLayer *)layer;
@@ -56,12 +54,10 @@ public:
56
54
  _layer.framebufferOnly = NO;
57
55
  _layer.device = MTLCreateSystemDefaultDevice();
58
56
  _layer.opaque = false;
59
- _layer.contentsScale = pd;
57
+ _layer.contentsScale = 3;
60
58
  _layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
61
59
  _layer.contentsGravity = kCAGravityBottomLeft;
62
-
63
- _layer.frame = CGRectMake(0, 0, width, height);
64
- _layer.drawableSize = CGSizeMake(width * pd, height * pd);
60
+ _layer.drawableSize = CGSizeMake(width, height);
65
61
  }
66
62
 
67
63
  ~IOSSkiaContext() {}
@@ -70,11 +66,6 @@ public:
70
66
  if (_skSurface) {
71
67
  return _skSurface;
72
68
  }
73
- // Create the Skia Direct Context if it doesn't exist
74
- if (!SkiaMetalSurfaceFactory::createSkiaDirectContextIfNecessary(
75
- &ThreadContextHolder::ThreadSkiaMetalContext)) {
76
- return nullptr;
77
- }
78
69
 
79
70
  // Get the next drawable from the CAMetalLayer
80
71
  _currentDrawable = [_layer nextDrawable];
@@ -86,7 +77,7 @@ public:
86
77
 
87
78
  // Get the texture from the drawable
88
79
  _skSurface = SkiaMetalSurfaceFactory::makeWindowedSurface(
89
- _currentDrawable.texture, _layer.drawableSize.width,
80
+ _context, _currentDrawable.texture, _layer.drawableSize.width,
90
81
  _layer.drawableSize.height);
91
82
  return _skSurface;
92
83
  }
@@ -96,15 +87,20 @@ public:
96
87
  dContext->flushAndSubmit();
97
88
  }
98
89
 
99
- id<MTLCommandBuffer> commandBuffer(
100
- [ThreadContextHolder::ThreadSkiaMetalContext
101
- .commandQueue commandBuffer]);
90
+ id<MTLCommandBuffer> commandBuffer([_context->commandQueue commandBuffer]);
102
91
  [commandBuffer presentDrawable:_currentDrawable];
103
92
  [commandBuffer commit];
104
93
  _skSurface = nullptr;
105
94
  }
106
95
 
96
+ void resize(int width, int height) override { _skSurface = nullptr; }
97
+
98
+ int getWidth() override { return _layer.frame.size.width; };
99
+
100
+ int getHeight() override { return _layer.frame.size.height; };
101
+
107
102
  private:
103
+ SkiaMetalContext *_context;
108
104
  sk_sp<SkSurface> _skSurface = nullptr;
109
105
  #pragma clang diagnostic push
110
106
  #pragma clang diagnostic ignored "-Wunguarded-availability-new"
@@ -21,8 +21,6 @@
21
21
 
22
22
  #pragma clang diagnostic pop
23
23
 
24
- thread_local SkiaMetalContext ThreadContextHolder::ThreadSkiaMetalContext;
25
-
26
24
  struct OffscreenRenderContext {
27
25
  id<MTLTexture> texture;
28
26
 
@@ -42,43 +40,14 @@ struct OffscreenRenderContext {
42
40
  }
43
41
  };
44
42
 
45
- id<MTLDevice> SkiaMetalSurfaceFactory::device = MTLCreateSystemDefaultDevice();
46
-
47
- bool SkiaMetalSurfaceFactory::createSkiaDirectContextIfNecessary(
48
- SkiaMetalContext *skiaMetalContext) {
49
- if (skiaMetalContext->skContext == nullptr) {
50
- skiaMetalContext->commandQueue =
51
- id<MTLCommandQueue>(CFRetain((GrMTLHandle)[device newCommandQueue]));
52
-
53
- GrMtlBackendContext backendContext = {};
54
- backendContext.fDevice.reset((__bridge void *)device);
55
- backendContext.fQueue.reset(
56
- (__bridge void *)skiaMetalContext->commandQueue);
57
- GrContextOptions grContextOptions; // set different options here.
58
-
59
- // Create the Skia Direct Context
60
- skiaMetalContext->skContext = GrDirectContexts::MakeMetal(backendContext);
61
- if (skiaMetalContext->skContext == nullptr) {
62
- RNSkia::RNSkLogger::logToConsole("Couldn't create a Skia Metal Context");
63
- return false;
64
- }
65
- }
66
- return true;
67
- }
68
-
69
- std::shared_ptr<RNSkia::SkiaContext>
70
- SkiaMetalSurfaceFactory::makeContext(CALayer *texture, int width, int height) {
71
- return std::make_shared<IOSSkiaContext>(texture, width, height);
43
+ std::unique_ptr<RNSkia::WindowContext>
44
+ SkiaMetalSurfaceFactory::makeContext(SkiaMetalContext *context,
45
+ CALayer *texture, int width, int height) {
46
+ return std::make_unique<IOSSkiaContext>(context, texture, width, height);
72
47
  }
73
48
 
74
- sk_sp<SkSurface>
75
- SkiaMetalSurfaceFactory::makeWindowedSurface(id<MTLTexture> texture, int width,
76
- int height) {
77
- // Get render context for current thread
78
- if (!SkiaMetalSurfaceFactory::createSkiaDirectContextIfNecessary(
79
- &ThreadContextHolder::ThreadSkiaMetalContext)) {
80
- return nullptr;
81
- }
49
+ sk_sp<SkSurface> SkiaMetalSurfaceFactory::makeWindowedSurface(
50
+ SkiaMetalContext *context, id<MTLTexture> texture, int width, int height) {
82
51
  GrMtlTextureInfo fbInfo;
83
52
  fbInfo.fTexture.retain((__bridge void *)texture);
84
53
 
@@ -86,8 +55,8 @@ SkiaMetalSurfaceFactory::makeWindowedSurface(id<MTLTexture> texture, int width,
86
55
  GrBackendRenderTargets::MakeMtl(width, height, fbInfo);
87
56
 
88
57
  auto skSurface = SkSurfaces::WrapBackendRenderTarget(
89
- ThreadContextHolder::ThreadSkiaMetalContext.skContext.get(), backendRT,
90
- kTopLeft_GrSurfaceOrigin, kBGRA_8888_SkColorType, nullptr, nullptr);
58
+ context->skContext.get(), backendRT, kTopLeft_GrSurfaceOrigin,
59
+ kBGRA_8888_SkColorType, nullptr, nullptr);
91
60
 
92
61
  if (skSurface == nullptr || skSurface->getCanvas() == nullptr) {
93
62
  RNSkia::RNSkLogger::logToConsole(
@@ -97,15 +66,11 @@ SkiaMetalSurfaceFactory::makeWindowedSurface(id<MTLTexture> texture, int width,
97
66
  return skSurface;
98
67
  }
99
68
 
100
- sk_sp<SkSurface> SkiaMetalSurfaceFactory::makeOffscreenSurface(int width,
101
- int height) {
102
- if (!SkiaMetalSurfaceFactory::createSkiaDirectContextIfNecessary(
103
- &ThreadContextHolder::ThreadSkiaMetalContext)) {
104
- return nullptr;
105
- }
106
- auto ctx = new OffscreenRenderContext(
107
- device, ThreadContextHolder::ThreadSkiaMetalContext.skContext,
108
- ThreadContextHolder::ThreadSkiaMetalContext.commandQueue, width, height);
69
+ sk_sp<SkSurface> SkiaMetalSurfaceFactory::makeOffscreenSurface(
70
+ id<MTLDevice> device, SkiaMetalContext *context, int width, int height) {
71
+
72
+ auto ctx = new OffscreenRenderContext(device, context->skContext,
73
+ context->commandQueue, width, height);
109
74
 
110
75
  // Create a GrBackendTexture from the Metal texture
111
76
  GrMtlTextureInfo info;
@@ -115,34 +80,27 @@ sk_sp<SkSurface> SkiaMetalSurfaceFactory::makeOffscreenSurface(int width,
115
80
 
116
81
  // Create a SkSurface from the GrBackendTexture
117
82
  auto surface = SkSurfaces::WrapBackendTexture(
118
- ThreadContextHolder::ThreadSkiaMetalContext.skContext.get(),
119
- backendTexture, kTopLeft_GrSurfaceOrigin, 0, kBGRA_8888_SkColorType,
120
- nullptr, nullptr,
83
+ context->skContext.get(), backendTexture, kTopLeft_GrSurfaceOrigin, 0,
84
+ kBGRA_8888_SkColorType, nullptr, nullptr,
121
85
  [](void *addr) { delete (OffscreenRenderContext *)addr; }, ctx);
122
86
 
123
87
  return surface;
124
88
  }
125
89
 
126
90
  sk_sp<SkImage> SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer(
127
- CVPixelBufferRef pixelBuffer) {
128
- if (!SkiaMetalSurfaceFactory::createSkiaDirectContextIfNecessary(
129
- &ThreadContextHolder::ThreadSkiaMetalContext)) [[unlikely]] {
130
- throw std::runtime_error("Failed to create Skia Context for this Thread!");
131
- }
132
- const SkiaMetalContext &context = ThreadContextHolder::ThreadSkiaMetalContext;
133
-
91
+ SkiaMetalContext *context, CVPixelBufferRef pixelBuffer) {
134
92
  SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat format =
135
93
  SkiaCVPixelBufferUtils::getCVPixelBufferBaseFormat(pixelBuffer);
136
94
  switch (format) {
137
95
  case SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat::rgb: {
138
96
  // CVPixelBuffer is in any RGB format, single-plane
139
97
  return SkiaCVPixelBufferUtils::RGB::makeSkImageFromCVPixelBuffer(
140
- context.skContext.get(), pixelBuffer);
98
+ context->skContext.get(), pixelBuffer);
141
99
  }
142
100
  case SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat::yuv: {
143
101
  // CVPixelBuffer is in any YUV format, multi-plane
144
102
  return SkiaCVPixelBufferUtils::YUV::makeSkImageFromCVPixelBuffer(
145
- context.skContext.get(), pixelBuffer);
103
+ context->skContext.get(), pixelBuffer);
146
104
  }
147
105
  default:
148
106
  [[unlikely]] {
@@ -14,8 +14,6 @@
14
14
  #import <React/RCTViewComponentView.h>
15
15
  #endif // RCT_NEW_ARCH_ENABLED
16
16
 
17
- class RNSkiOSJsView;
18
-
19
17
  @interface SkiaUIView :
20
18
  #if RCT_NEW_ARCH_ENABLED
21
19
  RCTViewComponentView
@@ -34,14 +34,7 @@
34
34
  UIGraphicsImageRendererFormat *format =
35
35
  [UIGraphicsImageRendererFormat defaultFormat];
36
36
  format.opaque = NO;
37
-
38
- // Explicitly ask for the standard format to get ARGB 32bits and not 64bits.
39
- if (@available(iOS 12.0, *)) {
40
- format.preferredRange = UIGraphicsImageRendererFormatRangeStandard;
41
- } else {
42
- // Fallback on earlier versions
43
- format.prefersExtendedRange = false;
44
- }
37
+ format.preferredRange = UIGraphicsImageRendererFormatRangeStandard;
45
38
 
46
39
  UIGraphicsImageRenderer *renderer =
47
40
  [[UIGraphicsImageRenderer alloc] initWithSize:size format:format];
@@ -25,7 +25,10 @@ const WithSkiaWeb = ({
25
25
  console.warn("<WithSkiaWeb /> is only necessary on web. Consider not using on native.");
26
26
  }
27
27
  return getComponent();
28
- }), [getComponent, opts]);
28
+ }),
29
+ // We we to run this only once.
30
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31
+ []);
29
32
  return /*#__PURE__*/_react.default.createElement(_react.Suspense, {
30
33
  fallback: fallback !== null && fallback !== void 0 ? fallback : null
31
34
  }, /*#__PURE__*/_react.default.createElement(Inner, componentProps));
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_Platform","_LoadSkiaWeb","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","WithSkiaWeb","getComponent","fallback","opts","componentProps","Inner","useMemo","lazy","Platform","OS","LoadSkiaWeb","console","warn","createElement","Suspense","exports"],"sources":["WithSkiaWeb.tsx"],"sourcesContent":["import type { ComponentProps, ComponentType } from \"react\";\nimport React, { useMemo, lazy, Suspense } from \"react\";\n\nimport { Platform } from \"../Platform\";\n\nimport { LoadSkiaWeb } from \"./LoadSkiaWeb\";\n\ntype NonOptionalKeys<T> = {\n [k in keyof T]-?: undefined extends T[k] ? never : k;\n}[keyof T];\n\ntype WithSkiaProps<TProps> = {\n fallback?: ComponentProps<typeof Suspense>[\"fallback\"];\n getComponent: () => Promise<{ default: ComponentType<TProps> }>;\n opts?: Parameters<typeof LoadSkiaWeb>[0];\n} & (NonOptionalKeys<TProps> extends never\n ? {\n componentProps?: TProps;\n }\n : {\n componentProps: TProps;\n });\n\nexport const WithSkiaWeb = <TProps extends object>({\n getComponent,\n fallback,\n opts,\n componentProps,\n}: WithSkiaProps<TProps>) => {\n const Inner = useMemo(\n // TODO: investigate\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (): any =>\n lazy(async () => {\n if (Platform.OS === \"web\") {\n await LoadSkiaWeb(opts);\n } else {\n console.warn(\n \"<WithSkiaWeb /> is only necessary on web. Consider not using on native.\"\n );\n }\n return getComponent();\n }),\n [getComponent, opts]\n );\n return (\n <Suspense fallback={fallback ?? null}>\n <Inner {...componentProps} />\n </Suspense>\n );\n};\n"],"mappings":";;;;;;AACA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AAEA,IAAAC,SAAA,GAAAD,OAAA;AAEA,IAAAE,YAAA,GAAAF,OAAA;AAA4C,SAAAG,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAL,wBAAAK,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,OAAAC,cAAA,CAAAC,IAAA,CAAAhB,CAAA,EAAAc,CAAA,SAAAG,CAAA,GAAAP,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAG,CAAA,KAAAA,CAAA,CAAAV,GAAA,IAAAU,CAAA,CAAAC,GAAA,IAAAP,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAG,CAAA,IAAAT,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAe,GAAA,CAAAlB,CAAA,EAAAQ,CAAA,GAAAA,CAAA;AAkBrC,MAAMW,WAAW,GAAGA,CAAwB;EACjDC,YAAY;EACZC,QAAQ;EACRC,IAAI;EACJC;AACqB,CAAC,KAAK;EAC3B,MAAMC,KAAK,GAAG,IAAAC,cAAO;EACnB;EACA;EACA,mBACE,IAAAC,WAAI,EAAC,YAAY;IACf,IAAIC,kBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzB,MAAM,IAAAC,wBAAW,EAACP,IAAI,CAAC;IACzB,CAAC,MAAM;MACLQ,OAAO,CAACC,IAAI,CACV,yEACF,CAAC;IACH;IACA,OAAOX,YAAY,CAAC,CAAC;EACvB,CAAC,CAAC,EACJ,CAACA,YAAY,EAAEE,IAAI,CACrB,CAAC;EACD,oBACE5B,MAAA,CAAAW,OAAA,CAAA2B,aAAA,CAACtC,MAAA,CAAAuC,QAAQ;IAACZ,QAAQ,EAAEA,QAAQ,aAARA,QAAQ,cAARA,QAAQ,GAAI;EAAK,gBACnC3B,MAAA,CAAAW,OAAA,CAAA2B,aAAA,CAACR,KAAK,EAAKD,cAAiB,CACpB,CAAC;AAEf,CAAC;AAACW,OAAA,CAAAf,WAAA,GAAAA,WAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_Platform","_LoadSkiaWeb","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","WithSkiaWeb","getComponent","fallback","opts","componentProps","Inner","useMemo","lazy","Platform","OS","LoadSkiaWeb","console","warn","createElement","Suspense","exports"],"sources":["WithSkiaWeb.tsx"],"sourcesContent":["import type { ComponentProps, ComponentType } from \"react\";\nimport React, { useMemo, lazy, Suspense } from \"react\";\n\nimport { Platform } from \"../Platform\";\n\nimport { LoadSkiaWeb } from \"./LoadSkiaWeb\";\n\ntype NonOptionalKeys<T> = {\n [k in keyof T]-?: undefined extends T[k] ? never : k;\n}[keyof T];\n\ntype WithSkiaProps<TProps> = {\n fallback?: ComponentProps<typeof Suspense>[\"fallback\"];\n getComponent: () => Promise<{ default: ComponentType<TProps> }>;\n opts?: Parameters<typeof LoadSkiaWeb>[0];\n} & (NonOptionalKeys<TProps> extends never\n ? {\n componentProps?: TProps;\n }\n : {\n componentProps: TProps;\n });\n\nexport const WithSkiaWeb = <TProps extends object>({\n getComponent,\n fallback,\n opts,\n componentProps,\n}: WithSkiaProps<TProps>) => {\n const Inner = useMemo(\n // TODO: investigate\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (): any =>\n lazy(async () => {\n if (Platform.OS === \"web\") {\n await LoadSkiaWeb(opts);\n } else {\n console.warn(\n \"<WithSkiaWeb /> is only necessary on web. Consider not using on native.\"\n );\n }\n return getComponent();\n }),\n // We we to run this only once.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n return (\n <Suspense fallback={fallback ?? null}>\n <Inner {...componentProps} />\n </Suspense>\n );\n};\n"],"mappings":";;;;;;AACA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AAEA,IAAAC,SAAA,GAAAD,OAAA;AAEA,IAAAE,YAAA,GAAAF,OAAA;AAA4C,SAAAG,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAL,wBAAAK,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,OAAAC,cAAA,CAAAC,IAAA,CAAAhB,CAAA,EAAAc,CAAA,SAAAG,CAAA,GAAAP,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAG,CAAA,KAAAA,CAAA,CAAAV,GAAA,IAAAU,CAAA,CAAAC,GAAA,IAAAP,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAG,CAAA,IAAAT,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAe,GAAA,CAAAlB,CAAA,EAAAQ,CAAA,GAAAA,CAAA;AAkBrC,MAAMW,WAAW,GAAGA,CAAwB;EACjDC,YAAY;EACZC,QAAQ;EACRC,IAAI;EACJC;AACqB,CAAC,KAAK;EAC3B,MAAMC,KAAK,GAAG,IAAAC,cAAO;EACnB;EACA;EACA,mBACE,IAAAC,WAAI,EAAC,YAAY;IACf,IAAIC,kBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;MACzB,MAAM,IAAAC,wBAAW,EAACP,IAAI,CAAC;IACzB,CAAC,MAAM;MACLQ,OAAO,CAACC,IAAI,CACV,yEACF,CAAC;IACH;IACA,OAAOX,YAAY,CAAC,CAAC;EACvB,CAAC,CAAC;EACJ;EACA;EACA,EACF,CAAC;EACD,oBACE1B,MAAA,CAAAW,OAAA,CAAA2B,aAAA,CAACtC,MAAA,CAAAuC,QAAQ;IAACZ,QAAQ,EAAEA,QAAQ,aAARA,QAAQ,cAARA,QAAQ,GAAI;EAAK,gBACnC3B,MAAA,CAAAW,OAAA,CAAA2B,aAAA,CAACR,KAAK,EAAKD,cAAiB,CACpB,CAAC;AAEf,CAAC;AAACW,OAAA,CAAAf,WAAA,GAAAA,WAAA","ignoreList":[]}
@@ -17,7 +17,10 @@ export const WithSkiaWeb = ({
17
17
  console.warn("<WithSkiaWeb /> is only necessary on web. Consider not using on native.");
18
18
  }
19
19
  return getComponent();
20
- }), [getComponent, opts]);
20
+ }),
21
+ // We we to run this only once.
22
+ // eslint-disable-next-line react-hooks/exhaustive-deps
23
+ []);
21
24
  return /*#__PURE__*/React.createElement(Suspense, {
22
25
  fallback: fallback !== null && fallback !== void 0 ? fallback : null
23
26
  }, /*#__PURE__*/React.createElement(Inner, componentProps));