@shopify/react-native-skia 1.6.0 → 1.7.1

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 (109) hide show
  1. package/android/cpp/jni/include/JniSkiaBaseView.h +2 -3
  2. package/android/cpp/jni/include/JniSkiaManager.h +2 -2
  3. package/android/cpp/rnskia-android/GrAHardwareBufferUtils.cpp +14 -14
  4. package/android/cpp/rnskia-android/MainThreadDispatcher.h +4 -6
  5. package/android/cpp/rnskia-android/OpenGLContext.h +24 -10
  6. package/android/cpp/rnskia-android/OpenGLWindowContext.h +3 -3
  7. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +64 -8
  8. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +1 -1
  9. package/android/cpp/rnskia-android/RNSkAndroidVideo.h +1 -1
  10. package/android/cpp/rnskia-android/RNSkAndroidView.h +0 -4
  11. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +3 -3
  12. package/android/cpp/rnskia-android/gl/Display.h +2 -0
  13. package/cpp/api/JsiSkApi.h +1 -1
  14. package/cpp/api/JsiSkCanvas.h +1 -1
  15. package/cpp/api/JsiSkColor.h +2 -2
  16. package/cpp/api/JsiSkContourMeasure.h +1 -5
  17. package/cpp/api/JsiSkImage.h +11 -0
  18. package/cpp/api/JsiSkImageFactory.h +14 -0
  19. package/cpp/api/JsiSkPicture.h +2 -0
  20. package/cpp/api/JsiSkSurface.h +7 -0
  21. package/cpp/api/JsiTextureInfo.h +53 -0
  22. package/cpp/api/third_party/CSSColorParser.h +1 -1
  23. package/cpp/api/third_party/base64.cpp +4 -4
  24. package/cpp/jsi/ViewProperty.h +48 -0
  25. package/cpp/rnskia/RNSkDomView.h +4 -7
  26. package/cpp/rnskia/RNSkJsiViewApi.h +3 -3
  27. package/cpp/rnskia/RNSkManager.cpp +1 -1
  28. package/cpp/rnskia/RNSkPictureView.h +8 -18
  29. package/cpp/rnskia/RNSkPlatformContext.h +18 -13
  30. package/cpp/rnskia/RNSkView.h +2 -8
  31. package/ios/RNSkia-iOS/MetalContext.h +101 -15
  32. package/ios/RNSkia-iOS/MetalContext.mm +9 -8
  33. package/ios/RNSkia-iOS/MetalWindowContext.h +39 -0
  34. package/ios/RNSkia-iOS/MetalWindowContext.mm +60 -0
  35. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +13 -29
  36. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +88 -2
  37. package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +17 -6
  38. package/ios/RNSkia-iOS/SkiaDomView.mm +3 -3
  39. package/ios/RNSkia-iOS/SkiaDomViewManager.mm +2 -1
  40. package/ios/RNSkia-iOS/SkiaManager.h +6 -0
  41. package/ios/RNSkia-iOS/SkiaManager.mm +18 -2
  42. package/ios/RNSkia-iOS/SkiaPictureView.mm +3 -3
  43. package/ios/RNSkia-iOS/SkiaPictureViewManager.mm +2 -1
  44. package/ios/RNSkia-iOS/SkiaUIView.h +0 -1
  45. package/ios/RNSkia-iOS/SkiaUIView.mm +18 -22
  46. package/lib/commonjs/skia/types/Image/Image.d.ts +10 -0
  47. package/lib/commonjs/skia/types/Image/Image.js.map +1 -1
  48. package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +18 -0
  49. package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
  50. package/lib/commonjs/skia/types/Matrix4.d.ts +6 -0
  51. package/lib/commonjs/skia/types/Matrix4.js +69 -1
  52. package/lib/commonjs/skia/types/Matrix4.js.map +1 -1
  53. package/lib/commonjs/skia/types/Surface/Surface.d.ts +11 -0
  54. package/lib/commonjs/skia/types/Surface/Surface.js.map +1 -1
  55. package/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -0
  56. package/lib/commonjs/skia/web/JsiSkImage.js +4 -0
  57. package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
  58. package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
  59. package/lib/commonjs/skia/web/JsiSkImageFactory.js +3 -0
  60. package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
  61. package/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -0
  62. package/lib/commonjs/skia/web/JsiSkSurface.js +4 -0
  63. package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
  64. package/lib/module/skia/types/Image/Image.d.ts +10 -0
  65. package/lib/module/skia/types/Image/Image.js.map +1 -1
  66. package/lib/module/skia/types/Image/ImageFactory.d.ts +18 -0
  67. package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
  68. package/lib/module/skia/types/Matrix4.d.ts +6 -0
  69. package/lib/module/skia/types/Matrix4.js +67 -0
  70. package/lib/module/skia/types/Matrix4.js.map +1 -1
  71. package/lib/module/skia/types/Surface/Surface.d.ts +11 -0
  72. package/lib/module/skia/types/Surface/Surface.js.map +1 -1
  73. package/lib/module/skia/web/JsiSkImage.d.ts +1 -0
  74. package/lib/module/skia/web/JsiSkImage.js +4 -0
  75. package/lib/module/skia/web/JsiSkImage.js.map +1 -1
  76. package/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
  77. package/lib/module/skia/web/JsiSkImageFactory.js +3 -0
  78. package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
  79. package/lib/module/skia/web/JsiSkSurface.d.ts +1 -0
  80. package/lib/module/skia/web/JsiSkSurface.js +4 -0
  81. package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
  82. package/lib/typescript/lib/commonjs/skia/types/Matrix4.d.ts +6 -0
  83. package/lib/typescript/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -0
  84. package/lib/typescript/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
  85. package/lib/typescript/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -0
  86. package/lib/typescript/lib/module/mock/index.d.ts +1 -0
  87. package/lib/typescript/lib/module/skia/types/Matrix4.d.ts +1 -0
  88. package/lib/typescript/lib/module/skia/web/JsiSkImage.d.ts +1 -0
  89. package/lib/typescript/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
  90. package/lib/typescript/lib/module/skia/web/JsiSkSurface.d.ts +1 -0
  91. package/lib/typescript/src/skia/types/Image/Image.d.ts +10 -0
  92. package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +18 -0
  93. package/lib/typescript/src/skia/types/Matrix4.d.ts +6 -0
  94. package/lib/typescript/src/skia/types/Surface/Surface.d.ts +11 -0
  95. package/lib/typescript/src/skia/web/JsiSkImage.d.ts +1 -0
  96. package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +1 -0
  97. package/lib/typescript/src/skia/web/JsiSkSurface.d.ts +1 -0
  98. package/package.json +1 -1
  99. package/src/renderer/__tests__/e2e/Matrix4.spec.tsx +93 -0
  100. package/src/skia/types/Image/Image.ts +11 -0
  101. package/src/skia/types/Image/ImageFactory.ts +24 -0
  102. package/src/skia/types/Matrix4.ts +101 -0
  103. package/src/skia/types/Surface/Surface.ts +12 -0
  104. package/src/skia/web/JsiSkImage.ts +5 -0
  105. package/src/skia/web/JsiSkImageFactory.ts +4 -0
  106. package/src/skia/web/JsiSkSurface.ts +5 -0
  107. package/cpp/jsi/JsiValueWrapper.h +0 -164
  108. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +0 -128
  109. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +0 -92
@@ -34,7 +34,7 @@
34
34
  namespace CSSColorParser {
35
35
 
36
36
  struct Color {
37
- inline Color() {}
37
+ inline Color() = default;
38
38
  inline Color(unsigned char r_, unsigned char g_, unsigned char b_, float a_)
39
39
  : r(r_), g(g_), b(b_), a(a_ > 1 ? 1
40
40
  : a_ < 0 ? 0
@@ -26,8 +26,8 @@ namespace RNSkia {
26
26
 
27
27
  Base64::Error Base64::Decode(const void *srcv, size_t srcLength, void *dstv,
28
28
  size_t *dstLength) {
29
- const unsigned char *src = static_cast<const unsigned char *>(srcv);
30
- unsigned char *dst = static_cast<unsigned char *>(dstv);
29
+ auto *src = static_cast<const unsigned char *>(srcv);
30
+ auto *dst = static_cast<unsigned char *>(dstv);
31
31
 
32
32
  int i = 0;
33
33
  bool padTwo = false;
@@ -112,8 +112,8 @@ Base64::Error Base64::Decode(const void *srcv, size_t srcLength, void *dstv,
112
112
  }
113
113
 
114
114
  size_t Base64::Encode(const void *srcv, size_t length, void *dstv) {
115
- const unsigned char *src = static_cast<const unsigned char *>(srcv);
116
- unsigned char *dst = static_cast<unsigned char *>(dstv);
115
+ auto *src = static_cast<const unsigned char *>(srcv);
116
+ auto *dst = static_cast<unsigned char *>(dstv);
117
117
 
118
118
  const char *encode = kDefaultEncode;
119
119
  if (dst) {
@@ -0,0 +1,48 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <memory>
5
+ #include <string>
6
+
7
+ #include "JsiDomRenderNode.h"
8
+ #include "JsiSkPicture.h"
9
+
10
+ namespace RNJsi {
11
+ namespace jsi = facebook::jsi;
12
+
13
+ class ViewProperty {
14
+ public:
15
+ ViewProperty(jsi::Runtime &runtime, const jsi::Value &value) {
16
+ if (value.isObject()) {
17
+ auto object = value.asObject(runtime);
18
+ if (object.isHostObject(runtime)) {
19
+ auto hostObject = object.asHostObject(runtime);
20
+ auto dom =
21
+ std::dynamic_pointer_cast<RNSkia::JsiDomRenderNode>(hostObject);
22
+ if (dom) {
23
+ _value = dom;
24
+ } else {
25
+ auto jsiPicture =
26
+ std::dynamic_pointer_cast<RNSkia::JsiSkPicture>(hostObject);
27
+ if (jsiPicture) {
28
+ _value = jsiPicture->getObject();
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ bool isNull() { return std::holds_alternative<nullptr_t>(_value); }
36
+
37
+ std::shared_ptr<RNSkia::JsiDomRenderNode> getDomRenderNode() {
38
+ return std::get<std::shared_ptr<RNSkia::JsiDomRenderNode>>(_value);
39
+ }
40
+
41
+ sk_sp<SkPicture> getPicture() { return std::get<sk_sp<SkPicture>>(_value); }
42
+
43
+ private:
44
+ std::variant<nullptr_t, sk_sp<SkPicture>,
45
+ std::shared_ptr<RNSkia::JsiDomRenderNode>>
46
+ _value = nullptr;
47
+ };
48
+ } // namespace RNJsi
@@ -9,8 +9,8 @@
9
9
 
10
10
  #include <jsi/jsi.h>
11
11
 
12
- #include "JsiValueWrapper.h"
13
12
  #include "RNSkView.h"
13
+ #include "ViewProperty.h"
14
14
 
15
15
  #include "JsiDomRenderNode.h"
16
16
  #include "RNSkLog.h"
@@ -75,20 +75,17 @@ public:
75
75
  std::bind(&RNSkView::requestRedraw, this), context)) {}
76
76
 
77
77
  void setJsiProperties(
78
- std::unordered_map<std::string, JsiValueWrapper> &props) override {
79
-
80
- RNSkView::setJsiProperties(props);
78
+ std::unordered_map<std::string, ViewProperty> &props) override {
81
79
 
82
80
  for (auto &prop : props) {
83
81
  if (prop.first == "root") {
84
82
  // Save root
85
- if (prop.second.isUndefined() || prop.second.isNull()) {
83
+ if (prop.second.isNull()) {
86
84
  std::static_pointer_cast<RNSkDomRenderer>(getRenderer())
87
85
  ->setRoot(nullptr);
88
86
  } else {
89
87
  std::static_pointer_cast<RNSkDomRenderer>(getRenderer())
90
- ->setRoot(std::dynamic_pointer_cast<JsiDomRenderNode>(
91
- prop.second.getAsHostObject()));
88
+ ->setRoot(prop.second.getDomRenderNode());
92
89
  }
93
90
 
94
91
  // Request redraw
@@ -9,9 +9,9 @@
9
9
  #include <vector>
10
10
 
11
11
  #include "JsiHostObject.h"
12
- #include "JsiValueWrapper.h"
13
12
  #include "RNSkPlatformContext.h"
14
13
  #include "RNSkView.h"
14
+ #include "ViewProperty.h"
15
15
  #include <jsi/jsi.h>
16
16
 
17
17
  namespace RNSkia {
@@ -20,7 +20,7 @@ namespace jsi = facebook::jsi;
20
20
  using RNSkViewInfo = struct RNSkViewInfo {
21
21
  RNSkViewInfo() { view = nullptr; }
22
22
  std::shared_ptr<RNSkView> view;
23
- std::unordered_map<std::string, RNJsi::JsiValueWrapper> props;
23
+ std::unordered_map<std::string, RNJsi::ViewProperty> props;
24
24
  };
25
25
 
26
26
  class RNSkJsiViewApi : public RNJsi::JsiHostObject,
@@ -57,7 +57,7 @@ public:
57
57
  auto info = getEnsuredViewInfo(nativeId);
58
58
 
59
59
  info->props.insert_or_assign(arguments[1].asString(runtime).utf8(runtime),
60
- RNJsi::JsiValueWrapper(runtime, arguments[2]));
60
+ RNJsi::ViewProperty(runtime, arguments[2]));
61
61
 
62
62
  // Now let's see if we have a view that we can update
63
63
  if (info->view != nullptr) {
@@ -69,7 +69,7 @@ void RNSkManager::installBindings() {
69
69
  // Create the API objects and install it on the global object in the
70
70
  // provided runtime.
71
71
 
72
- auto skiaApi = std::make_shared<JsiSkApi>(*_jsRuntime, _platformContext);
72
+ auto skiaApi = std::make_shared<JsiSkApi>(_platformContext);
73
73
  _jsRuntime->global().setProperty(
74
74
  *_jsRuntime, "SkiaApi",
75
75
  jsi::Object::createFromHostObject(*_jsRuntime, std::move(skiaApi)));
@@ -9,8 +9,8 @@
9
9
 
10
10
  #include <jsi/jsi.h>
11
11
 
12
- #include "JsiValueWrapper.h"
13
12
  #include "RNSkView.h"
13
+ #include "ViewProperty.h"
14
14
 
15
15
  #include "JsiSkPicture.h"
16
16
  #include "RNSkLog.h"
@@ -40,19 +40,16 @@ class RNSkPictureRenderer
40
40
  public:
41
41
  RNSkPictureRenderer(std::function<void()> requestRedraw,
42
42
  std::shared_ptr<RNSkPlatformContext> context)
43
- : RNSkRenderer(std::move(requestRedraw)), _platformContext(std::move(context)) {}
43
+ : RNSkRenderer(std::move(requestRedraw)),
44
+ _platformContext(std::move(context)) {}
44
45
 
45
46
  void
46
47
  renderImmediate(std::shared_ptr<RNSkCanvasProvider> canvasProvider) override {
47
48
  performDraw(canvasProvider);
48
49
  }
49
50
 
50
- void setPicture(std::shared_ptr<jsi::HostObject> picture) {
51
- if (picture == nullptr) {
52
- _picture = nullptr;
53
- } else {
54
- _picture = std::dynamic_pointer_cast<JsiSkPicture>(picture)->getObject();
55
- }
51
+ void setPicture(sk_sp<SkPicture> picture) {
52
+ _picture = picture;
56
53
  _requestRedraw();
57
54
  }
58
55
 
@@ -88,27 +85,20 @@ public:
88
85
  std::bind(&RNSkPictureView::requestRedraw, this), context)) {}
89
86
 
90
87
  void setJsiProperties(
91
- std::unordered_map<std::string, RNJsi::JsiValueWrapper> &props) override {
92
-
93
- RNSkView::setJsiProperties(props);
88
+ std::unordered_map<std::string, RNJsi::ViewProperty> &props) override {
94
89
 
95
90
  for (auto &prop : props) {
96
91
  if (prop.first == "picture") {
97
- if (prop.second.isUndefinedOrNull()) {
92
+ if (prop.second.isNull()) {
98
93
  // Clear picture
99
94
  std::static_pointer_cast<RNSkPictureRenderer>(getRenderer())
100
95
  ->setPicture(nullptr);
101
96
  continue;
102
- } else if (prop.second.getType() !=
103
- RNJsi::JsiWrapperValueType::HostObject) {
104
- // We expect a function for the picture custom property
105
- throw std::runtime_error(
106
- "Expected an object for the picture custom property.");
107
97
  }
108
98
 
109
99
  // Save picture
110
100
  std::static_pointer_cast<RNSkPictureRenderer>(getRenderer())
111
- ->setPicture(prop.second.getAsHostObject());
101
+ ->setPicture(prop.second.getPicture());
112
102
  }
113
103
  }
114
104
  }
@@ -23,25 +23,28 @@
23
23
 
24
24
  #pragma clang diagnostic pop
25
25
 
26
- #include <jsi/jsi.h>
27
-
28
26
  #include <ReactCommon/CallInvoker.h>
29
27
 
30
28
  namespace RNSkia {
31
29
 
32
- namespace jsi = facebook::jsi;
33
30
  namespace react = facebook::react;
34
31
 
32
+ struct TextureInfo {
33
+ const void *mtlTexture = nullptr;
34
+ unsigned int glTarget = 0;
35
+ unsigned int glID = 0;
36
+ unsigned int glFormat = 0;
37
+ bool glProtected = false;
38
+ };
39
+
35
40
  class RNSkPlatformContext {
36
41
  public:
37
42
  /**
38
43
  * Constructor
39
44
  */
40
- RNSkPlatformContext(jsi::Runtime *runtime,
41
- std::shared_ptr<react::CallInvoker> callInvoker,
45
+ RNSkPlatformContext(std::shared_ptr<react::CallInvoker> callInvoker,
42
46
  float pixelDensity)
43
- : _pixelDensity(pixelDensity), _jsRuntime(runtime),
44
- _callInvoker(callInvoker) {}
47
+ : _pixelDensity(pixelDensity), _callInvoker(callInvoker) {}
45
48
 
46
49
  virtual ~RNSkPlatformContext() = default;
47
50
 
@@ -65,11 +68,6 @@ public:
65
68
  */
66
69
  virtual sk_sp<SkImage> takeScreenshotFromViewTag(size_t tag) = 0;
67
70
 
68
- /**
69
- Returns the javascript runtime
70
- */
71
- jsi::Runtime *getJsRuntime() { return _jsRuntime; }
72
-
73
71
  /**
74
72
  * Returns an SkStream wrapping the require uri provided.
75
73
  * @param sourceUri Uri for the resource to load as a string
@@ -107,6 +105,10 @@ public:
107
105
  */
108
106
  virtual sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) = 0;
109
107
 
108
+ virtual sk_sp<SkImage>
109
+ makeImageFromNativeTexture(const TextureInfo &textureInfo, int width,
110
+ int height, bool mipMapped) = 0;
111
+
110
112
  #if !defined(SK_GRAPHITE)
111
113
  virtual GrDirectContext *getDirectContext() = 0;
112
114
  #endif
@@ -115,6 +117,10 @@ public:
115
117
 
116
118
  virtual uint64_t makeNativeBuffer(sk_sp<SkImage> image) = 0;
117
119
 
120
+ virtual const TextureInfo getTexture(sk_sp<SkSurface> image) = 0;
121
+
122
+ virtual const TextureInfo getTexture(sk_sp<SkImage> image) = 0;
123
+
118
124
  virtual std::shared_ptr<RNSkVideo> createVideo(const std::string &url) = 0;
119
125
 
120
126
  /**
@@ -154,7 +160,6 @@ public:
154
160
 
155
161
  private:
156
162
  float _pixelDensity;
157
- jsi::Runtime *_jsRuntime;
158
163
  std::shared_ptr<react::CallInvoker> _callInvoker;
159
164
  };
160
165
  } // namespace RNSkia
@@ -6,8 +6,8 @@
6
6
  #include <unordered_map>
7
7
  #include <vector>
8
8
 
9
- #include "JsiValueWrapper.h"
10
9
  #include "RNSkPlatformContext.h"
10
+ #include "ViewProperty.h"
11
11
 
12
12
  #include "JsiSkImage.h"
13
13
  #include "JsiSkPoint.h"
@@ -143,14 +143,8 @@ public:
143
143
  */
144
144
  virtual ~RNSkView() {}
145
145
 
146
- /**
147
- Sets custom properties. Custom properties are properties that are set
148
- directly from Javascript without having to go through the async bridge.
149
- */
150
146
  virtual void setJsiProperties(
151
- std::unordered_map<std::string, RNJsi::JsiValueWrapper> &props) {
152
- // Nothing here...
153
- }
147
+ std::unordered_map<std::string, RNJsi::ViewProperty> &props) = 0;
154
148
 
155
149
  void requestRedraw() {
156
150
  if (!_redrawRequested) {
@@ -1,13 +1,64 @@
1
1
  #pragma once
2
2
 
3
- #include "SkiaMetalSurfaceFactory.h"
4
- #include "WindowContext.h"
3
+ #include "MetalWindowContext.h"
4
+ #include "SkiaCVPixelBufferUtils.h"
5
5
 
6
6
  #include "include/core/SkSurface.h"
7
7
 
8
- namespace RNSkia {
9
- class RNSkiOSPlatformContext;
10
- }
8
+ #import <include/gpu/ganesh/GrBackendSurface.h>
9
+ #import <include/gpu/ganesh/GrDirectContext.h>
10
+ #import <include/gpu/ganesh/SkImageGanesh.h>
11
+ #import <include/gpu/ganesh/SkSurfaceGanesh.h>
12
+ #import <include/gpu/ganesh/mtl/GrMtlBackendContext.h>
13
+ #import <include/gpu/ganesh/mtl/GrMtlBackendSurface.h>
14
+ #import <include/gpu/ganesh/mtl/GrMtlDirectContext.h>
15
+ #import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>
16
+
17
+ // namespace RNSkia {
18
+ // class RNSkiOSPlatformContext;
19
+ // }
20
+
21
+ class MetalSharedContext {
22
+ public:
23
+ static MetalSharedContext &getInstance() {
24
+ static MetalSharedContext instance;
25
+ return instance;
26
+ }
27
+
28
+ id<MTLDevice> getDevice() { return _device; }
29
+
30
+ private:
31
+ MetalSharedContext() {
32
+ _device = MTLCreateSystemDefaultDevice();
33
+ if (!_device) {
34
+ throw std::runtime_error("Failed to create Metal device");
35
+ }
36
+ }
37
+
38
+ MetalSharedContext(const MetalSharedContext &) = delete;
39
+ MetalSharedContext &operator=(const MetalSharedContext &) = delete;
40
+
41
+ id<MTLDevice> _device;
42
+ };
43
+
44
+ struct OffscreenRenderContext {
45
+ id<MTLTexture> texture;
46
+
47
+ OffscreenRenderContext(id<MTLDevice> device,
48
+ sk_sp<GrDirectContext> skiaContext,
49
+ id<MTLCommandQueue> commandQueue, int width,
50
+ int height) {
51
+ // Create a Metal texture descriptor
52
+ MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor
53
+ texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
54
+ width:width
55
+ height:height
56
+ mipmapped:NO];
57
+ textureDescriptor.usage =
58
+ MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
59
+ texture = [device newTextureWithDescriptor:textureDescriptor];
60
+ }
61
+ };
11
62
 
12
63
  class MetalContext {
13
64
 
@@ -21,28 +72,63 @@ public:
21
72
  }
22
73
 
23
74
  sk_sp<SkSurface> MakeOffscreen(int width, int height) {
24
- return SkiaMetalSurfaceFactory::makeOffscreenSurface(_device, &_context,
25
- width, height);
75
+ auto device = MetalSharedContext::getInstance().getDevice();
76
+ auto ctx = new OffscreenRenderContext(device, _directContext, _commandQueue,
77
+ width, height);
78
+
79
+ // Create a GrBackendTexture from the Metal texture
80
+ GrMtlTextureInfo info;
81
+ info.fTexture.retain((__bridge void *)ctx->texture);
82
+ GrBackendTexture backendTexture =
83
+ GrBackendTextures::MakeMtl(width, height, skgpu::Mipmapped::kNo, info);
84
+
85
+ // Create a SkSurface from the GrBackendTexture
86
+ auto surface = SkSurfaces::WrapBackendTexture(
87
+ _directContext.get(), backendTexture, kTopLeft_GrSurfaceOrigin, 0,
88
+ kBGRA_8888_SkColorType, nullptr, nullptr,
89
+ [](void *addr) { delete (OffscreenRenderContext *)addr; }, ctx);
90
+
91
+ return surface;
26
92
  }
27
93
 
28
94
  sk_sp<SkImage> MakeImageFromBuffer(void *buffer) {
95
+
29
96
  CVPixelBufferRef sampleBuffer = (CVPixelBufferRef)buffer;
30
- return SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer(&_context,
31
- sampleBuffer);
97
+ SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat format =
98
+ SkiaCVPixelBufferUtils::getCVPixelBufferBaseFormat(sampleBuffer);
99
+ switch (format) {
100
+ case SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat::rgb: {
101
+ // CVPixelBuffer is in any RGB format, single-plane
102
+ return SkiaCVPixelBufferUtils::RGB::makeSkImageFromCVPixelBuffer(
103
+ _directContext.get(), sampleBuffer);
104
+ }
105
+ case SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat::yuv: {
106
+ // CVPixelBuffer is in any YUV format, multi-plane
107
+ return SkiaCVPixelBufferUtils::YUV::makeSkImageFromCVPixelBuffer(
108
+ _directContext.get(), sampleBuffer);
109
+ }
110
+ default:
111
+ [[unlikely]] {
112
+ throw std::runtime_error("Failed to convert NativeBuffer to SkImage - "
113
+ "NativeBuffer has unsupported PixelFormat! " +
114
+ std::to_string(static_cast<int>(format)));
115
+ }
116
+ }
32
117
  }
33
118
 
34
119
  std::unique_ptr<RNSkia::WindowContext> MakeWindow(CALayer *window, int width,
35
120
  int height) {
36
- return SkiaMetalSurfaceFactory::makeContext(&_context, window, width,
37
- height);
121
+ auto device = MetalSharedContext::getInstance().getDevice();
122
+ return std::make_unique<MetalWindowContext>(
123
+ _directContext.get(), device, _commandQueue, window, width, height);
38
124
  }
39
125
 
40
- GrDirectContext *getDirectContext() { return _context.skContext.get(); }
126
+ GrDirectContext *getDirectContext() { return _directContext.get(); }
41
127
 
42
128
  private:
43
- friend class RNSkia::RNSkiOSPlatformContext;
44
- id<MTLDevice> _device;
45
- SkiaMetalContext _context;
129
+ // friend class RNSkia::RNSkiOSPlatformContext;
130
+ id<MTLCommandQueue> _commandQueue = nullptr;
131
+ sk_sp<GrDirectContext> _directContext = nullptr;
46
132
 
47
133
  MetalContext();
48
134
  };
@@ -1,5 +1,7 @@
1
1
  #include "MetalContext.h"
2
2
 
3
+ #include "RNSkLog.h"
4
+
3
5
  #import <MetalKit/MetalKit.h>
4
6
 
5
7
  #pragma clang diagnostic push
@@ -16,18 +18,17 @@
16
18
  #pragma clang diagnostic pop
17
19
 
18
20
  MetalContext::MetalContext() {
19
- _device = MTLCreateSystemDefaultDevice();
20
- _context.commandQueue =
21
- id<MTLCommandQueue>(CFRetain((GrMTLHandle)[_device newCommandQueue]));
22
-
21
+ auto device = MetalSharedContext::getInstance().getDevice();
22
+ _commandQueue =
23
+ id<MTLCommandQueue>(CFRetain((GrMTLHandle)[device newCommandQueue]));
23
24
  GrMtlBackendContext backendContext = {};
24
- backendContext.fDevice.reset((__bridge void *)_device);
25
- backendContext.fQueue.reset((__bridge void *)_context.commandQueue);
25
+ backendContext.fDevice.reset((__bridge void *)device);
26
+ backendContext.fQueue.reset((__bridge void *)_commandQueue);
26
27
  GrContextOptions grContextOptions; // set different options here.
27
28
 
28
29
  // Create the Skia Direct Context
29
- _context.skContext = GrDirectContexts::MakeMetal(backendContext);
30
- if (_context.skContext == nullptr) {
30
+ _directContext = GrDirectContexts::MakeMetal(backendContext);
31
+ if (_directContext == nullptr) {
31
32
  RNSkia::RNSkLogger::logToConsole("Couldn't create a Skia Metal Context");
32
33
  }
33
34
  }
@@ -0,0 +1,39 @@
1
+ #pragma once
2
+
3
+ #import <MetalKit/MetalKit.h>
4
+
5
+ #include "WindowContext.h"
6
+
7
+ class SkiaMetalContext;
8
+
9
+ class MetalWindowContext : public RNSkia::WindowContext {
10
+ public:
11
+ MetalWindowContext(GrDirectContext *directContext, id<MTLDevice> device,
12
+ id<MTLCommandQueue> commandQueue, CALayer *layer,
13
+ int width, int height);
14
+ ~MetalWindowContext() = default;
15
+
16
+ sk_sp<SkSurface> getSurface() override;
17
+
18
+ void present() override;
19
+
20
+ int getWidth() override {
21
+ return _layer.frame.size.width * _layer.contentsScale;
22
+ };
23
+
24
+ int getHeight() override {
25
+ return _layer.frame.size.height * _layer.contentsScale;
26
+ };
27
+
28
+ void resize(int width, int height) override { _skSurface = nullptr; }
29
+
30
+ private:
31
+ GrDirectContext *_directContext;
32
+ id<MTLCommandQueue> _commandQueue;
33
+ sk_sp<SkSurface> _skSurface = nullptr;
34
+ #pragma clang diagnostic push
35
+ #pragma clang diagnostic ignored "-Wunguarded-availability-new"
36
+ CAMetalLayer *_layer;
37
+ #pragma clang diagnostic pop
38
+ id<CAMetalDrawable> _currentDrawable = nil;
39
+ };
@@ -0,0 +1,60 @@
1
+ #include "MetalWindowContext.h"
2
+
3
+ #include "MetalContext.h"
4
+ #include "RNSkLog.h"
5
+
6
+ MetalWindowContext::MetalWindowContext(GrDirectContext *directContext,
7
+ id<MTLDevice> device,
8
+ id<MTLCommandQueue> commandQueue,
9
+ CALayer *layer, int width, int height)
10
+ : _directContext(directContext), _commandQueue(commandQueue) {
11
+ #pragma clang diagnostic push
12
+ #pragma clang diagnostic ignored "-Wunguarded-availability-new"
13
+ _layer = (CAMetalLayer *)layer;
14
+ #pragma clang diagnostic pop
15
+ _layer.framebufferOnly = NO;
16
+ _layer.device = device;
17
+ _layer.opaque = false;
18
+ _layer.contentsScale = [UIScreen mainScreen].scale;
19
+ _layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
20
+ _layer.contentsGravity = kCAGravityBottomLeft;
21
+ _layer.drawableSize = CGSizeMake(width, height);
22
+ }
23
+
24
+ sk_sp<SkSurface> MetalWindowContext::getSurface() {
25
+ if (_skSurface) {
26
+ return _skSurface;
27
+ }
28
+
29
+ // Get the next drawable from the CAMetalLayer
30
+ _currentDrawable = [_layer nextDrawable];
31
+ if (!_currentDrawable) {
32
+ RNSkia::RNSkLogger::logToConsole(
33
+ "Could not retrieve drawable from CAMetalLayer");
34
+ return nullptr;
35
+ }
36
+
37
+ // Get the texture from the drawable
38
+ GrMtlTextureInfo fbInfo;
39
+ fbInfo.fTexture.retain((__bridge void *)_currentDrawable.texture);
40
+
41
+ GrBackendRenderTarget backendRT = GrBackendRenderTargets::MakeMtl(
42
+ _layer.drawableSize.width, _layer.drawableSize.height, fbInfo);
43
+
44
+ _skSurface = SkSurfaces::WrapBackendRenderTarget(
45
+ _directContext, backendRT, kTopLeft_GrSurfaceOrigin,
46
+ kBGRA_8888_SkColorType, nullptr, nullptr);
47
+
48
+ return _skSurface;
49
+ }
50
+
51
+ void MetalWindowContext::present() {
52
+ if (auto dContext = GrAsDirectContext(_skSurface->recordingContext())) {
53
+ dContext->flushAndSubmit();
54
+ }
55
+
56
+ id<MTLCommandBuffer> commandBuffer([_commandQueue commandBuffer]);
57
+ [commandBuffer presentDrawable:_currentDrawable];
58
+ [commandBuffer commit];
59
+ _skSurface = nullptr;
60
+ }
@@ -10,8 +10,6 @@
10
10
  #include "RNSkPlatformContext.h"
11
11
  #include "ViewScreenshotService.h"
12
12
 
13
- #include <jsi/jsi.h>
14
-
15
13
  namespace facebook {
16
14
  namespace react {
17
15
  class CallInvoker;
@@ -20,35 +18,19 @@ class CallInvoker;
20
18
 
21
19
  namespace RNSkia {
22
20
 
23
- namespace jsi = facebook::jsi;
24
-
25
- static void handleNotification(CFNotificationCenterRef center, void *observer,
26
- CFStringRef name, const void *object,
27
- CFDictionaryRef userInfo);
28
-
29
21
  class RNSkiOSPlatformContext : public RNSkPlatformContext {
30
22
  public:
31
23
  RNSkiOSPlatformContext(
32
- jsi::Runtime *runtime, RCTBridge *bridge,
24
+ RCTBridge *bridge,
33
25
  std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker)
34
- : RNSkPlatformContext(runtime, jsCallInvoker,
35
- [[UIScreen mainScreen] scale]) {
36
-
37
- // We need to make sure we invalidate when modules are freed
38
- CFNotificationCenterAddObserver(
39
- CFNotificationCenterGetLocalCenter(), this, &handleNotification,
40
- (__bridge CFStringRef)RCTBridgeWillInvalidateModulesNotification, NULL,
41
- CFNotificationSuspensionBehaviorDeliverImmediately);
26
+ : RNSkPlatformContext(jsCallInvoker, [[UIScreen mainScreen] scale]) {
42
27
 
43
28
  // Create screenshot manager
44
29
  _screenshotService =
45
30
  [[ViewScreenshotService alloc] initWithUiManager:bridge.uiManager];
46
31
  }
47
32
 
48
- ~RNSkiOSPlatformContext() {
49
- CFNotificationCenterRemoveEveryObserver(
50
- CFNotificationCenterGetLocalCenter(), this);
51
- }
33
+ ~RNSkiOSPlatformContext() = default;
52
34
 
53
35
  void runOnMainThread(std::function<void()>) override;
54
36
 
@@ -56,8 +38,16 @@ public:
56
38
 
57
39
  sk_sp<SkImage> makeImageFromNativeBuffer(void *buffer) override;
58
40
 
41
+ sk_sp<SkImage> makeImageFromNativeTexture(const TextureInfo &textureInfo,
42
+ int width, int height,
43
+ bool mipMapped) override;
44
+
59
45
  uint64_t makeNativeBuffer(sk_sp<SkImage> image) override;
60
46
 
47
+ const TextureInfo getTexture(sk_sp<SkSurface> image) override;
48
+
49
+ const TextureInfo getTexture(sk_sp<SkImage> image) override;
50
+
61
51
  void releaseNativeBuffer(uint64_t pointer) override;
62
52
 
63
53
  std::shared_ptr<RNSkVideo> createVideo(const std::string &url) override;
@@ -76,16 +66,10 @@ public:
76
66
  #endif
77
67
  sk_sp<SkFontMgr> createFontMgr() override;
78
68
 
79
- void willInvalidateModules() {}
80
-
81
69
  private:
82
70
  ViewScreenshotService *_screenshotService;
83
- };
84
71
 
85
- static void handleNotification(CFNotificationCenterRef center, void *observer,
86
- CFStringRef name, const void *object,
87
- CFDictionaryRef userInfo) {
88
- (static_cast<RNSkiOSPlatformContext *>(observer))->willInvalidateModules();
89
- }
72
+ SkColorType mtlPixelFormatToSkColorType(MTLPixelFormat pixelFormat);
73
+ };
90
74
 
91
75
  } // namespace RNSkia