@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.
- package/android/cpp/jni/include/JniSkiaBaseView.h +0 -1
- package/android/cpp/jni/include/JniSkiaPictureView.h +0 -1
- package/android/cpp/rnskia-android/OpenGLContext.h +40 -0
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +5 -5
- package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +2 -2
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +49 -14
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +5 -2
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.cpp +19 -133
- package/android/cpp/rnskia-android/SkiaOpenGLSurfaceFactory.h +30 -138
- package/cpp/api/JsiSkTypefaceFontProvider.h +1 -1
- package/cpp/api/JsiSkiaContext.h +6 -3
- package/cpp/jsi/JsiValue.cpp +1 -2
- package/cpp/rnskia/RNSkPlatformContext.h +2 -2
- package/cpp/rnskia/{SkiaContext.h → WindowContext.h} +5 -2
- package/ios/RNSkia-iOS/DisplayLink.mm +7 -0
- package/ios/RNSkia-iOS/MetalContext.h +46 -0
- package/ios/RNSkia-iOS/MetalContext.mm +33 -0
- package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm +8 -28
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +1 -1
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +8 -9
- package/ios/RNSkia-iOS/RNSkiOSView.mm +0 -2
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +28 -32
- package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +18 -60
- package/ios/RNSkia-iOS/SkiaUIView.h +0 -2
- package/ios/RNSkia-iOS/ViewScreenshotService.mm +1 -8
- package/lib/commonjs/web/WithSkiaWeb.js +4 -1
- package/lib/commonjs/web/WithSkiaWeb.js.map +1 -1
- package/lib/module/web/WithSkiaWeb.js +4 -1
- package/lib/module/web/WithSkiaWeb.js.map +1 -1
- package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
- package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
- package/libs/ios/libskottie.xcframework/Info.plist +5 -5
- package/libs/ios/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
- package/libs/ios/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
- package/libs/ios/libskparagraph.xcframework/Info.plist +5 -5
- package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
- package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
- package/libs/ios/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
- package/libs/ios/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
- package/libs/ios/libskshaper.xcframework/Info.plist +5 -5
- package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
- package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
- package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e/libskunicode_core.a +0 -0
- package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_core.a +0 -0
- package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e/libskunicode_libgrapheme.a +0 -0
- package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_libgrapheme.a +0 -0
- package/libs/ios/libsvg.xcframework/Info.plist +5 -5
- package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
- package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
- package/package.json +3 -6
- 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
|
-
|
43
|
+
getObject()->registerTypeface(typeface, familyName);
|
44
44
|
return jsi::Value::undefined();
|
45
45
|
}
|
46
46
|
|
package/cpp/api/JsiSkiaContext.h
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
#include "JsiSkRect.h"
|
15
15
|
#include "JsiSkTypeface.h"
|
16
16
|
|
17
|
-
#include "
|
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<
|
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<
|
54
|
+
std::shared_ptr<WindowContext> ctx)
|
52
55
|
: JsiSkWrappingSharedPtrHostObject(std::move(context), std::move(ctx)) {}
|
53
56
|
|
54
57
|
/**
|
package/cpp/jsi/JsiValue.cpp
CHANGED
@@ -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::
|
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 "
|
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<
|
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
|
15
|
+
class WindowContext {
|
16
16
|
public:
|
17
|
-
virtual ~
|
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 =
|
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
|
-
|
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
|
-
|
109
|
-
|
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<
|
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
|
-
|
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<
|
152
|
+
std::shared_ptr<WindowContext>
|
153
153
|
RNSkiOSPlatformContext::makeContextFromNativeSurface(void *surface, int width,
|
154
154
|
int height) {
|
155
|
-
return
|
156
|
-
|
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
|
165
|
+
return MetalContext::getInstance().MakeOffscreen(width, height);
|
166
166
|
}
|
167
167
|
|
168
168
|
sk_sp<SkImage> RNSkiOSPlatformContext::makeImageFromNativeBuffer(void *buffer) {
|
169
|
-
|
170
|
-
return SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer(sampleBuffer);
|
169
|
+
return MetalContext::getInstance().MakeImageFromBuffer(buffer);
|
171
170
|
}
|
172
171
|
|
173
172
|
sk_sp<SkFontMgr> RNSkiOSPlatformContext::createFontMgr() {
|
@@ -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 "
|
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(
|
29
|
+
static sk_sp<SkSurface> makeWindowedSurface(SkiaMetalContext *context,
|
30
|
+
id<MTLTexture> texture, int width,
|
33
31
|
int height);
|
34
|
-
static sk_sp<SkSurface> makeOffscreenSurface(
|
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(
|
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
|
-
|
43
|
-
|
44
|
-
|
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::
|
45
|
+
class IOSSkiaContext : public RNSkia::WindowContext {
|
49
46
|
public:
|
50
|
-
IOSSkiaContext(CALayer *layer, int width,
|
51
|
-
|
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 =
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
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
|
-
|
90
|
-
|
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(
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
119
|
-
|
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
|
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
|
103
|
+
context->skContext.get(), pixelBuffer);
|
146
104
|
}
|
147
105
|
default:
|
148
106
|
[[unlikely]] {
|
@@ -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
|
-
}),
|
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 [
|
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
|
-
}),
|
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));
|