@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.
- package/android/cpp/jni/include/JniSkiaBaseView.h +2 -3
- package/android/cpp/jni/include/JniSkiaManager.h +2 -2
- package/android/cpp/rnskia-android/GrAHardwareBufferUtils.cpp +14 -14
- package/android/cpp/rnskia-android/MainThreadDispatcher.h +4 -6
- package/android/cpp/rnskia-android/OpenGLContext.h +24 -10
- package/android/cpp/rnskia-android/OpenGLWindowContext.h +3 -3
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +64 -8
- package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +1 -1
- package/android/cpp/rnskia-android/RNSkAndroidVideo.h +1 -1
- package/android/cpp/rnskia-android/RNSkAndroidView.h +0 -4
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +3 -3
- package/android/cpp/rnskia-android/gl/Display.h +2 -0
- package/cpp/api/JsiSkApi.h +1 -1
- package/cpp/api/JsiSkCanvas.h +1 -1
- package/cpp/api/JsiSkColor.h +2 -2
- package/cpp/api/JsiSkContourMeasure.h +1 -5
- package/cpp/api/JsiSkImage.h +11 -0
- package/cpp/api/JsiSkImageFactory.h +14 -0
- package/cpp/api/JsiSkPicture.h +2 -0
- package/cpp/api/JsiSkSurface.h +7 -0
- package/cpp/api/JsiTextureInfo.h +53 -0
- package/cpp/api/third_party/CSSColorParser.h +1 -1
- package/cpp/api/third_party/base64.cpp +4 -4
- package/cpp/jsi/ViewProperty.h +48 -0
- package/cpp/rnskia/RNSkDomView.h +4 -7
- package/cpp/rnskia/RNSkJsiViewApi.h +3 -3
- package/cpp/rnskia/RNSkManager.cpp +1 -1
- package/cpp/rnskia/RNSkPictureView.h +8 -18
- package/cpp/rnskia/RNSkPlatformContext.h +18 -13
- package/cpp/rnskia/RNSkView.h +2 -8
- package/ios/RNSkia-iOS/MetalContext.h +101 -15
- package/ios/RNSkia-iOS/MetalContext.mm +9 -8
- package/ios/RNSkia-iOS/MetalWindowContext.h +39 -0
- package/ios/RNSkia-iOS/MetalWindowContext.mm +60 -0
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +13 -29
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +88 -2
- package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +17 -6
- package/ios/RNSkia-iOS/SkiaDomView.mm +3 -3
- package/ios/RNSkia-iOS/SkiaDomViewManager.mm +2 -1
- package/ios/RNSkia-iOS/SkiaManager.h +6 -0
- package/ios/RNSkia-iOS/SkiaManager.mm +18 -2
- package/ios/RNSkia-iOS/SkiaPictureView.mm +3 -3
- package/ios/RNSkia-iOS/SkiaPictureViewManager.mm +2 -1
- package/ios/RNSkia-iOS/SkiaUIView.h +0 -1
- package/ios/RNSkia-iOS/SkiaUIView.mm +18 -22
- package/lib/commonjs/skia/types/Image/Image.d.ts +10 -0
- package/lib/commonjs/skia/types/Image/Image.js.map +1 -1
- package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +18 -0
- package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
- package/lib/commonjs/skia/types/Matrix4.d.ts +6 -0
- package/lib/commonjs/skia/types/Matrix4.js +69 -1
- package/lib/commonjs/skia/types/Matrix4.js.map +1 -1
- package/lib/commonjs/skia/types/Surface/Surface.d.ts +11 -0
- package/lib/commonjs/skia/types/Surface/Surface.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -0
- package/lib/commonjs/skia/web/JsiSkImage.js +4 -0
- package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
- package/lib/commonjs/skia/web/JsiSkImageFactory.js +3 -0
- package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -0
- package/lib/commonjs/skia/web/JsiSkSurface.js +4 -0
- package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
- package/lib/module/skia/types/Image/Image.d.ts +10 -0
- package/lib/module/skia/types/Image/Image.js.map +1 -1
- package/lib/module/skia/types/Image/ImageFactory.d.ts +18 -0
- package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
- package/lib/module/skia/types/Matrix4.d.ts +6 -0
- package/lib/module/skia/types/Matrix4.js +67 -0
- package/lib/module/skia/types/Matrix4.js.map +1 -1
- package/lib/module/skia/types/Surface/Surface.d.ts +11 -0
- package/lib/module/skia/types/Surface/Surface.js.map +1 -1
- package/lib/module/skia/web/JsiSkImage.d.ts +1 -0
- package/lib/module/skia/web/JsiSkImage.js +4 -0
- package/lib/module/skia/web/JsiSkImage.js.map +1 -1
- package/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
- package/lib/module/skia/web/JsiSkImageFactory.js +3 -0
- package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkSurface.d.ts +1 -0
- package/lib/module/skia/web/JsiSkSurface.js +4 -0
- package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
- package/lib/typescript/lib/commonjs/skia/types/Matrix4.d.ts +6 -0
- package/lib/typescript/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -0
- package/lib/typescript/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
- package/lib/typescript/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -0
- package/lib/typescript/lib/module/mock/index.d.ts +1 -0
- package/lib/typescript/lib/module/skia/types/Matrix4.d.ts +1 -0
- package/lib/typescript/lib/module/skia/web/JsiSkImage.d.ts +1 -0
- package/lib/typescript/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
- package/lib/typescript/lib/module/skia/web/JsiSkSurface.d.ts +1 -0
- package/lib/typescript/src/skia/types/Image/Image.d.ts +10 -0
- package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +18 -0
- package/lib/typescript/src/skia/types/Matrix4.d.ts +6 -0
- package/lib/typescript/src/skia/types/Surface/Surface.d.ts +11 -0
- package/lib/typescript/src/skia/web/JsiSkImage.d.ts +1 -0
- package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +1 -0
- package/lib/typescript/src/skia/web/JsiSkSurface.d.ts +1 -0
- package/package.json +1 -1
- package/src/renderer/__tests__/e2e/Matrix4.spec.tsx +93 -0
- package/src/skia/types/Image/Image.ts +11 -0
- package/src/skia/types/Image/ImageFactory.ts +24 -0
- package/src/skia/types/Matrix4.ts +101 -0
- package/src/skia/types/Surface/Surface.ts +12 -0
- package/src/skia/web/JsiSkImage.ts +5 -0
- package/src/skia/web/JsiSkImageFactory.ts +4 -0
- package/src/skia/web/JsiSkSurface.ts +5 -0
- package/cpp/jsi/JsiValueWrapper.h +0 -164
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +0 -128
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +0 -92
@@ -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
|
-
|
30
|
-
|
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
|
-
|
116
|
-
|
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
|
package/cpp/rnskia/RNSkDomView.h
CHANGED
@@ -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,
|
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.
|
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(
|
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::
|
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::
|
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>(
|
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)),
|
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(
|
51
|
-
|
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::
|
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.
|
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.
|
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(
|
41
|
-
std::shared_ptr<react::CallInvoker> callInvoker,
|
45
|
+
RNSkPlatformContext(std::shared_ptr<react::CallInvoker> callInvoker,
|
42
46
|
float pixelDensity)
|
43
|
-
: _pixelDensity(pixelDensity),
|
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
|
package/cpp/rnskia/RNSkView.h
CHANGED
@@ -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::
|
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 "
|
4
|
-
#include "
|
3
|
+
#include "MetalWindowContext.h"
|
4
|
+
#include "SkiaCVPixelBufferUtils.h"
|
5
5
|
|
6
6
|
#include "include/core/SkSurface.h"
|
7
7
|
|
8
|
-
|
9
|
-
|
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
|
-
|
25
|
-
|
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
|
-
|
31
|
-
|
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
|
-
|
37
|
-
|
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
|
126
|
+
GrDirectContext *getDirectContext() { return _directContext.get(); }
|
41
127
|
|
42
128
|
private:
|
43
|
-
friend class RNSkia::RNSkiOSPlatformContext;
|
44
|
-
id<
|
45
|
-
|
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
|
-
|
20
|
-
|
21
|
-
id<MTLCommandQueue>(CFRetain((GrMTLHandle)[
|
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 *)
|
25
|
-
backendContext.fQueue.reset((__bridge void *)
|
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
|
-
|
30
|
-
if (
|
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
|
-
|
24
|
+
RCTBridge *bridge,
|
33
25
|
std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker)
|
34
|
-
: RNSkPlatformContext(
|
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
|
-
|
86
|
-
|
87
|
-
CFDictionaryRef userInfo) {
|
88
|
-
(static_cast<RNSkiOSPlatformContext *>(observer))->willInvalidateModules();
|
89
|
-
}
|
72
|
+
SkColorType mtlPixelFormatToSkColorType(MTLPixelFormat pixelFormat);
|
73
|
+
};
|
90
74
|
|
91
75
|
} // namespace RNSkia
|