@shopify/react-native-skia 1.6.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
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