@shopify/react-native-skia 1.12.1 → 1.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apple/MetalContext.h +129 -0
- package/apple/MetalContext.mm +34 -0
- package/apple/MetalWindowContext.h +39 -0
- package/apple/MetalWindowContext.mm +64 -0
- package/apple/RNSkApplePlatformContext.h +79 -0
- package/apple/RNSkApplePlatformContext.mm +303 -0
- package/apple/RNSkAppleVideo.h +51 -0
- package/apple/RNSkAppleVideo.mm +137 -0
- package/apple/RNSkAppleView.h +37 -0
- package/apple/RNSkAppleView.mm +35 -0
- package/apple/RNSkMetalCanvasProvider.h +38 -0
- package/apple/RNSkMetalCanvasProvider.mm +108 -0
- package/apple/RNSkiaModule.h +20 -0
- package/apple/RNSkiaModule.mm +55 -0
- package/apple/SkiaCVPixelBufferUtils.h +119 -0
- package/apple/SkiaCVPixelBufferUtils.mm +344 -0
- package/apple/SkiaManager.h +25 -0
- package/apple/SkiaManager.mm +62 -0
- package/apple/SkiaPictureView.h +7 -0
- package/apple/SkiaPictureView.mm +66 -0
- package/apple/SkiaPictureViewManager.h +8 -0
- package/apple/SkiaPictureViewManager.mm +55 -0
- package/apple/SkiaUIView.h +45 -0
- package/apple/SkiaUIView.mm +172 -0
- package/apple/ViewScreenshotService.h +25 -0
- package/apple/ViewScreenshotService.mm +89 -0
- package/lib/commonjs/skia/web/Host.d.ts +3 -3
- package/lib/commonjs/skia/web/Host.js +16 -4
- package/lib/commonjs/skia/web/Host.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.js +15 -15
- package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkColorFilterFactory.js +1 -1
- package/lib/commonjs/skia/web/JsiSkColorFilterFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkFont.js +2 -2
- package/lib/commonjs/skia/web/JsiSkFont.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImage.js +6 -6
- package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImageFactory.js +2 -2
- package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImageFilterFactory.js +3 -3
- package/lib/commonjs/skia/web/JsiSkImageFilterFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkMaskFilterFactory.js +1 -1
- package/lib/commonjs/skia/web/JsiSkMaskFilterFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPaint.js +3 -3
- package/lib/commonjs/skia/web/JsiSkPaint.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPath.js +4 -4
- package/lib/commonjs/skia/web/JsiSkPath.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPathEffectFactory.js +1 -1
- package/lib/commonjs/skia/web/JsiSkPathEffectFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPathFactory.js +1 -1
- package/lib/commonjs/skia/web/JsiSkPathFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPicture.js +1 -1
- package/lib/commonjs/skia/web/JsiSkPicture.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkShaderFactory.js +5 -5
- package/lib/commonjs/skia/web/JsiSkShaderFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkVerticesFactory.js +1 -1
- package/lib/commonjs/skia/web/JsiSkVerticesFactory.js.map +1 -1
- package/lib/module/skia/web/Host.d.ts +3 -3
- package/lib/module/skia/web/Host.js +16 -4
- package/lib/module/skia/web/Host.js.map +1 -1
- package/lib/module/skia/web/JsiSkCanvas.js +15 -15
- package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/module/skia/web/JsiSkColorFilterFactory.js +1 -1
- package/lib/module/skia/web/JsiSkColorFilterFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkFont.js +2 -2
- package/lib/module/skia/web/JsiSkFont.js.map +1 -1
- package/lib/module/skia/web/JsiSkImage.js +6 -6
- package/lib/module/skia/web/JsiSkImage.js.map +1 -1
- package/lib/module/skia/web/JsiSkImageFactory.js +2 -2
- package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkImageFilterFactory.js +3 -3
- package/lib/module/skia/web/JsiSkImageFilterFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkMaskFilterFactory.js +1 -1
- package/lib/module/skia/web/JsiSkMaskFilterFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkPaint.js +3 -3
- package/lib/module/skia/web/JsiSkPaint.js.map +1 -1
- package/lib/module/skia/web/JsiSkPath.js +4 -4
- package/lib/module/skia/web/JsiSkPath.js.map +1 -1
- package/lib/module/skia/web/JsiSkPathEffectFactory.js +1 -1
- package/lib/module/skia/web/JsiSkPathEffectFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkPathFactory.js +1 -1
- package/lib/module/skia/web/JsiSkPathFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkPicture.js +1 -1
- package/lib/module/skia/web/JsiSkPicture.js.map +1 -1
- package/lib/module/skia/web/JsiSkShaderFactory.js +5 -5
- package/lib/module/skia/web/JsiSkShaderFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkVerticesFactory.js +1 -1
- package/lib/module/skia/web/JsiSkVerticesFactory.js.map +1 -1
- package/lib/typescript/lib/commonjs/skia/web/Host.d.ts +2 -2
- package/lib/typescript/lib/module/skia/web/Host.d.ts +2 -2
- package/lib/typescript/src/skia/web/Host.d.ts +3 -3
- package/package.json +2 -2
- package/src/skia/__tests__/Enums.spec.ts +34 -0
- package/src/skia/web/Host.ts +24 -7
- package/src/skia/web/JsiSkCanvas.ts +17 -17
- package/src/skia/web/JsiSkColorFilterFactory.ts +1 -1
- package/src/skia/web/JsiSkFont.ts +2 -2
- package/src/skia/web/JsiSkImage.ts +14 -10
- package/src/skia/web/JsiSkImageFactory.ts +2 -2
- package/src/skia/web/JsiSkImageFilterFactory.ts +4 -4
- package/src/skia/web/JsiSkMaskFilterFactory.ts +1 -1
- package/src/skia/web/JsiSkPaint.ts +3 -3
- package/src/skia/web/JsiSkPath.ts +4 -4
- package/src/skia/web/JsiSkPathEffectFactory.ts +1 -1
- package/src/skia/web/JsiSkPathFactory.ts +1 -1
- package/src/skia/web/JsiSkPicture.ts +3 -3
- package/src/skia/web/JsiSkShaderFactory.ts +5 -5
- package/src/skia/web/JsiSkVerticesFactory.ts +1 -1
@@ -0,0 +1,137 @@
|
|
1
|
+
#include <memory>
|
2
|
+
#include <string>
|
3
|
+
|
4
|
+
#pragma clang diagnostic push
|
5
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
6
|
+
|
7
|
+
#include "include/core/SkImage.h"
|
8
|
+
|
9
|
+
#pragma clang diagnostic pop
|
10
|
+
|
11
|
+
#include "RNSkAppleVideo.h"
|
12
|
+
#include <AVFoundation/AVFoundation.h>
|
13
|
+
#include <CoreVideo/CoreVideo.h>
|
14
|
+
|
15
|
+
namespace RNSkia {
|
16
|
+
|
17
|
+
RNSkAppleVideo::RNSkAppleVideo(std::string url, RNSkPlatformContext *context)
|
18
|
+
: _url(std::move(url)), _context(context) {
|
19
|
+
setupPlayer();
|
20
|
+
}
|
21
|
+
|
22
|
+
RNSkAppleVideo::~RNSkAppleVideo() {
|
23
|
+
if (_player) {
|
24
|
+
[_player pause];
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
void RNSkAppleVideo::setupPlayer() {
|
29
|
+
NSURL *videoURL = [NSURL URLWithString:@(_url.c_str())];
|
30
|
+
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:videoURL];
|
31
|
+
_player = [AVPlayer playerWithPlayerItem:playerItem];
|
32
|
+
_playerItem = playerItem;
|
33
|
+
|
34
|
+
NSDictionary *outputSettings = getOutputSettings();
|
35
|
+
_videoOutput =
|
36
|
+
[[AVPlayerItemVideoOutput alloc] initWithOutputSettings:outputSettings];
|
37
|
+
[playerItem addOutput:_videoOutput];
|
38
|
+
|
39
|
+
CMTime time = playerItem.asset.duration;
|
40
|
+
if (time.timescale != 0) {
|
41
|
+
_duration = CMTimeGetSeconds(time) * 1000; // Store duration in milliseconds
|
42
|
+
}
|
43
|
+
|
44
|
+
AVAssetTrack *videoTrack =
|
45
|
+
[[playerItem.asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
|
46
|
+
if (videoTrack) {
|
47
|
+
_framerate = videoTrack.nominalFrameRate;
|
48
|
+
_preferredTransform = videoTrack.preferredTransform;
|
49
|
+
CGSize videoSize = videoTrack.naturalSize;
|
50
|
+
_videoWidth = videoSize.width;
|
51
|
+
_videoHeight = videoSize.height;
|
52
|
+
}
|
53
|
+
play();
|
54
|
+
}
|
55
|
+
|
56
|
+
sk_sp<SkImage> RNSkAppleVideo::nextImage(double *timeStamp) {
|
57
|
+
CMTime currentTime = [_player currentTime];
|
58
|
+
CVPixelBufferRef pixelBuffer =
|
59
|
+
[_videoOutput copyPixelBufferForItemTime:currentTime
|
60
|
+
itemTimeForDisplay:nullptr];
|
61
|
+
if (!pixelBuffer) {
|
62
|
+
NSLog(@"No pixel buffer.");
|
63
|
+
return nullptr;
|
64
|
+
}
|
65
|
+
|
66
|
+
auto skImage = _context->makeImageFromNativeBuffer((void *)pixelBuffer);
|
67
|
+
|
68
|
+
if (timeStamp) {
|
69
|
+
*timeStamp = CMTimeGetSeconds(currentTime);
|
70
|
+
}
|
71
|
+
|
72
|
+
CVPixelBufferRelease(pixelBuffer);
|
73
|
+
return skImage;
|
74
|
+
}
|
75
|
+
|
76
|
+
NSDictionary *RNSkAppleVideo::getOutputSettings() {
|
77
|
+
return @{
|
78
|
+
(id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA),
|
79
|
+
(id)kCVPixelBufferMetalCompatibilityKey : @YES
|
80
|
+
};
|
81
|
+
}
|
82
|
+
|
83
|
+
float RNSkAppleVideo::getRotationInDegrees() {
|
84
|
+
CGFloat rotationAngle = 0.0;
|
85
|
+
auto transform = _preferredTransform;
|
86
|
+
// Determine the rotation angle in radians
|
87
|
+
if (transform.a == 0 && transform.b == 1 && transform.c == -1 &&
|
88
|
+
transform.d == 0) {
|
89
|
+
rotationAngle = 90;
|
90
|
+
} else if (transform.a == 0 && transform.b == -1 && transform.c == 1 &&
|
91
|
+
transform.d == 0) {
|
92
|
+
rotationAngle = 270;
|
93
|
+
} else if (transform.a == -1 && transform.b == 0 && transform.c == 0 &&
|
94
|
+
transform.d == -1) {
|
95
|
+
rotationAngle = 180;
|
96
|
+
}
|
97
|
+
return rotationAngle;
|
98
|
+
}
|
99
|
+
|
100
|
+
void RNSkAppleVideo::seek(double timeInMilliseconds) {
|
101
|
+
CMTime seekTime =
|
102
|
+
CMTimeMakeWithSeconds(timeInMilliseconds / 1000.0, NSEC_PER_SEC);
|
103
|
+
[_player seekToTime:seekTime
|
104
|
+
toleranceBefore:kCMTimeZero
|
105
|
+
toleranceAfter:kCMTimeZero
|
106
|
+
completionHandler:^(BOOL finished) {
|
107
|
+
if (!finished) {
|
108
|
+
NSLog(@"Seek failed or was interrupted.");
|
109
|
+
}
|
110
|
+
}];
|
111
|
+
}
|
112
|
+
|
113
|
+
void RNSkAppleVideo::play() {
|
114
|
+
if (_player) {
|
115
|
+
[_player play];
|
116
|
+
_isPlaying = true;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
void RNSkAppleVideo::pause() {
|
121
|
+
if (_player) {
|
122
|
+
[_player pause];
|
123
|
+
_isPlaying = false;
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
double RNSkAppleVideo::duration() { return _duration; }
|
128
|
+
|
129
|
+
double RNSkAppleVideo::framerate() { return _framerate; }
|
130
|
+
|
131
|
+
SkISize RNSkAppleVideo::getSize() {
|
132
|
+
return SkISize::Make(_videoWidth, _videoHeight);
|
133
|
+
}
|
134
|
+
|
135
|
+
void RNSkAppleVideo::setVolume(float volume) { _player.volume = volume; }
|
136
|
+
|
137
|
+
} // namespace RNSkia
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#import <memory>
|
4
|
+
|
5
|
+
#import "RNSkMetalCanvasProvider.h"
|
6
|
+
#import "RNSkView.h"
|
7
|
+
#import "RNSkApplePlatformContext.h"
|
8
|
+
|
9
|
+
class RNSkBaseAppleView {
|
10
|
+
public:
|
11
|
+
virtual CALayer *getLayer() = 0;
|
12
|
+
virtual void setSize(int width, int height) = 0;
|
13
|
+
virtual std::shared_ptr<RNSkia::RNSkView> getDrawView() = 0;
|
14
|
+
};
|
15
|
+
|
16
|
+
template <class T> class RNSkAppleView : public RNSkBaseAppleView, public T {
|
17
|
+
public:
|
18
|
+
RNSkAppleView(std::shared_ptr<RNSkia::RNSkPlatformContext> context)
|
19
|
+
: T(context,
|
20
|
+
std::make_shared<RNSkMetalCanvasProvider>(
|
21
|
+
std::bind(&RNSkia::RNSkView::requestRedraw, this), context)) {}
|
22
|
+
|
23
|
+
CALayer *getLayer() override {
|
24
|
+
return std::static_pointer_cast<RNSkMetalCanvasProvider>(
|
25
|
+
this->getCanvasProvider())
|
26
|
+
->getLayer();
|
27
|
+
}
|
28
|
+
|
29
|
+
void setSize(int width, int height) override {
|
30
|
+
std::static_pointer_cast<RNSkMetalCanvasProvider>(this->getCanvasProvider())
|
31
|
+
->setSize(width, height);
|
32
|
+
}
|
33
|
+
|
34
|
+
std::shared_ptr<RNSkia::RNSkView> getDrawView() override {
|
35
|
+
return this->shared_from_this();
|
36
|
+
}
|
37
|
+
};
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#import <memory>
|
2
|
+
|
3
|
+
#import "RNSkMetalCanvasProvider.h"
|
4
|
+
#import "RNSkView.h"
|
5
|
+
#import "RNSkApplePlatformContext.h"
|
6
|
+
|
7
|
+
class RNSkBaseAppleView {
|
8
|
+
public:
|
9
|
+
virtual CALayer *getLayer() = 0;
|
10
|
+
virtual void setSize(int width, int height) = 0;
|
11
|
+
virtual std::shared_ptr<RNSkia::RNSkView> getDrawView() = 0;
|
12
|
+
};
|
13
|
+
|
14
|
+
template <class T> class RNSkAppleView : public RNSkBaseAppleView, public T {
|
15
|
+
public:
|
16
|
+
RNSkAppleView(std::shared_ptr<RNSkia::RNSkPlatformContext> context)
|
17
|
+
: T(context,
|
18
|
+
std::make_shared<RNSkMetalCanvasProvider>(
|
19
|
+
std::bind(&RNSkia::RNSkView::requestRedraw, this), context)) {}
|
20
|
+
|
21
|
+
CALayer *getLayer() override {
|
22
|
+
return std::static_pointer_cast<RNSkMetalCanvasProvider>(
|
23
|
+
this->getCanvasProvider())
|
24
|
+
->getLayer();
|
25
|
+
}
|
26
|
+
|
27
|
+
void setSize(int width, int height) override {
|
28
|
+
std::static_pointer_cast<RNSkMetalCanvasProvider>(this->getCanvasProvider())
|
29
|
+
->setSize(width, height);
|
30
|
+
}
|
31
|
+
|
32
|
+
std::shared_ptr<RNSkia::RNSkView> getDrawView() override {
|
33
|
+
return this->shared_from_this();
|
34
|
+
}
|
35
|
+
};
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#import "RNSkPlatformContext.h"
|
4
|
+
#import "RNSkView.h"
|
5
|
+
|
6
|
+
#import <MetalKit/MetalKit.h>
|
7
|
+
#import <QuartzCore/CAMetalLayer.h>
|
8
|
+
|
9
|
+
#pragma clang diagnostic push
|
10
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
11
|
+
|
12
|
+
#import <include/gpu/ganesh/GrDirectContext.h>
|
13
|
+
|
14
|
+
#pragma clang diagnostic pop
|
15
|
+
|
16
|
+
class RNSkMetalCanvasProvider : public RNSkia::RNSkCanvasProvider {
|
17
|
+
public:
|
18
|
+
RNSkMetalCanvasProvider(std::function<void()> requestRedraw,
|
19
|
+
std::shared_ptr<RNSkia::RNSkPlatformContext> context);
|
20
|
+
|
21
|
+
~RNSkMetalCanvasProvider();
|
22
|
+
|
23
|
+
int getScaledWidth() override;
|
24
|
+
int getScaledHeight() override;
|
25
|
+
|
26
|
+
bool renderToCanvas(const std::function<void(SkCanvas *)> &cb) override;
|
27
|
+
|
28
|
+
void setSize(int width, int height);
|
29
|
+
CALayer *getLayer();
|
30
|
+
|
31
|
+
private:
|
32
|
+
std::shared_ptr<RNSkia::RNSkPlatformContext> _context;
|
33
|
+
std::unique_ptr<RNSkia::WindowContext> _ctx = nullptr;
|
34
|
+
#pragma clang diagnostic push
|
35
|
+
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
36
|
+
CAMetalLayer *_layer;
|
37
|
+
#pragma clang diagnostic pop
|
38
|
+
};
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#import "RNSkMetalCanvasProvider.h"
|
2
|
+
|
3
|
+
#import "RNSkLog.h"
|
4
|
+
|
5
|
+
#if defined(SK_GRAPHITE)
|
6
|
+
#import "DawnContext.h"
|
7
|
+
#else
|
8
|
+
#import "MetalContext.h"
|
9
|
+
#endif
|
10
|
+
|
11
|
+
#pragma clang diagnostic push
|
12
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
13
|
+
|
14
|
+
#import "include/core/SkCanvas.h"
|
15
|
+
#import "include/core/SkColorSpace.h"
|
16
|
+
#import "include/core/SkSurface.h"
|
17
|
+
|
18
|
+
#import <include/gpu/ganesh/GrBackendSurface.h>
|
19
|
+
#import <include/gpu/ganesh/GrDirectContext.h>
|
20
|
+
#import <include/gpu/ganesh/SkSurfaceGanesh.h>
|
21
|
+
|
22
|
+
#pragma clang diagnostic pop
|
23
|
+
|
24
|
+
RNSkMetalCanvasProvider::RNSkMetalCanvasProvider(
|
25
|
+
std::function<void()> requestRedraw,
|
26
|
+
std::shared_ptr<RNSkia::RNSkPlatformContext> context)
|
27
|
+
: RNSkCanvasProvider(requestRedraw), _context(context) {
|
28
|
+
#pragma clang diagnostic push
|
29
|
+
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
30
|
+
_layer = [CAMetalLayer layer];
|
31
|
+
#pragma clang diagnostic pop
|
32
|
+
}
|
33
|
+
|
34
|
+
RNSkMetalCanvasProvider::~RNSkMetalCanvasProvider() {}
|
35
|
+
|
36
|
+
/**
|
37
|
+
Returns the scaled width of the view
|
38
|
+
*/
|
39
|
+
int RNSkMetalCanvasProvider::getScaledWidth() {
|
40
|
+
return _ctx ? _ctx->getWidth() : -1;
|
41
|
+
};
|
42
|
+
|
43
|
+
/**
|
44
|
+
Returns the scaled height of the view
|
45
|
+
*/
|
46
|
+
int RNSkMetalCanvasProvider::getScaledHeight() {
|
47
|
+
return _ctx ? _ctx->getHeight() : -1;
|
48
|
+
};
|
49
|
+
|
50
|
+
/**
|
51
|
+
Render to a canvas
|
52
|
+
*/
|
53
|
+
bool RNSkMetalCanvasProvider::renderToCanvas(
|
54
|
+
const std::function<void(SkCanvas *)> &cb) {
|
55
|
+
if (!_ctx) {
|
56
|
+
return false;
|
57
|
+
}
|
58
|
+
|
59
|
+
// Make sure to NOT render or try any render operations while we're in the
|
60
|
+
// background or inactive. This will cause an error that might clear the
|
61
|
+
// CAMetalLayer so that the canvas is empty when the app receives focus again.
|
62
|
+
// Reference: https://github.com/Shopify/react-native-skia/issues/1257
|
63
|
+
// NOTE: UIApplication.sharedApplication.applicationState can only be
|
64
|
+
// accessed from the main thread so we need to check here.
|
65
|
+
if ([[NSThread currentThread] isMainThread]) {
|
66
|
+
#if !TARGET_OS_OSX
|
67
|
+
auto state = UIApplication.sharedApplication.applicationState;
|
68
|
+
bool appIsBackgrounded = (state == UIApplicationStateBackground);
|
69
|
+
#else
|
70
|
+
bool appIsBackgrounded = !NSApplication.sharedApplication.isActive;
|
71
|
+
#endif // !TARGET_OS_OSX
|
72
|
+
if (appIsBackgrounded) {
|
73
|
+
// Request a redraw in the next run loop callback
|
74
|
+
_requestRedraw();
|
75
|
+
// and don't draw now since it might cause errors in the metal renderer if
|
76
|
+
// we try to render while in the background. (see above issue)
|
77
|
+
return false;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
// Wrap in auto release pool since we want the system to clean up after
|
81
|
+
// rendering and not wait until later - we've seen some example of memory
|
82
|
+
// usage growing very fast in the simulator without this.
|
83
|
+
@autoreleasepool {
|
84
|
+
auto surface = _ctx->getSurface();
|
85
|
+
if (!surface) {
|
86
|
+
return false;
|
87
|
+
}
|
88
|
+
auto canvas = surface->getCanvas();
|
89
|
+
cb(canvas);
|
90
|
+
_ctx->present();
|
91
|
+
}
|
92
|
+
return true;
|
93
|
+
};
|
94
|
+
|
95
|
+
void RNSkMetalCanvasProvider::setSize(int width, int height) {
|
96
|
+
_layer.frame = CGRectMake(0, 0, width, height);
|
97
|
+
auto w = width * _context->getPixelDensity();
|
98
|
+
auto h = height * _context->getPixelDensity();
|
99
|
+
#if defined(SK_GRAPHITE)
|
100
|
+
_ctx = RNSkia::DawnContext::getInstance().MakeWindow((__bridge void *)_layer,
|
101
|
+
w, h);
|
102
|
+
#else
|
103
|
+
_ctx = MetalContext::getInstance().MakeWindow(_layer, w, h);
|
104
|
+
#endif
|
105
|
+
_requestRedraw();
|
106
|
+
}
|
107
|
+
|
108
|
+
CALayer *RNSkMetalCanvasProvider::getLayer() { return _layer; }
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
4
|
+
#import <rnskia/rnskia.h>
|
5
|
+
#else
|
6
|
+
#import <React/RCTBridgeModule.h>
|
7
|
+
#endif
|
8
|
+
|
9
|
+
#include "SkiaManager.h"
|
10
|
+
|
11
|
+
@interface RNSkiaModule : NSObject
|
12
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
13
|
+
<NativeSkiaModuleSpec>
|
14
|
+
#else
|
15
|
+
<RCTBridgeModule>
|
16
|
+
#endif
|
17
|
+
|
18
|
+
- (SkiaManager *)manager;
|
19
|
+
|
20
|
+
@end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
#import "RNSkiaModule.h"
|
3
|
+
#import <React/RCTBridge+Private.h>
|
4
|
+
#import <ReactCommon/RCTTurboModule.h>
|
5
|
+
|
6
|
+
@implementation RNSkiaModule {
|
7
|
+
SkiaManager *skiaManager;
|
8
|
+
std::shared_ptr<facebook::react::CallInvoker> jsInvoker;
|
9
|
+
}
|
10
|
+
|
11
|
+
RCT_EXPORT_MODULE()
|
12
|
+
@synthesize bridge = _bridge;
|
13
|
+
|
14
|
+
#pragma Accessors
|
15
|
+
|
16
|
+
- (SkiaManager *)manager {
|
17
|
+
return skiaManager;
|
18
|
+
}
|
19
|
+
|
20
|
+
#pragma Setup and invalidation
|
21
|
+
|
22
|
+
+ (BOOL)requiresMainQueueSetup {
|
23
|
+
return YES;
|
24
|
+
}
|
25
|
+
|
26
|
+
- (void)invalidate {
|
27
|
+
if (skiaManager != nil) {
|
28
|
+
[skiaManager invalidate];
|
29
|
+
}
|
30
|
+
skiaManager = nil;
|
31
|
+
}
|
32
|
+
|
33
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) {
|
34
|
+
if (skiaManager != nil) {
|
35
|
+
// Already initialized, ignore call.
|
36
|
+
return @true;
|
37
|
+
}
|
38
|
+
RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
|
39
|
+
if (!jsInvoker) {
|
40
|
+
jsInvoker = cxxBridge.jsCallInvoker;
|
41
|
+
}
|
42
|
+
skiaManager = [[SkiaManager alloc] initWithBridge:cxxBridge
|
43
|
+
jsInvoker:jsInvoker];
|
44
|
+
return @true;
|
45
|
+
}
|
46
|
+
|
47
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
48
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
49
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params {
|
50
|
+
jsInvoker = params.jsInvoker;
|
51
|
+
return std::make_shared<facebook::react::NativeSkiaModuleSpecJSI>(params);
|
52
|
+
}
|
53
|
+
#endif
|
54
|
+
|
55
|
+
@end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
//
|
2
|
+
// SkiaCVPixelBufferUtils.h
|
3
|
+
// react-native-skia
|
4
|
+
//
|
5
|
+
// Created by Marc Rousavy on 10.04.24.
|
6
|
+
//
|
7
|
+
|
8
|
+
#pragma once
|
9
|
+
|
10
|
+
#import <vector>
|
11
|
+
|
12
|
+
#import <CoreMedia/CMSampleBuffer.h>
|
13
|
+
#import <CoreVideo/CVMetalTextureCache.h>
|
14
|
+
#import <MetalKit/MetalKit.h>
|
15
|
+
|
16
|
+
#pragma clang diagnostic push
|
17
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
18
|
+
#import "include/core/SkColorSpace.h"
|
19
|
+
#import "include/core/SkImage.h"
|
20
|
+
#import "include/gpu/ganesh/GrBackendSurface.h"
|
21
|
+
#import "include/gpu/ganesh/GrYUVABackendTextures.h"
|
22
|
+
#pragma clang diagnostic pop
|
23
|
+
|
24
|
+
/**
|
25
|
+
Holds a Metal Texture.
|
26
|
+
When the `TextureHolder` is destroyed, the underlying Metal Texture
|
27
|
+
is marked as invalid and might be overwritten by the Texture Cache,
|
28
|
+
so make sure to delete the `TextureHolder` only when the `SkImage`
|
29
|
+
has been deleted.
|
30
|
+
|
31
|
+
For example, use the `releaseProc` parameter in `BorrowImageFromTexture`
|
32
|
+
to delete the `TextureHolder`.
|
33
|
+
*/
|
34
|
+
class TextureHolder {
|
35
|
+
public:
|
36
|
+
/**
|
37
|
+
Create a new instance of TextureHolder which holds
|
38
|
+
the given `CVMetalTextureRef`.
|
39
|
+
|
40
|
+
The given `CVMetalTextureRef` is assumed to already be
|
41
|
+
retained with `CFRetain`, and will later be manually
|
42
|
+
released with `CFRelease`.
|
43
|
+
*/
|
44
|
+
TextureHolder(CVMetalTextureRef texture);
|
45
|
+
~TextureHolder();
|
46
|
+
|
47
|
+
/**
|
48
|
+
Converts this Texture to a Skia GrBackendTexture.
|
49
|
+
*/
|
50
|
+
GrBackendTexture toGrBackendTexture();
|
51
|
+
|
52
|
+
private:
|
53
|
+
CVMetalTextureRef _texture;
|
54
|
+
};
|
55
|
+
|
56
|
+
/**
|
57
|
+
Same as `TextureHolder`, but for multiple planar textures (e.g. YUVA)
|
58
|
+
*/
|
59
|
+
class MultiTexturesHolder {
|
60
|
+
public:
|
61
|
+
~MultiTexturesHolder();
|
62
|
+
void addTexture(TextureHolder *texture);
|
63
|
+
|
64
|
+
private:
|
65
|
+
std::vector<TextureHolder *> _textures;
|
66
|
+
};
|
67
|
+
|
68
|
+
class SkiaCVPixelBufferUtils {
|
69
|
+
public:
|
70
|
+
enum class CVPixelBufferBaseFormat { rgb, yuv };
|
71
|
+
|
72
|
+
/**
|
73
|
+
Get the base format (currently only RGB) of the PixelBuffer.
|
74
|
+
Depending on the base-format, different methods have to be used to create
|
75
|
+
Skia buffers.
|
76
|
+
*/
|
77
|
+
static CVPixelBufferBaseFormat
|
78
|
+
getCVPixelBufferBaseFormat(CVPixelBufferRef pixelBuffer);
|
79
|
+
|
80
|
+
class RGB {
|
81
|
+
public:
|
82
|
+
/**
|
83
|
+
Creates a GPU-backed Skia Texture (SkImage) with the given RGB
|
84
|
+
CVPixelBuffer.
|
85
|
+
*/
|
86
|
+
static sk_sp<SkImage>
|
87
|
+
makeSkImageFromCVPixelBuffer(GrDirectContext *context,
|
88
|
+
CVPixelBufferRef pixelBuffer);
|
89
|
+
|
90
|
+
private:
|
91
|
+
static SkColorType getCVPixelBufferColorType(CVPixelBufferRef pixelBuffer);
|
92
|
+
};
|
93
|
+
|
94
|
+
class YUV {
|
95
|
+
public:
|
96
|
+
/**
|
97
|
+
Creates a GPU-backed Skia Texture (SkImage) with the given YUV
|
98
|
+
CVPixelBuffer.
|
99
|
+
*/
|
100
|
+
static sk_sp<SkImage>
|
101
|
+
makeSkImageFromCVPixelBuffer(GrDirectContext *context,
|
102
|
+
CVPixelBufferRef pixelBuffer);
|
103
|
+
|
104
|
+
private:
|
105
|
+
static SkYUVAInfo::PlaneConfig getPlaneConfig(OSType pixelFormat);
|
106
|
+
static SkYUVAInfo::Subsampling getSubsampling(OSType pixelFormat);
|
107
|
+
static SkYUVColorSpace getColorspace(OSType pixelFormat);
|
108
|
+
static SkYUVAInfo getYUVAInfoForCVPixelBuffer(CVPixelBufferRef pixelBuffer);
|
109
|
+
};
|
110
|
+
|
111
|
+
private:
|
112
|
+
static CVMetalTextureCacheRef getTextureCache();
|
113
|
+
static TextureHolder *
|
114
|
+
getSkiaTextureForCVPixelBufferPlane(CVPixelBufferRef pixelBuffer,
|
115
|
+
size_t planeIndex);
|
116
|
+
static MTLPixelFormat
|
117
|
+
getMTLPixelFormatForCVPixelBufferPlane(CVPixelBufferRef pixelBuffer,
|
118
|
+
size_t planeIndex);
|
119
|
+
};
|