@shopify/react-native-skia 0.1.151 → 0.1.152
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/android/CMakeLists.txt +4 -5
- package/android/cpp/jni/JniLoad.cpp +7 -5
- package/android/cpp/jni/JniSkiaManager.cpp +2 -15
- package/android/cpp/jni/include/JniSkiaBaseView.h +68 -0
- package/android/cpp/jni/include/JniSkiaDrawView.h +64 -47
- package/android/cpp/jni/include/JniSkiaManager.h +8 -10
- package/android/cpp/jni/include/JniSkiaPictureView.h +96 -0
- package/android/cpp/rnskia-android/{RNSkPlatformContextImpl.h → RNSkAndroidPlatformContext.h} +4 -4
- package/android/cpp/rnskia-android/RNSkAndroidView.h +100 -0
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +91 -0
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +39 -0
- package/android/cpp/rnskia-android/SkiaOpenGLRenderer.cpp +15 -6
- package/android/cpp/rnskia-android/SkiaOpenGLRenderer.h +5 -4
- package/android/src/main/java/com/shopify/reactnative/skia/PlatformContext.java +5 -11
- package/android/src/main/java/com/shopify/reactnative/skia/RNSkiaPackage.java +1 -2
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +143 -0
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java +17 -145
- package/android/src/main/java/com/shopify/reactnative/skia/{RNSkiaViewManager.java → SkiaDrawViewManager.java} +4 -15
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaManager.java +1 -10
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java +45 -0
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureViewManager.java +64 -0
- package/cpp/jsi/JsiValueWrapper.h +11 -0
- package/cpp/rnskia/RNSkInfoParameter.h +4 -14
- package/cpp/rnskia/RNSkJsView.cpp +211 -0
- package/cpp/rnskia/RNSkJsView.h +115 -0
- package/cpp/rnskia/RNSkJsiViewApi.h +6 -6
- package/cpp/rnskia/RNSkManager.cpp +7 -7
- package/cpp/rnskia/RNSkManager.h +7 -7
- package/cpp/rnskia/RNSkPictureView.h +124 -0
- package/cpp/rnskia/RNSkView.h +287 -0
- package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.h +38 -0
- package/ios/RNSkia-iOS/{RNSkDrawViewImpl.mm → RNSkMetalCanvasProvider.mm} +40 -23
- package/ios/RNSkia-iOS/{PlatformContext.h → RNSkiOSPlatformContext.h} +4 -4
- package/ios/RNSkia-iOS/{PlatformContext.mm → RNSkiOSPlatformContext.mm} +5 -5
- package/ios/RNSkia-iOS/RNSkiOSView.h +34 -0
- package/ios/RNSkia-iOS/SkiaDrawViewManager.mm +19 -11
- package/ios/RNSkia-iOS/SkiaManager.mm +3 -3
- package/ios/RNSkia-iOS/SkiaPictureViewManager.h +8 -0
- package/ios/RNSkia-iOS/SkiaPictureViewManager.mm +51 -0
- package/ios/RNSkia-iOS/SkiaUIView.h +26 -0
- package/ios/RNSkia-iOS/{SkiaDrawView.mm → SkiaUIView.mm} +29 -23
- package/lib/commonjs/views/SkiaBaseWebView.js +213 -0
- package/lib/commonjs/views/SkiaBaseWebView.js.map +1 -0
- package/lib/commonjs/views/SkiaPictureView.js +112 -0
- package/lib/commonjs/views/SkiaPictureView.js.map +1 -0
- package/lib/commonjs/views/SkiaPictureView.web.js +31 -0
- package/lib/commonjs/views/SkiaPictureView.web.js.map +1 -0
- package/lib/commonjs/views/SkiaView.js +1 -1
- package/lib/commonjs/views/SkiaView.js.map +1 -1
- package/lib/commonjs/views/SkiaView.web.js +14 -201
- package/lib/commonjs/views/SkiaView.web.js.map +1 -1
- package/lib/commonjs/views/index.js +13 -0
- package/lib/commonjs/views/index.js.map +1 -1
- package/lib/commonjs/views/types.js.map +1 -1
- package/lib/module/views/SkiaBaseWebView.js +198 -0
- package/lib/module/views/SkiaBaseWebView.js.map +1 -0
- package/lib/module/views/SkiaPictureView.js +94 -0
- package/lib/module/views/SkiaPictureView.js.map +1 -0
- package/lib/module/views/SkiaPictureView.web.js +19 -0
- package/lib/module/views/SkiaPictureView.web.js.map +1 -0
- package/lib/module/views/SkiaView.js +1 -1
- package/lib/module/views/SkiaView.js.map +1 -1
- package/lib/module/views/SkiaView.web.js +15 -199
- package/lib/module/views/SkiaView.web.js.map +1 -1
- package/lib/module/views/index.js +1 -0
- package/lib/module/views/index.js.map +1 -1
- package/lib/module/views/types.js.map +1 -1
- package/lib/typescript/src/views/SkiaBaseWebView.d.ts +58 -0
- package/lib/typescript/src/views/SkiaPictureView.d.ts +27 -0
- package/lib/typescript/src/views/SkiaPictureView.web.d.ts +7 -0
- package/lib/typescript/src/views/SkiaView.d.ts +4 -4
- package/lib/typescript/src/views/SkiaView.web.d.ts +6 -53
- package/lib/typescript/src/views/index.d.ts +1 -0
- package/lib/typescript/src/views/types.d.ts +7 -2
- package/package.json +1 -1
- package/src/views/SkiaBaseWebView.tsx +177 -0
- package/src/views/SkiaPictureView.tsx +93 -0
- package/src/views/SkiaPictureView.web.tsx +23 -0
- package/src/views/SkiaView.tsx +6 -7
- package/src/views/SkiaView.web.tsx +18 -167
- package/src/views/index.ts +1 -0
- package/src/views/types.ts +9 -2
- package/android/cpp/jni/JniSkiaDrawView.cpp +0 -113
- package/android/cpp/rnskia-android/RNSkDrawViewImpl.cpp +0 -73
- package/android/cpp/rnskia-android/RNSkDrawViewImpl.h +0 -48
- package/cpp/rnskia/RNSkDrawView.cpp +0 -315
- package/cpp/rnskia/RNSkDrawView.h +0 -226
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.h +0 -52
- package/ios/RNSkia-iOS/SkiaDrawView.h +0 -23
|
@@ -18,6 +18,7 @@ enum JsiWrapperValueType
|
|
|
18
18
|
Object,
|
|
19
19
|
Function,
|
|
20
20
|
Array,
|
|
21
|
+
HostObject,
|
|
21
22
|
Unknown
|
|
22
23
|
};
|
|
23
24
|
|
|
@@ -64,6 +65,10 @@ public:
|
|
|
64
65
|
_type = JsiWrapperValueType::Array;
|
|
65
66
|
_arrayValue = std::make_shared<jsi::Array>(_objectValue->asArray(runtime));
|
|
66
67
|
_objectValue = nullptr;
|
|
68
|
+
} else if (_objectValue->isHostObject(runtime)) {
|
|
69
|
+
_type = JsiWrapperValueType::HostObject;
|
|
70
|
+
_hostObjectValue = _objectValue->asHostObject(runtime);
|
|
71
|
+
_objectValue = nullptr;
|
|
67
72
|
}
|
|
68
73
|
} else {
|
|
69
74
|
throw std::runtime_error("Could not store jsi::Value of provided type");
|
|
@@ -110,6 +115,11 @@ public:
|
|
|
110
115
|
return _objectValue;
|
|
111
116
|
}
|
|
112
117
|
|
|
118
|
+
std::shared_ptr<jsi::HostObject> getAsHostObject() {
|
|
119
|
+
assert(_type == JsiWrapperValueType::HostObject);
|
|
120
|
+
return _hostObjectValue;
|
|
121
|
+
}
|
|
122
|
+
|
|
113
123
|
JsiWrapperValueType getType() { return _type; }
|
|
114
124
|
|
|
115
125
|
private:
|
|
@@ -121,6 +131,7 @@ private:
|
|
|
121
131
|
std::shared_ptr<jsi::Object> _objectValue;
|
|
122
132
|
std::shared_ptr<jsi::Function> _functionValue;
|
|
123
133
|
std::shared_ptr<jsi::Array> _arrayValue;
|
|
134
|
+
std::shared_ptr<jsi::HostObject> _hostObjectValue;
|
|
124
135
|
|
|
125
136
|
JsiWrapperValueType _type;
|
|
126
137
|
};
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#include <jsi/jsi.h>
|
|
10
10
|
|
|
11
11
|
#include <JsiHostObject.h>
|
|
12
|
+
#include <RNSkView.h>
|
|
12
13
|
|
|
13
14
|
namespace RNSkia {
|
|
14
15
|
|
|
@@ -16,17 +17,6 @@ using namespace facebook;
|
|
|
16
17
|
using namespace RNJsi;
|
|
17
18
|
using namespace std::chrono;
|
|
18
19
|
|
|
19
|
-
enum RNSkTouchType { Start, Active, End, Cancelled };
|
|
20
|
-
|
|
21
|
-
using RNSkTouchPoint = struct {
|
|
22
|
-
double x;
|
|
23
|
-
double y;
|
|
24
|
-
double force;
|
|
25
|
-
RNSkTouchType type;
|
|
26
|
-
size_t id;
|
|
27
|
-
long timestamp;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
20
|
class RNSkInfoObject : public JsiHostObject {
|
|
31
21
|
public:
|
|
32
22
|
JSI_PROPERTY_GET(width) { return _width; }
|
|
@@ -77,7 +67,7 @@ public:
|
|
|
77
67
|
|
|
78
68
|
void endDrawOperation() { _touchesCache.clear(); }
|
|
79
69
|
|
|
80
|
-
void updateTouches(std::vector<
|
|
70
|
+
void updateTouches(std::vector<RNSkTouchInfo>& touches) {
|
|
81
71
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
82
72
|
// Add timestamp
|
|
83
73
|
auto ms = std::chrono::duration_cast<milliseconds>(
|
|
@@ -95,8 +85,8 @@ private:
|
|
|
95
85
|
int _width;
|
|
96
86
|
int _height;
|
|
97
87
|
double _timestamp;
|
|
98
|
-
std::vector<std::vector<
|
|
99
|
-
std::vector<std::vector<
|
|
88
|
+
std::vector<std::vector<RNSkTouchInfo>> _currentTouches;
|
|
89
|
+
std::vector<std::vector<RNSkTouchInfo>> _touchesCache;
|
|
100
90
|
std::mutex _mutex;
|
|
101
91
|
};
|
|
102
92
|
} // namespace RNSkia
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
#include "RNSkJsView.h"
|
|
2
|
+
|
|
3
|
+
namespace RNSkia
|
|
4
|
+
{
|
|
5
|
+
|
|
6
|
+
RNSkJsRenderer::RNSkJsRenderer(std::function<void()> requestRedraw,
|
|
7
|
+
std::shared_ptr<RNSkPlatformContext> context) :
|
|
8
|
+
RNSkRenderer(requestRedraw),
|
|
9
|
+
_jsiCanvas(std::make_shared<JsiSkCanvas>(context)),
|
|
10
|
+
_platformContext(std::move(context)),
|
|
11
|
+
_infoObject(std::make_shared<RNSkInfoObject>()),
|
|
12
|
+
_jsDrawingLock(std::make_shared<std::timed_mutex>()),
|
|
13
|
+
_gpuDrawingLock(std::make_shared<std::timed_mutex>()),
|
|
14
|
+
_jsTimingInfo("SKIA/JS"),
|
|
15
|
+
_gpuTimingInfo("SKIA/GPU") {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
bool RNSkJsRenderer::tryRender(std::shared_ptr<RNSkCanvasProvider> canvasProvider) {
|
|
19
|
+
// We render on the javascript thread.
|
|
20
|
+
if(_jsDrawingLock->try_lock()) {
|
|
21
|
+
_platformContext->runOnJavascriptThread([weakSelf = weak_from_this(), canvasProvider](){
|
|
22
|
+
auto self = weakSelf.lock();
|
|
23
|
+
if(self) {
|
|
24
|
+
self->performDraw(canvasProvider);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return true;
|
|
28
|
+
} else {
|
|
29
|
+
#ifdef DEBUG
|
|
30
|
+
_jsTimingInfo.markSkipped();
|
|
31
|
+
#endif
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
void RNSkJsRenderer::renderImmediate(std::shared_ptr<RNSkCanvasProvider> canvasProvider) {
|
|
37
|
+
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
|
|
38
|
+
canvasProvider->renderToCanvas([&](SkCanvas* canvas) {
|
|
39
|
+
// Create jsi canvas
|
|
40
|
+
auto jsiCanvas = std::make_shared<JsiSkCanvas>(_platformContext);
|
|
41
|
+
jsiCanvas->setCanvas(canvas);
|
|
42
|
+
|
|
43
|
+
drawInJsiCanvas(std::move(jsiCanvas),
|
|
44
|
+
canvasProvider->getScaledWidth(),
|
|
45
|
+
canvasProvider->getScaledHeight(),
|
|
46
|
+
ms.count() / 1000);
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
void RNSkJsRenderer::setDrawCallback(std::shared_ptr<jsi::Function> drawCallback) {
|
|
51
|
+
_drawCallback = drawCallback;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
std::shared_ptr<RNSkInfoObject> RNSkJsRenderer::getInfoObject() {
|
|
55
|
+
return _infoObject;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void RNSkJsRenderer::performDraw(std::shared_ptr<RNSkCanvasProvider> canvasProvider) {
|
|
59
|
+
// Start timing
|
|
60
|
+
_jsTimingInfo.beginTiming();
|
|
61
|
+
|
|
62
|
+
// Record the drawing operations on the JS thread so that we can
|
|
63
|
+
// move the actual drawing onto the render thread later
|
|
64
|
+
SkPictureRecorder recorder;
|
|
65
|
+
SkRTreeFactory factory;
|
|
66
|
+
SkCanvas* canvas = recorder.beginRecording(canvasProvider->getScaledWidth(),
|
|
67
|
+
canvasProvider->getScaledHeight(),
|
|
68
|
+
&factory);
|
|
69
|
+
|
|
70
|
+
_jsiCanvas->setCanvas(canvas);
|
|
71
|
+
|
|
72
|
+
// Get current milliseconds
|
|
73
|
+
milliseconds ms = duration_cast<milliseconds>(
|
|
74
|
+
system_clock::now().time_since_epoch());
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
// Perform the javascript drawing
|
|
78
|
+
drawInJsiCanvas(_jsiCanvas,
|
|
79
|
+
canvasProvider->getScaledWidth(),
|
|
80
|
+
canvasProvider->getScaledHeight(),
|
|
81
|
+
ms.count() / 1000.0);
|
|
82
|
+
|
|
83
|
+
} catch(...) {
|
|
84
|
+
_jsTimingInfo.stopTiming();
|
|
85
|
+
_jsDrawingLock->unlock();
|
|
86
|
+
throw;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Finish drawing operations
|
|
90
|
+
auto p = recorder.finishRecordingAsPicture();
|
|
91
|
+
|
|
92
|
+
_jsiCanvas->setCanvas(nullptr);
|
|
93
|
+
|
|
94
|
+
// Calculate duration
|
|
95
|
+
_jsTimingInfo.stopTiming();
|
|
96
|
+
|
|
97
|
+
if(_gpuDrawingLock->try_lock()) {
|
|
98
|
+
|
|
99
|
+
// Post drawing message to the render thread where the picture recorded
|
|
100
|
+
// will be sent to the GPU/backend for rendering to screen.
|
|
101
|
+
auto gpuLock = _gpuDrawingLock;
|
|
102
|
+
_platformContext->runOnRenderThread([weakSelf = weak_from_this(), p = std::move(p), gpuLock, canvasProvider]() {
|
|
103
|
+
auto self = weakSelf.lock();
|
|
104
|
+
if (self) {
|
|
105
|
+
// Draw the picture recorded on the real GPU canvas
|
|
106
|
+
self->_gpuTimingInfo.beginTiming();
|
|
107
|
+
|
|
108
|
+
canvasProvider->renderToCanvas([p = std::move(p)](SkCanvas* canvas) {
|
|
109
|
+
canvas->drawPicture(p);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
self->_gpuTimingInfo.stopTiming();
|
|
113
|
+
}
|
|
114
|
+
// Unlock GPU drawing
|
|
115
|
+
gpuLock->unlock();
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
#ifdef DEBUG
|
|
119
|
+
_gpuTimingInfo.markSkipped();
|
|
120
|
+
#endif
|
|
121
|
+
// Request a new redraw since the last frame was skipped.
|
|
122
|
+
_requestRedraw();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Unlock JS drawing
|
|
126
|
+
_jsDrawingLock->unlock();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
void RNSkJsRenderer::callJsDrawCallback(std::shared_ptr<JsiSkCanvas> jsiCanvas,
|
|
130
|
+
int width,
|
|
131
|
+
int height,
|
|
132
|
+
double timestamp) {
|
|
133
|
+
|
|
134
|
+
if(_drawCallback == nullptr) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Reset timing info
|
|
139
|
+
_jsTimingInfo.reset();
|
|
140
|
+
_gpuTimingInfo.reset();
|
|
141
|
+
|
|
142
|
+
auto runtime = _platformContext->getJsRuntime();
|
|
143
|
+
|
|
144
|
+
// Update info parameter
|
|
145
|
+
_infoObject->beginDrawOperation(width, height, timestamp);
|
|
146
|
+
|
|
147
|
+
// Set up arguments array
|
|
148
|
+
std::vector<jsi::Value> args(2);
|
|
149
|
+
args[0] = jsi::Object::createFromHostObject(*runtime, jsiCanvas);
|
|
150
|
+
args[1] = jsi::Object::createFromHostObject(*runtime, _infoObject);
|
|
151
|
+
|
|
152
|
+
// To be able to call the drawing function we'll wrap it once again
|
|
153
|
+
_drawCallback->call(*runtime,
|
|
154
|
+
static_cast<const jsi::Value *>(args.data()),
|
|
155
|
+
(size_t)2);
|
|
156
|
+
|
|
157
|
+
// Reset touches
|
|
158
|
+
_infoObject->endDrawOperation();
|
|
159
|
+
|
|
160
|
+
// Draw debug overlays
|
|
161
|
+
if (getShowDebugOverlays()) {
|
|
162
|
+
|
|
163
|
+
// Display average rendering timer
|
|
164
|
+
auto jsAvg = _jsTimingInfo.getAverage();
|
|
165
|
+
//auto jsFps = _jsTimingInfo.getFps();
|
|
166
|
+
|
|
167
|
+
auto gpuAvg = _gpuTimingInfo.getAverage();
|
|
168
|
+
//auto gpuFps = _gpuTimingInfo.getFps();
|
|
169
|
+
|
|
170
|
+
auto total = jsAvg + gpuAvg;
|
|
171
|
+
|
|
172
|
+
// Build string
|
|
173
|
+
std::ostringstream stream;
|
|
174
|
+
stream << "js: " << jsAvg << "ms gpu: " << gpuAvg << "ms " << " total: " << total << "ms";
|
|
175
|
+
|
|
176
|
+
std::string debugString = stream.str();
|
|
177
|
+
|
|
178
|
+
// Set up debug font/paints
|
|
179
|
+
auto font = SkFont();
|
|
180
|
+
font.setSize(14);
|
|
181
|
+
auto paint = SkPaint();
|
|
182
|
+
paint.setColor(SkColors::kRed);
|
|
183
|
+
jsiCanvas->getCanvas()->drawSimpleText(
|
|
184
|
+
debugString.c_str(), debugString.size(), SkTextEncoding::kUTF8, 8,
|
|
185
|
+
18, font, paint);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
void RNSkJsRenderer::drawInJsiCanvas(std::shared_ptr<JsiSkCanvas> jsiCanvas,
|
|
190
|
+
int width,
|
|
191
|
+
int height,
|
|
192
|
+
double time) {
|
|
193
|
+
|
|
194
|
+
// Call the draw drawCallback and perform js based drawing
|
|
195
|
+
auto skCanvas = jsiCanvas->getCanvas();
|
|
196
|
+
if (_drawCallback != nullptr && skCanvas != nullptr) {
|
|
197
|
+
// Make sure to scale correctly
|
|
198
|
+
auto pd = _platformContext->getPixelDensity();
|
|
199
|
+
skCanvas->save();
|
|
200
|
+
skCanvas->scale(pd, pd);
|
|
201
|
+
|
|
202
|
+
// Call draw function.
|
|
203
|
+
callJsDrawCallback(jsiCanvas, width / pd, height / pd, time);
|
|
204
|
+
|
|
205
|
+
// Restore and flush canvas
|
|
206
|
+
skCanvas->restore();
|
|
207
|
+
skCanvas->flush();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
} // Namespace RNSkia
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <functional>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <mutex>
|
|
6
|
+
#include <vector>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
#include <jsi/jsi.h>
|
|
10
|
+
|
|
11
|
+
#include <JsiValueWrapper.h>
|
|
12
|
+
#include <RNSkView.h>
|
|
13
|
+
|
|
14
|
+
#include <RNSkInfoParameter.h>
|
|
15
|
+
#include <RNSkPlatformContext.h>
|
|
16
|
+
#include <RNSkTimingInfo.h>
|
|
17
|
+
#include <RNSkLog.h>
|
|
18
|
+
#include <JsiSkCanvas.h>
|
|
19
|
+
|
|
20
|
+
#pragma clang diagnostic push
|
|
21
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
22
|
+
|
|
23
|
+
#include <SkCanvas.h>
|
|
24
|
+
#include <SkBBHFactory.h>
|
|
25
|
+
#include <SkPictureRecorder.h>
|
|
26
|
+
|
|
27
|
+
#pragma clang diagnostic pop
|
|
28
|
+
|
|
29
|
+
class SkPicture;
|
|
30
|
+
class SkRect;
|
|
31
|
+
class SkImage;
|
|
32
|
+
|
|
33
|
+
namespace RNSkia {
|
|
34
|
+
class JsiSkCanvas;
|
|
35
|
+
using namespace facebook;
|
|
36
|
+
|
|
37
|
+
class RNSkJsRenderer:
|
|
38
|
+
public RNSkRenderer,
|
|
39
|
+
public std::enable_shared_from_this<RNSkJsRenderer> {
|
|
40
|
+
public:
|
|
41
|
+
RNSkJsRenderer(std::function<void()> requestRedraw,
|
|
42
|
+
std::shared_ptr<RNSkPlatformContext> context);
|
|
43
|
+
|
|
44
|
+
bool tryRender(std::shared_ptr<RNSkCanvasProvider> canvasProvider) override;
|
|
45
|
+
|
|
46
|
+
void renderImmediate(std::shared_ptr<RNSkCanvasProvider> canvasProvider) override;
|
|
47
|
+
|
|
48
|
+
void setDrawCallback(std::shared_ptr<jsi::Function> drawCallback);
|
|
49
|
+
|
|
50
|
+
std::shared_ptr<RNSkInfoObject> getInfoObject();
|
|
51
|
+
|
|
52
|
+
private:
|
|
53
|
+
void performDraw(std::shared_ptr<RNSkCanvasProvider> canvasProvider);
|
|
54
|
+
|
|
55
|
+
void callJsDrawCallback(std::shared_ptr<JsiSkCanvas> jsiCanvas,
|
|
56
|
+
int width,
|
|
57
|
+
int height,
|
|
58
|
+
double timestamp);
|
|
59
|
+
|
|
60
|
+
void drawInJsiCanvas(std::shared_ptr<JsiSkCanvas> jsiCanvas,
|
|
61
|
+
int width,
|
|
62
|
+
int height,
|
|
63
|
+
double time);
|
|
64
|
+
|
|
65
|
+
std::shared_ptr<RNSkPlatformContext> _platformContext;
|
|
66
|
+
std::shared_ptr<jsi::Function> _drawCallback;
|
|
67
|
+
std::shared_ptr<JsiSkCanvas> _jsiCanvas;
|
|
68
|
+
std::shared_ptr<std::timed_mutex> _jsDrawingLock;
|
|
69
|
+
std::shared_ptr<std::timed_mutex> _gpuDrawingLock;
|
|
70
|
+
std::shared_ptr<RNSkInfoObject> _infoObject;
|
|
71
|
+
RNSkTimingInfo _jsTimingInfo;
|
|
72
|
+
RNSkTimingInfo _gpuTimingInfo;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
class RNSkJsView: public RNSkView {
|
|
76
|
+
public:
|
|
77
|
+
/**
|
|
78
|
+
* Constructor
|
|
79
|
+
*/
|
|
80
|
+
RNSkJsView(std::shared_ptr<RNSkPlatformContext> context,
|
|
81
|
+
std::shared_ptr<RNSkCanvasProvider> canvasProvider):
|
|
82
|
+
RNSkView(context,
|
|
83
|
+
canvasProvider,
|
|
84
|
+
std::make_shared<RNSkJsRenderer>(std::bind(&RNSkJsView::requestRedraw, this), context)) {}
|
|
85
|
+
|
|
86
|
+
void updateTouchState(std::vector<RNSkTouchInfo>& touches) override {
|
|
87
|
+
std::static_pointer_cast<RNSkJsRenderer>(getRenderer())->getInfoObject()->updateTouches(touches);
|
|
88
|
+
RNSkView::updateTouchState(touches);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void setJsiProperties(std::unordered_map<std::string, JsiValueWrapper> &props) override {
|
|
92
|
+
for(auto& prop: props) {
|
|
93
|
+
if(prop.first == "drawCallback") {
|
|
94
|
+
if(prop.second.isUndefinedOrNull()) {
|
|
95
|
+
// Clear drawcallback
|
|
96
|
+
std::static_pointer_cast<RNSkJsRenderer>(getRenderer())->setDrawCallback(nullptr);
|
|
97
|
+
return;
|
|
98
|
+
} else if (prop.second.getType() != JsiWrapperValueType::Function) {
|
|
99
|
+
// We expect a function for the draw callback custom property
|
|
100
|
+
throw std::runtime_error("Expected a function for the drawCallback custom property.");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Save callback
|
|
104
|
+
std::static_pointer_cast<RNSkJsRenderer>(getRenderer())->setDrawCallback(prop.second.getAsFunction());
|
|
105
|
+
|
|
106
|
+
// Request redraw
|
|
107
|
+
requestRedraw();
|
|
108
|
+
|
|
109
|
+
} else {
|
|
110
|
+
RNSkView::setJsiProperties(props);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
} // namespace RNSkia
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
#include <JsiHostObject.h>
|
|
10
10
|
#include <JsiValueWrapper.h>
|
|
11
|
-
#include <
|
|
11
|
+
#include <RNSkView.h>
|
|
12
12
|
#include <RNSkPlatformContext.h>
|
|
13
13
|
#include <RNSkValue.h>
|
|
14
14
|
#include <jsi/jsi.h>
|
|
@@ -20,7 +20,7 @@ using RNSkViewInfo = struct RNSkViewInfo {
|
|
|
20
20
|
RNSkViewInfo() {
|
|
21
21
|
view = nullptr;
|
|
22
22
|
}
|
|
23
|
-
std::shared_ptr<
|
|
23
|
+
std::shared_ptr<RNSkView> view;
|
|
24
24
|
std::unordered_map<std::string, JsiValueWrapper> props;
|
|
25
25
|
};
|
|
26
26
|
|
|
@@ -243,7 +243,7 @@ public:
|
|
|
243
243
|
// Unregister all views
|
|
244
244
|
auto tempList = _viewInfos;
|
|
245
245
|
for (const auto& info : tempList) {
|
|
246
|
-
|
|
246
|
+
unregisterSkiaView(info.first);
|
|
247
247
|
}
|
|
248
248
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
249
249
|
_viewInfos.clear();
|
|
@@ -254,7 +254,7 @@ public:
|
|
|
254
254
|
* @param nativeId Id of view to register
|
|
255
255
|
* @param view View to register
|
|
256
256
|
*/
|
|
257
|
-
void
|
|
257
|
+
void registerSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view) {
|
|
258
258
|
auto info = getEnsuredViewInfo(nativeId);
|
|
259
259
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
260
260
|
info->view = view;
|
|
@@ -267,7 +267,7 @@ public:
|
|
|
267
267
|
* Unregisters a Skia draw view
|
|
268
268
|
* @param nativeId View id
|
|
269
269
|
*/
|
|
270
|
-
void
|
|
270
|
+
void unregisterSkiaView(size_t nativeId) {
|
|
271
271
|
if (_viewInfos.count(nativeId) == 0) {
|
|
272
272
|
return;
|
|
273
273
|
}
|
|
@@ -284,7 +284,7 @@ public:
|
|
|
284
284
|
removed due to ex. a transition). The view can be set to a nullptr
|
|
285
285
|
or a valid view, effectively toggling the view's availability.
|
|
286
286
|
*/
|
|
287
|
-
void
|
|
287
|
+
void setSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view) {
|
|
288
288
|
if (_viewInfos.find(nativeId) == _viewInfos.end()) {
|
|
289
289
|
return;
|
|
290
290
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#include <JsiSkApi.h>
|
|
9
9
|
#include <RNSkJsiViewApi.h>
|
|
10
|
-
#include <
|
|
10
|
+
#include <RNSkView.h>
|
|
11
11
|
#include <RNSkValueApi.h>
|
|
12
12
|
|
|
13
13
|
namespace RNSkia {
|
|
@@ -45,19 +45,19 @@ void RNSkManager::invalidate() {
|
|
|
45
45
|
_platformContext->invalidate();
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
void RNSkManager::
|
|
48
|
+
void RNSkManager::registerSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view) {
|
|
49
49
|
if (!_isInvalidated && _viewApi != nullptr)
|
|
50
|
-
_viewApi->
|
|
50
|
+
_viewApi->registerSkiaView(nativeId, view);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
void RNSkManager::
|
|
53
|
+
void RNSkManager::unregisterSkiaView(size_t nativeId) {
|
|
54
54
|
if (!_isInvalidated && _viewApi != nullptr)
|
|
55
|
-
_viewApi->
|
|
55
|
+
_viewApi->unregisterSkiaView(nativeId);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
void RNSkManager::
|
|
58
|
+
void RNSkManager::setSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view) {
|
|
59
59
|
if (!_isInvalidated && _viewApi != nullptr)
|
|
60
|
-
_viewApi->
|
|
60
|
+
_viewApi->setSkiaView(nativeId, view);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
void RNSkManager::installBindings() {
|
package/cpp/rnskia/RNSkManager.h
CHANGED
|
@@ -12,7 +12,7 @@ namespace facebook {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
namespace RNSkia {
|
|
15
|
-
class
|
|
15
|
+
class RNSkView;
|
|
16
16
|
class RNSkJsiViewApi;
|
|
17
17
|
using namespace facebook;
|
|
18
18
|
|
|
@@ -37,24 +37,24 @@ public:
|
|
|
37
37
|
void invalidate();
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Registers a
|
|
40
|
+
* Registers a RNSkView with the given native id
|
|
41
41
|
* @param nativeId Native view id
|
|
42
42
|
* @param view View to register
|
|
43
43
|
*/
|
|
44
|
-
void
|
|
44
|
+
void registerSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view);
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* Unregisters the
|
|
47
|
+
* Unregisters the RNSkView from the list of registered views
|
|
48
48
|
* @param nativeId Native view Id
|
|
49
49
|
*/
|
|
50
|
-
void
|
|
50
|
+
void unregisterSkiaView(size_t nativeId);
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
Sets the view pointed to by nativeId to the provided value.
|
|
54
54
|
Used when we want to remove a view without unregistering it
|
|
55
55
|
- this happens typically on iOS.
|
|
56
56
|
*/
|
|
57
|
-
void
|
|
57
|
+
void setSkiaView(size_t nativeId, std::shared_ptr<RNSkView> view);
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* @return The platform context
|
|
@@ -66,7 +66,7 @@ public:
|
|
|
66
66
|
private:
|
|
67
67
|
/**
|
|
68
68
|
* Installs the javascript methods for registering/unregistering draw
|
|
69
|
-
* callbacks for
|
|
69
|
+
* callbacks for RNSkViews. Called on installation of the parent native
|
|
70
70
|
* module.
|
|
71
71
|
*/
|
|
72
72
|
void installBindings();
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <functional>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <mutex>
|
|
6
|
+
#include <vector>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
#include <jsi/jsi.h>
|
|
10
|
+
|
|
11
|
+
#include <JsiValueWrapper.h>
|
|
12
|
+
#include <RNSkView.h>
|
|
13
|
+
|
|
14
|
+
#include <RNSkInfoParameter.h>
|
|
15
|
+
#include <RNSkPlatformContext.h>
|
|
16
|
+
#include <RNSkTimingInfo.h>
|
|
17
|
+
#include <RNSkLog.h>
|
|
18
|
+
#include <JsiSkPicture.h>
|
|
19
|
+
|
|
20
|
+
#pragma clang diagnostic push
|
|
21
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
22
|
+
|
|
23
|
+
#include <SkCanvas.h>
|
|
24
|
+
#include <SkBBHFactory.h>
|
|
25
|
+
#include <SkPictureRecorder.h>
|
|
26
|
+
|
|
27
|
+
#pragma clang diagnostic pop
|
|
28
|
+
|
|
29
|
+
class SkPicture;
|
|
30
|
+
class SkRect;
|
|
31
|
+
class SkImage;
|
|
32
|
+
|
|
33
|
+
namespace RNSkia {
|
|
34
|
+
|
|
35
|
+
using namespace facebook;
|
|
36
|
+
|
|
37
|
+
class RNSkPictureRenderer:
|
|
38
|
+
public RNSkRenderer,
|
|
39
|
+
public std::enable_shared_from_this<RNSkPictureRenderer> {
|
|
40
|
+
public:
|
|
41
|
+
RNSkPictureRenderer(std::function<void()> requestRedraw,
|
|
42
|
+
std::shared_ptr<RNSkPlatformContext> context):
|
|
43
|
+
RNSkRenderer(requestRedraw),
|
|
44
|
+
_platformContext(context) {}
|
|
45
|
+
|
|
46
|
+
bool tryRender(std::shared_ptr<RNSkCanvasProvider> canvasProvider) override {
|
|
47
|
+
performDraw(canvasProvider);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
void renderImmediate(std::shared_ptr<RNSkCanvasProvider> canvasProvider) override {
|
|
52
|
+
performDraw(canvasProvider);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
void setPicture(std::shared_ptr<jsi::HostObject> picture) {
|
|
56
|
+
if(picture == nullptr) {
|
|
57
|
+
_picture = nullptr;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_picture = std::dynamic_pointer_cast<JsiSkPicture>(picture);
|
|
62
|
+
_requestRedraw();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private:
|
|
66
|
+
void performDraw(std::shared_ptr<RNSkCanvasProvider> canvasProvider) {
|
|
67
|
+
if(_picture == nullptr) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
canvasProvider->renderToCanvas([=](SkCanvas* canvas){
|
|
72
|
+
// Make sure to scale correctly
|
|
73
|
+
auto pd = _platformContext->getPixelDensity();
|
|
74
|
+
canvas->save();
|
|
75
|
+
canvas->scale(pd, pd);
|
|
76
|
+
|
|
77
|
+
canvas->drawPicture(_picture->getObject());
|
|
78
|
+
|
|
79
|
+
// Restore and flush canvas
|
|
80
|
+
canvas->restore();
|
|
81
|
+
canvas->flush();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
std::shared_ptr<RNSkPlatformContext> _platformContext;
|
|
86
|
+
std::shared_ptr<JsiSkPicture> _picture;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
class RNSkPictureView: public RNSkView {
|
|
90
|
+
public:
|
|
91
|
+
/**
|
|
92
|
+
* Constructor
|
|
93
|
+
*/
|
|
94
|
+
RNSkPictureView(std::shared_ptr<RNSkPlatformContext> context,
|
|
95
|
+
std::shared_ptr<RNSkCanvasProvider> canvasProvider):
|
|
96
|
+
RNSkView(context,
|
|
97
|
+
canvasProvider,
|
|
98
|
+
std::make_shared<RNSkPictureRenderer>(std::bind(&RNSkPictureView::requestRedraw, this), context)) {}
|
|
99
|
+
|
|
100
|
+
void setJsiProperties(std::unordered_map<std::string, JsiValueWrapper> &props) override {
|
|
101
|
+
for(auto& prop: props) {
|
|
102
|
+
if(prop.first == "picture") {
|
|
103
|
+
if(prop.second.isUndefinedOrNull()) {
|
|
104
|
+
// Clear picture
|
|
105
|
+
std::static_pointer_cast<RNSkPictureRenderer>(getRenderer())->setPicture(nullptr);
|
|
106
|
+
return;
|
|
107
|
+
} else if (prop.second.getType() != JsiWrapperValueType::HostObject) {
|
|
108
|
+
// We expect a function for the picture custom property
|
|
109
|
+
throw std::runtime_error("Expected an object for the picture custom property.");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Save picture
|
|
113
|
+
std::static_pointer_cast<RNSkPictureRenderer>(getRenderer())->setPicture(prop.second.getAsHostObject());
|
|
114
|
+
|
|
115
|
+
// Request redraw
|
|
116
|
+
requestRedraw();
|
|
117
|
+
|
|
118
|
+
} else {
|
|
119
|
+
RNSkView::setJsiProperties(props);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
} // namespace RNSkia
|