@shopify/react-native-skia 0.1.121 → 0.1.124
Sign up to get free protection for your applications and to get access to all the features.
- package/android/CMakeLists.txt +3 -1
- package/android/cpp/jni/JniSkiaDrawView.cpp +14 -71
- package/android/cpp/jni/JniSkiaManager.cpp +1 -1
- package/android/cpp/jni/include/JniSkiaDrawView.h +18 -22
- package/android/cpp/jni/include/JniSkiaManager.h +4 -4
- package/android/cpp/rnskia-android/RNSkDrawViewImpl.cpp +68 -0
- package/android/cpp/rnskia-android/RNSkDrawViewImpl.h +48 -0
- package/android/cpp/{jni/include/JniPlatformContextWrapper.h → rnskia-android/RNSkPlatformContextImpl.h} +4 -4
- package/android/cpp/{jni → rnskia-android}/SkiaOpenGLRenderer.cpp +39 -54
- package/android/cpp/{jni/include → rnskia-android}/SkiaOpenGLRenderer.h +2 -31
- package/android/src/main/java/com/shopify/reactnative/skia/RNSkiaViewManager.java +1 -1
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java +21 -28
- package/cpp/api/JsiSkApi.h +2 -0
- package/cpp/api/JsiSkColor.h +49 -0
- package/cpp/api/JsiSkPath.h +31 -2
- package/cpp/api/JsiSkPathFactory.h +96 -1
- package/cpp/api/third_party/CSSColorParser.h +324 -0
- package/cpp/rnskia/RNSkAnimation.h +3 -8
- package/cpp/rnskia/RNSkDrawView.cpp +84 -126
- package/cpp/rnskia/RNSkDrawView.h +7 -37
- package/cpp/rnskia/RNSkJsiViewApi.h +8 -5
- package/cpp/rnskia/RNSkManager.cpp +2 -2
- package/cpp/rnskia/RNSkManager.h +2 -2
- package/cpp/rnskia/RNSkPlatformContext.h +1 -1
- package/cpp/rnskia/RNSkValueApi.h +6 -2
- package/cpp/rnskia/values/RNSkClockValue.h +21 -13
- package/cpp/rnskia/values/RNSkDerivedValue.h +13 -6
- package/cpp/rnskia/values/RNSkReadonlyValue.h +17 -16
- package/cpp/rnskia/values/RNSkValue.h +8 -3
- package/cpp/utils/RNSkTimingInfo.h +13 -1
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.h +8 -10
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.mm +25 -10
- package/ios/RNSkia-iOS/SkiaDrawView.mm +21 -16
- package/lib/commonjs/renderer/Canvas.js +17 -8
- package/lib/commonjs/renderer/Canvas.js.map +1 -1
- package/lib/commonjs/renderer/components/Paint.js +1 -1
- package/lib/commonjs/renderer/components/Paint.js.map +1 -1
- package/lib/commonjs/renderer/components/colorFilters/Lerp.js +1 -1
- package/lib/commonjs/renderer/components/colorFilters/Lerp.js.map +1 -1
- package/lib/commonjs/renderer/components/shaders/Shader.js +2 -2
- package/lib/commonjs/renderer/components/shaders/Shader.js.map +1 -1
- package/lib/commonjs/renderer/components/shapes/Path.js +10 -2
- package/lib/commonjs/renderer/components/shapes/Path.js.map +1 -1
- package/lib/commonjs/renderer/nodes/Node.js +3 -3
- package/lib/commonjs/renderer/nodes/Node.js.map +1 -1
- package/lib/commonjs/renderer/processors/Circles.js +3 -2
- package/lib/commonjs/renderer/processors/Circles.js.map +1 -1
- package/lib/commonjs/renderer/processors/Font.js +1 -1
- package/lib/commonjs/renderer/processors/Font.js.map +1 -1
- package/lib/commonjs/renderer/processors/Paint.js +6 -1
- package/lib/commonjs/renderer/processors/Paint.js.map +1 -1
- package/lib/commonjs/renderer/processors/Rects.js +6 -6
- package/lib/commonjs/renderer/processors/Rects.js.map +1 -1
- package/lib/commonjs/skia/Color.js +3 -25
- package/lib/commonjs/skia/Color.js.map +1 -1
- package/lib/commonjs/skia/Image/Image.js.map +1 -1
- package/lib/commonjs/skia/ImageFilter/ImageFilterFactory.js.map +1 -1
- package/lib/commonjs/skia/Paint/Paint.js +13 -1
- package/lib/commonjs/skia/Paint/Paint.js.map +1 -1
- package/lib/commonjs/skia/Paint/usePaint.js +2 -4
- package/lib/commonjs/skia/Paint/usePaint.js.map +1 -1
- package/lib/commonjs/skia/Path/Path.js +13 -1
- package/lib/commonjs/skia/Path/Path.js.map +1 -1
- package/lib/commonjs/skia/Shader/Shader.js.map +1 -1
- package/lib/commonjs/skia/Skia.js +43 -3
- package/lib/commonjs/skia/Skia.js.map +1 -1
- package/lib/commonjs/values/animation/timing/functions/getResolvedParams.js +3 -3
- package/lib/commonjs/values/animation/timing/functions/getResolvedParams.js.map +1 -1
- package/lib/module/renderer/Canvas.js +12 -6
- package/lib/module/renderer/Canvas.js.map +1 -1
- package/lib/module/renderer/components/Paint.js +2 -2
- package/lib/module/renderer/components/Paint.js.map +1 -1
- package/lib/module/renderer/components/colorFilters/Lerp.js +1 -1
- package/lib/module/renderer/components/colorFilters/Lerp.js.map +1 -1
- package/lib/module/renderer/components/shaders/Shader.js +3 -2
- package/lib/module/renderer/components/shaders/Shader.js.map +1 -1
- package/lib/module/renderer/components/shapes/Path.js +10 -3
- package/lib/module/renderer/components/shapes/Path.js.map +1 -1
- package/lib/module/renderer/nodes/Node.js +3 -3
- package/lib/module/renderer/nodes/Node.js.map +1 -1
- package/lib/module/renderer/processors/Circles.js +3 -2
- package/lib/module/renderer/processors/Circles.js.map +1 -1
- package/lib/module/renderer/processors/Font.js +1 -1
- package/lib/module/renderer/processors/Font.js.map +1 -1
- package/lib/module/renderer/processors/Paint.js +6 -1
- package/lib/module/renderer/processors/Paint.js.map +1 -1
- package/lib/module/renderer/processors/Rects.js +5 -6
- package/lib/module/renderer/processors/Rects.js.map +1 -1
- package/lib/module/skia/Color.js +2 -21
- package/lib/module/skia/Color.js.map +1 -1
- package/lib/module/skia/Image/Image.js.map +1 -1
- package/lib/module/skia/ImageFilter/ImageFilterFactory.js.map +1 -1
- package/lib/module/skia/Paint/Paint.js +6 -0
- package/lib/module/skia/Paint/Paint.js.map +1 -1
- package/lib/module/skia/Paint/usePaint.js +2 -3
- package/lib/module/skia/Paint/usePaint.js.map +1 -1
- package/lib/module/skia/Path/Path.js +11 -0
- package/lib/module/skia/Path/Path.js.map +1 -1
- package/lib/module/skia/Shader/Shader.js.map +1 -1
- package/lib/module/skia/Skia.js +45 -2
- package/lib/module/skia/Skia.js.map +1 -1
- package/lib/module/values/animation/timing/functions/getResolvedParams.js +3 -3
- package/lib/module/values/animation/timing/functions/getResolvedParams.js.map +1 -1
- package/lib/typescript/src/renderer/Canvas.d.ts +6 -0
- package/lib/typescript/src/renderer/components/shapes/Path.d.ts +3 -1
- package/lib/typescript/src/renderer/processors/Paint.d.ts +2 -1
- package/lib/typescript/src/skia/Color.d.ts +0 -1
- package/lib/typescript/src/skia/Image/Image.d.ts +3 -3
- package/lib/typescript/src/skia/ImageFilter/ImageFilterFactory.d.ts +2 -2
- package/lib/typescript/src/skia/Paint/Paint.d.ts +3 -2
- package/lib/typescript/src/skia/Path/Path.d.ts +13 -0
- package/lib/typescript/src/skia/Path/PathFactory.d.ts +7 -1
- package/lib/typescript/src/skia/Picture/Picture.d.ts +2 -2
- package/lib/typescript/src/skia/RuntimeEffect/RuntimeEffect.d.ts +3 -3
- package/lib/typescript/src/skia/Shader/Shader.d.ts +2 -2
- package/lib/typescript/src/skia/Shader/ShaderFactory.d.ts +9 -9
- package/lib/typescript/src/skia/Skia.d.ts +5 -3
- package/lib/typescript/src/values/animation/types.d.ts +5 -5
- package/package.json +1 -1
- package/scripts/install-npm.js +1 -1
- package/src/renderer/Canvas.tsx +13 -6
- package/src/renderer/components/Paint.tsx +2 -2
- package/src/renderer/components/colorFilters/Lerp.tsx +1 -1
- package/src/renderer/components/shaders/Shader.tsx +1 -1
- package/src/renderer/components/shapes/Path.tsx +12 -4
- package/src/renderer/nodes/Node.ts +3 -3
- package/src/renderer/processors/Circles.ts +2 -1
- package/src/renderer/processors/Font.ts +1 -1
- package/src/renderer/processors/Paint.ts +5 -0
- package/src/renderer/processors/Rects.ts +3 -2
- package/src/skia/Color.ts +3 -20
- package/src/skia/Image/Image.ts +3 -3
- package/src/skia/ImageFilter/ImageFilterFactory.ts +2 -2
- package/src/skia/Paint/Paint.ts +9 -2
- package/src/skia/Paint/usePaint.ts +2 -4
- package/src/skia/Path/Path.ts +16 -0
- package/src/skia/Path/PathFactory.ts +8 -1
- package/src/skia/Picture/Picture.ts +2 -2
- package/src/skia/RuntimeEffect/RuntimeEffect.ts +4 -4
- package/src/skia/Shader/Shader.ts +2 -2
- package/src/skia/Shader/ShaderFactory.ts +9 -9
- package/src/skia/Skia.ts +47 -3
- package/src/values/animation/timing/functions/getResolvedParams.ts +2 -2
- package/src/values/animation/types.ts +5 -5
@@ -15,7 +15,7 @@ using namespace facebook;
|
|
15
15
|
/**
|
16
16
|
Implements an animation that can be used to drive other values
|
17
17
|
*/
|
18
|
-
class RNSkAnimation : public RNSkClockValue
|
18
|
+
class RNSkAnimation : public RNSkClockValue
|
19
19
|
{
|
20
20
|
|
21
21
|
public:
|
@@ -23,8 +23,8 @@ public:
|
|
23
23
|
size_t identifier,
|
24
24
|
jsi::Runtime& runtime,
|
25
25
|
const jsi::Value *arguments,
|
26
|
-
size_t count)
|
27
|
-
|
26
|
+
size_t count) :
|
27
|
+
RNSkClockValue(platformContext, identifier, runtime, arguments, count) {
|
28
28
|
// Save the update function
|
29
29
|
_updateFunction = std::make_shared<jsi::Function>(arguments[0].asObject(runtime).asFunction(runtime));
|
30
30
|
|
@@ -32,11 +32,6 @@ public:
|
|
32
32
|
_args[1] = jsi::Value::undefined();
|
33
33
|
}
|
34
34
|
|
35
|
-
~RNSkAnimation() {
|
36
|
-
// We need to stop/unsubscribe
|
37
|
-
stopClock();
|
38
|
-
}
|
39
|
-
|
40
35
|
JSI_HOST_FUNCTION(cancel) {
|
41
36
|
stopClock();
|
42
37
|
return jsi::Value::undefined();
|
@@ -40,31 +40,13 @@ RNSkDrawView::RNSkDrawView(std::shared_ptr<RNSkPlatformContext> context)
|
|
40
40
|
_platformContext(std::move(context)),
|
41
41
|
_infoObject(std::make_shared<RNSkInfoObject>()),
|
42
42
|
_jsDrawingLock(std::make_shared<std::timed_mutex>()),
|
43
|
-
_gpuDrawingLock(std::make_shared<std::timed_mutex>())
|
43
|
+
_gpuDrawingLock(std::make_shared<std::timed_mutex>()),
|
44
|
+
_jsTimingInfo("SKIA/JS"),
|
45
|
+
_gpuTimingInfo("SKIA/GPU")
|
44
46
|
{}
|
45
47
|
|
46
48
|
RNSkDrawView::~RNSkDrawView() {
|
47
|
-
#if LOG_ALL_DRAWING
|
48
|
-
RNSkLogger::logToConsole("RNSkDrawView::~RNSkDrawView - %i", getNativeId());
|
49
|
-
#endif
|
50
|
-
|
51
|
-
_isInvalidated = true;
|
52
|
-
|
53
49
|
endDrawingLoop();
|
54
|
-
|
55
|
-
// Wait for the drawing locks
|
56
|
-
if(!_jsDrawingLock->try_lock_for(1250ms)) {
|
57
|
-
RNSkLogger::logToConsole("Warning: JS drawing is still locked for native view with id %i", _nativeId);
|
58
|
-
}
|
59
|
-
|
60
|
-
if(!_gpuDrawingLock->try_lock_for(1250ms)) {
|
61
|
-
RNSkLogger::logToConsole("Warning: SKIA drawing is still locked for native view with id %i", _nativeId);
|
62
|
-
}
|
63
|
-
|
64
|
-
onInvalidated();
|
65
|
-
|
66
|
-
_jsDrawingLock = nullptr;
|
67
|
-
_gpuDrawingLock = nullptr;
|
68
50
|
}
|
69
51
|
|
70
52
|
void RNSkDrawView::setNativeId(size_t nativeId) {
|
@@ -84,63 +66,63 @@ void RNSkDrawView::setDrawCallback(std::shared_ptr<jsi::Function> callback) {
|
|
84
66
|
// Reset timing info
|
85
67
|
_jsTimingInfo.reset();
|
86
68
|
_gpuTimingInfo.reset();
|
87
|
-
_vsyncTimingInfo.reset();
|
88
|
-
|
89
|
-
// Set up debug font/paints
|
90
|
-
auto font = SkFont();
|
91
|
-
font.setSize(14);
|
92
|
-
auto paint = SkPaint();
|
93
|
-
paint.setColor(SkColors::kRed);
|
94
69
|
|
95
70
|
// Create draw drawCallback wrapper
|
96
71
|
_drawCallback = std::make_shared<RNSkDrawCallback>(
|
97
|
-
[
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
//
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
//
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
72
|
+
[weakSelf = weak_from_this(),
|
73
|
+
callback = std::move(callback)](std::shared_ptr<JsiSkCanvas> canvas,
|
74
|
+
int width,
|
75
|
+
int height,
|
76
|
+
double timestamp,
|
77
|
+
std::shared_ptr<RNSkPlatformContext> context) {
|
78
|
+
|
79
|
+
auto self = weakSelf.lock();
|
80
|
+
if(self) {
|
81
|
+
auto runtime = context->getJsRuntime();
|
82
|
+
|
83
|
+
// Update info parameter
|
84
|
+
self->_infoObject->beginDrawOperation(width, height, timestamp);
|
85
|
+
|
86
|
+
// Set up arguments array
|
87
|
+
std::vector<jsi::Value> args(2);
|
88
|
+
args[0] = jsi::Object::createFromHostObject(*runtime, canvas);
|
89
|
+
args[1] = jsi::Object::createFromHostObject(*runtime, self->_infoObject);
|
90
|
+
|
91
|
+
// To be able to call the drawing function we'll wrap it once again
|
92
|
+
callback->call(*runtime,
|
93
|
+
static_cast<const jsi::Value *>(args.data()),
|
94
|
+
(size_t)2);
|
95
|
+
|
96
|
+
// Reset touches
|
97
|
+
self->_infoObject->endDrawOperation();
|
98
|
+
|
99
|
+
// Draw debug overlays
|
100
|
+
if (self->_showDebugOverlay) {
|
101
|
+
|
102
|
+
// Display average rendering timer
|
103
|
+
auto jsAvg = self->_jsTimingInfo.getAverage();
|
104
|
+
//auto jsFps = _jsTimingInfo.getFps();
|
105
|
+
|
106
|
+
auto gpuAvg = self->_gpuTimingInfo.getAverage();
|
107
|
+
//auto gpuFps = _gpuTimingInfo.getFps();
|
108
|
+
|
109
|
+
auto total = jsAvg + gpuAvg;
|
110
|
+
|
111
|
+
// Build string
|
112
|
+
std::ostringstream stream;
|
113
|
+
stream << "js: " << jsAvg << "ms gpu: " << gpuAvg << "ms " << " total: " << total << "ms";
|
114
|
+
|
115
|
+
std::string debugString = stream.str();
|
116
|
+
|
117
|
+
// Set up debug font/paints
|
118
|
+
auto font = SkFont();
|
119
|
+
font.setSize(14);
|
120
|
+
auto paint = SkPaint();
|
121
|
+
paint.setColor(SkColors::kRed);
|
122
|
+
canvas->getCanvas()->drawSimpleText(
|
123
|
+
debugString.c_str(), debugString.size(), SkTextEncoding::kUTF8, 8,
|
124
|
+
18, font, paint);
|
125
|
+
}
|
144
126
|
}
|
145
127
|
});
|
146
128
|
|
@@ -172,7 +154,7 @@ void RNSkDrawView::drawInCanvas(std::shared_ptr<JsiSkCanvas> canvas,
|
|
172
154
|
|
173
155
|
sk_sp<SkImage> RNSkDrawView::makeImageSnapshot(std::shared_ptr<SkRect> bounds) {
|
174
156
|
// Assert width/height
|
175
|
-
auto surface = SkSurface::MakeRasterN32Premul(
|
157
|
+
auto surface = SkSurface::MakeRasterN32Premul(getScaledWidth(), getScaledHeight());
|
176
158
|
auto canvas = surface->getCanvas();
|
177
159
|
auto jsiCanvas = std::make_shared<JsiSkCanvas>(_platformContext);
|
178
160
|
jsiCanvas->setCanvas(canvas);
|
@@ -180,7 +162,7 @@ sk_sp<SkImage> RNSkDrawView::makeImageSnapshot(std::shared_ptr<SkRect> bounds) {
|
|
180
162
|
milliseconds ms = duration_cast<milliseconds>(
|
181
163
|
system_clock::now().time_since_epoch());
|
182
164
|
|
183
|
-
drawInCanvas(jsiCanvas,
|
165
|
+
drawInCanvas(jsiCanvas, getScaledWidth(), getScaledHeight(), ms.count() / 1000);
|
184
166
|
|
185
167
|
if(bounds != nullptr) {
|
186
168
|
SkIRect b = SkIRect::MakeXYWH(bounds->x(), bounds->y(), bounds->width(), bounds->height());
|
@@ -196,10 +178,6 @@ void RNSkDrawView::updateTouchState(std::vector<RNSkTouchPoint>&& points) {
|
|
196
178
|
}
|
197
179
|
|
198
180
|
void RNSkDrawView::performDraw() {
|
199
|
-
#if LOG_ALL_DRAWING
|
200
|
-
RNSkLogger::logToConsole("RNSkDrawView::performDraw - %i", getNativeId());
|
201
|
-
#endif
|
202
|
-
|
203
181
|
// Start timing
|
204
182
|
_jsTimingInfo.beginTiming();
|
205
183
|
|
@@ -207,7 +185,7 @@ void RNSkDrawView::performDraw() {
|
|
207
185
|
// move the actual drawing onto the render thread later
|
208
186
|
SkPictureRecorder recorder;
|
209
187
|
SkRTreeFactory factory;
|
210
|
-
SkCanvas* canvas = recorder.beginRecording(
|
188
|
+
SkCanvas* canvas = recorder.beginRecording(getScaledWidth(), getScaledHeight(), &factory);
|
211
189
|
_jsiCanvas->setCanvas(canvas);
|
212
190
|
|
213
191
|
// Get current milliseconds
|
@@ -216,7 +194,7 @@ void RNSkDrawView::performDraw() {
|
|
216
194
|
|
217
195
|
try {
|
218
196
|
// Perform the javascript drawing
|
219
|
-
drawInCanvas(_jsiCanvas,
|
197
|
+
drawInCanvas(_jsiCanvas, getScaledWidth(), getScaledHeight(), ms.count() / 1000.0);
|
220
198
|
} catch(...) {
|
221
199
|
_jsTimingInfo.stopTiming();
|
222
200
|
_jsDrawingLock->unlock();
|
@@ -234,37 +212,22 @@ void RNSkDrawView::performDraw() {
|
|
234
212
|
// Post drawing message to the render thread where the picture recorded
|
235
213
|
// will be sent to the GPU/backend for rendering to screen.
|
236
214
|
auto gpuLock = _gpuDrawingLock;
|
237
|
-
|
238
|
-
|
239
|
-
if(
|
240
|
-
|
241
|
-
|
215
|
+
_platformContext->runOnRenderThread([weakSelf = weak_from_this(), p = std::move(p), gpuLock]() {
|
216
|
+
auto self = weakSelf.lock();
|
217
|
+
if (self) {
|
218
|
+
// Draw the picture recorded on the real GPU canvas
|
219
|
+
self->_gpuTimingInfo.beginTiming();
|
220
|
+
self->drawPicture(p);
|
221
|
+
self->_gpuTimingInfo.stopTiming();
|
242
222
|
}
|
243
|
-
|
244
|
-
_gpuTimingInfo.beginTiming();
|
245
|
-
|
246
|
-
// Draw the picture recorded on the real GPU canvas
|
247
|
-
if(_nativeDrawFunc != nullptr) {
|
248
|
-
#if LOG_ALL_DRAWING
|
249
|
-
RNSkLogger::logToConsole("RNSkDrawView::drawFrame - %i", getNativeId());
|
250
|
-
#endif
|
251
|
-
_nativeDrawFunc(p);
|
252
|
-
} else {
|
253
|
-
#if LOG_ALL_DRAWING
|
254
|
-
RNSkLogger::logToConsole("RNSkDrawView::drawFrame - %i SKIPPING, draw func is null", getNativeId());
|
255
|
-
#endif
|
256
|
-
}
|
257
|
-
|
258
|
-
_gpuTimingInfo.stopTiming();
|
259
|
-
|
260
223
|
// Unlock GPU drawing
|
261
224
|
gpuLock->unlock();
|
262
225
|
});
|
263
226
|
} else {
|
264
227
|
#ifdef DEBUG
|
265
|
-
|
266
|
-
printf("SKIA/GPU: Skipped frames: %lu\n", ++framesSkipped);
|
228
|
+
_gpuTimingInfo.markSkipped();
|
267
229
|
#endif
|
230
|
+
// Request a new redraw since the last frame was skipped.
|
268
231
|
requestRedraw();
|
269
232
|
}
|
270
233
|
|
@@ -280,39 +243,34 @@ void RNSkDrawView::beginDrawingLoop() {
|
|
280
243
|
if (_drawingLoopId != 0 || _nativeId == 0) {
|
281
244
|
return;
|
282
245
|
}
|
283
|
-
|
284
246
|
// Set to zero to avoid calling beginDrawLoop before we return
|
285
|
-
_drawingLoopId = _platformContext->beginDrawLoop(
|
286
|
-
|
247
|
+
_drawingLoopId = _platformContext->beginDrawLoop(_nativeId,
|
248
|
+
[weakSelf = weak_from_this()](bool invalidated) {
|
249
|
+
auto self = weakSelf.lock();
|
250
|
+
if(self) {
|
251
|
+
self->drawLoopCallback(invalidated);
|
252
|
+
}
|
253
|
+
});
|
287
254
|
}
|
288
255
|
|
289
256
|
void RNSkDrawView::drawLoopCallback(bool invalidated) {
|
290
|
-
if(invalidated) {
|
291
|
-
_isInvalidated = true;
|
292
|
-
onInvalidated();
|
293
|
-
#if LOG_ALL_DRAWING
|
294
|
-
RNSkLogger::logToConsole("RNSkDrawView::onInvalidated - %i", getNativeId());
|
295
|
-
#endif
|
296
|
-
return;
|
297
|
-
}
|
298
|
-
|
299
257
|
if(_redrawRequestCounter > 0 || _drawingMode == RNSkDrawingMode::Continuous) {
|
300
258
|
_redrawRequestCounter = 0;
|
301
259
|
|
302
|
-
_vsyncTimingInfo.beginTiming();
|
303
|
-
|
304
260
|
// We render on the javascript thread.
|
305
261
|
if(_jsDrawingLock->try_lock()) {
|
306
|
-
_platformContext->runOnJavascriptThread(
|
262
|
+
_platformContext->runOnJavascriptThread([weakSelf = weak_from_this()](){
|
263
|
+
auto self = weakSelf.lock();
|
264
|
+
if(self) {
|
265
|
+
self->performDraw();
|
266
|
+
}
|
267
|
+
});
|
307
268
|
} else {
|
308
269
|
#ifdef DEBUG
|
309
|
-
|
310
|
-
printf("SKIA/JS: Skipped frames: %lu\n", ++framesSkipped);
|
270
|
+
_jsTimingInfo.markSkipped();
|
311
271
|
#endif
|
312
272
|
requestRedraw();
|
313
273
|
}
|
314
|
-
|
315
|
-
_vsyncTimingInfo.stopTiming();
|
316
274
|
}
|
317
275
|
}
|
318
276
|
|
@@ -20,8 +20,6 @@
|
|
20
20
|
|
21
21
|
#pragma clang diagnostic pop
|
22
22
|
|
23
|
-
#define LOG_ALL_DRAWING 0
|
24
|
-
|
25
23
|
class SkPicture;
|
26
24
|
class SkRect;
|
27
25
|
class SkImage;
|
@@ -35,7 +33,7 @@ using RNSkDrawCallback =
|
|
35
33
|
|
36
34
|
enum RNSkDrawingMode { Default, Continuous };
|
37
35
|
|
38
|
-
class RNSkDrawView {
|
36
|
+
class RNSkDrawView: public std::enable_shared_from_this<RNSkDrawView> {
|
39
37
|
public:
|
40
38
|
/**
|
41
39
|
* Constructor
|
@@ -45,7 +43,7 @@ public:
|
|
45
43
|
/**
|
46
44
|
Destructor
|
47
45
|
*/
|
48
|
-
~RNSkDrawView();
|
46
|
+
virtual ~RNSkDrawView();
|
49
47
|
|
50
48
|
/**
|
51
49
|
* Repaints the Skia view using the underlying context and the drawcallback.
|
@@ -96,33 +94,20 @@ public:
|
|
96
94
|
sk_sp<SkImage> makeImageSnapshot(std::shared_ptr<SkRect> bounds);
|
97
95
|
|
98
96
|
protected:
|
99
|
-
void setNativeDrawFunc(std::function<void(const sk_sp<SkPicture>)> drawFunc) {
|
100
|
-
if(!_gpuDrawingLock->try_lock_for(250ms)) {
|
101
|
-
RNSkLogger::logToConsole("Could not lock drawing when clearing drawing function - %i", _nativeId);
|
102
|
-
}
|
103
|
-
_nativeDrawFunc = drawFunc;
|
104
|
-
_gpuDrawingLock->unlock();
|
105
|
-
}
|
106
|
-
|
107
97
|
/**
|
108
98
|
Returns the scaled width of the view
|
109
99
|
*/
|
110
|
-
virtual
|
100
|
+
virtual float getScaledWidth() = 0;
|
111
101
|
|
112
102
|
/**
|
113
103
|
Returns the scaled height of the view
|
114
104
|
*/
|
115
|
-
virtual
|
116
|
-
|
117
|
-
/**
|
118
|
-
Returns true if the view is invalidated
|
119
|
-
*/
|
120
|
-
volatile bool isInvalidated() { return _isInvalidated; }
|
105
|
+
virtual float getScaledHeight() = 0;
|
121
106
|
|
122
107
|
/**
|
123
|
-
Override to
|
108
|
+
Override to render picture to GPU
|
124
109
|
*/
|
125
|
-
virtual void
|
110
|
+
virtual void drawPicture(const sk_sp<SkPicture> picture) = 0;
|
126
111
|
|
127
112
|
/**
|
128
113
|
* @return The platformcontext
|
@@ -210,12 +195,7 @@ private:
|
|
210
195
|
/**
|
211
196
|
Timing information for GPU rendering
|
212
197
|
*/
|
213
|
-
RNSkTimingInfo _gpuTimingInfo;
|
214
|
-
|
215
|
-
/**
|
216
|
-
Measures vsync framerate
|
217
|
-
*/
|
218
|
-
RNSkTimingInfo _vsyncTimingInfo;
|
198
|
+
RNSkTimingInfo _gpuTimingInfo;
|
219
199
|
|
220
200
|
/**
|
221
201
|
Redraw queue counter
|
@@ -227,16 +207,6 @@ private:
|
|
227
207
|
*/
|
228
208
|
size_t _nativeId;
|
229
209
|
|
230
|
-
/**
|
231
|
-
Invalidation flag
|
232
|
-
*/
|
233
|
-
std::atomic<bool> _isInvalidated = { false };
|
234
|
-
|
235
|
-
/**
|
236
|
-
Native draw handler
|
237
|
-
*/
|
238
|
-
std::function<void(const sk_sp<SkPicture>)> _nativeDrawFunc;
|
239
|
-
|
240
210
|
};
|
241
211
|
|
242
212
|
} // namespace RNSkia
|
@@ -20,7 +20,7 @@ using CallbackInfo = struct CallbackInfo {
|
|
20
20
|
view = nullptr;
|
21
21
|
}
|
22
22
|
std::shared_ptr<jsi::Function> drawCallback;
|
23
|
-
RNSkDrawView
|
23
|
+
std::shared_ptr<RNSkDrawView> view;
|
24
24
|
};
|
25
25
|
|
26
26
|
class RNSkJsiViewApi : public JsiHostObject {
|
@@ -105,7 +105,7 @@ public:
|
|
105
105
|
sk_sp<SkImage> image;
|
106
106
|
auto info = getEnsuredCallbackInfo(nativeId);
|
107
107
|
if (info->view != nullptr) {
|
108
|
-
if(count > 1 && !arguments[1].isUndefined() && arguments[1].isNull()) {
|
108
|
+
if(count > 1 && !arguments[1].isUndefined() && !arguments[1].isNull()) {
|
109
109
|
auto rect = JsiSkRect::fromValue(runtime, arguments[1]);
|
110
110
|
image = info->view->makeImageSnapshot(rect);
|
111
111
|
} else {
|
@@ -226,7 +226,7 @@ public:
|
|
226
226
|
* @param nativeId Id of view to register
|
227
227
|
* @param view View to register
|
228
228
|
*/
|
229
|
-
void registerSkiaDrawView(size_t nativeId, RNSkDrawView
|
229
|
+
void registerSkiaDrawView(size_t nativeId, std::shared_ptr<RNSkDrawView> view) {
|
230
230
|
auto info = getEnsuredCallbackInfo(nativeId);
|
231
231
|
info->view = view;
|
232
232
|
if (info->drawCallback != nullptr) {
|
@@ -260,15 +260,18 @@ public:
|
|
260
260
|
a valid view is set, the setDrawCallback method is called on the
|
261
261
|
view (if a valid callback exists).
|
262
262
|
*/
|
263
|
-
void setSkiaDrawView(size_t nativeId, RNSkDrawView
|
263
|
+
void setSkiaDrawView(size_t nativeId, std::shared_ptr<RNSkDrawView> view) {
|
264
264
|
if (_callbackInfos.find(nativeId) == _callbackInfos.end()) {
|
265
265
|
return;
|
266
266
|
}
|
267
267
|
auto info = getEnsuredCallbackInfo(nativeId);
|
268
|
-
info->view = view;
|
269
268
|
if (view != nullptr && info->drawCallback != nullptr) {
|
269
|
+
info->view = view;
|
270
270
|
info->view->setNativeId(nativeId);
|
271
271
|
info->view->setDrawCallback(info->drawCallback);
|
272
|
+
} else if(view == nullptr && info->drawCallback != nullptr) {
|
273
|
+
info->view->setDrawCallback(nullptr);
|
274
|
+
info->view = view;
|
272
275
|
}
|
273
276
|
}
|
274
277
|
|
@@ -45,7 +45,7 @@ void RNSkManager::invalidate() {
|
|
45
45
|
_platformContext->invalidate();
|
46
46
|
}
|
47
47
|
|
48
|
-
void RNSkManager::registerSkiaDrawView(size_t nativeId, RNSkDrawView
|
48
|
+
void RNSkManager::registerSkiaDrawView(size_t nativeId, std::shared_ptr<RNSkDrawView> view) {
|
49
49
|
if (!_isInvalidated && _viewApi != nullptr)
|
50
50
|
_viewApi->registerSkiaDrawView(nativeId, view);
|
51
51
|
}
|
@@ -55,7 +55,7 @@ void RNSkManager::unregisterSkiaDrawView(size_t nativeId) {
|
|
55
55
|
_viewApi->unregisterSkiaDrawView(nativeId);
|
56
56
|
}
|
57
57
|
|
58
|
-
void RNSkManager::setSkiaDrawView(size_t nativeId, RNSkDrawView
|
58
|
+
void RNSkManager::setSkiaDrawView(size_t nativeId, std::shared_ptr<RNSkDrawView> view) {
|
59
59
|
if (!_isInvalidated && _viewApi != nullptr)
|
60
60
|
_viewApi->setSkiaDrawView(nativeId, view);
|
61
61
|
}
|
package/cpp/rnskia/RNSkManager.h
CHANGED
@@ -41,7 +41,7 @@ public:
|
|
41
41
|
* @param nativeId Native view id
|
42
42
|
* @param view View to register
|
43
43
|
*/
|
44
|
-
void registerSkiaDrawView(size_t nativeId, RNSkDrawView
|
44
|
+
void registerSkiaDrawView(size_t nativeId, std::shared_ptr<RNSkDrawView> view);
|
45
45
|
|
46
46
|
/**
|
47
47
|
* Unregisters the RNSkDrawView from the list of registered views
|
@@ -54,7 +54,7 @@ public:
|
|
54
54
|
Used when we want to remove a view without unregistering it
|
55
55
|
- this happens typically on iOS.
|
56
56
|
*/
|
57
|
-
void setSkiaDrawView(size_t nativeId, RNSkDrawView
|
57
|
+
void setSkiaDrawView(size_t nativeId, std::shared_ptr<RNSkDrawView> view);
|
58
58
|
|
59
59
|
/**
|
60
60
|
* @return The platform context
|
@@ -34,8 +34,12 @@ public:
|
|
34
34
|
}
|
35
35
|
|
36
36
|
JSI_HOST_FUNCTION(createDerivedValue) {
|
37
|
-
|
38
|
-
|
37
|
+
// Creation and initialization is done in two steps to be able to use weak references when setting
|
38
|
+
// up dependencies - since weak_from_this needs our instance to be a shared_ptr before calling
|
39
|
+
// weak_from_this().
|
40
|
+
auto derivedValue = std::make_shared<RNSkDerivedValue>(_platformContext, runtime, arguments, count);
|
41
|
+
derivedValue->initializeDependencies(runtime, arguments, count);
|
42
|
+
return jsi::Object::createFromHostObject(runtime, derivedValue);
|
39
43
|
}
|
40
44
|
|
41
45
|
JSI_HOST_FUNCTION(createAnimation) {
|
@@ -8,7 +8,6 @@
|
|
8
8
|
#include <algorithm>
|
9
9
|
#include <functional>
|
10
10
|
#include <chrono>
|
11
|
-
#include <mutex>
|
12
11
|
|
13
12
|
namespace RNSkia
|
14
13
|
{
|
@@ -33,12 +32,11 @@ public:
|
|
33
32
|
size_t count) : RNSkReadonlyValue(platformContext),
|
34
33
|
_runtime(runtime),
|
35
34
|
_identifier(identifier) {
|
36
|
-
|
37
35
|
// Start by updating to zero (start value)
|
38
36
|
update(_runtime, static_cast<double>(0));
|
39
37
|
}
|
40
38
|
|
41
|
-
~RNSkClockValue() {
|
39
|
+
virtual ~RNSkClockValue() {
|
42
40
|
stopClock();
|
43
41
|
}
|
44
42
|
|
@@ -73,8 +71,13 @@ public:
|
|
73
71
|
_start += timeSinceStop;
|
74
72
|
|
75
73
|
_state = RNSkClockState::Running;
|
76
|
-
|
77
|
-
getContext()->beginDrawLoop(_identifier,
|
74
|
+
|
75
|
+
getContext()->beginDrawLoop(_identifier, [weakSelf = weak_from_this()](bool invalidated){
|
76
|
+
auto self = weakSelf.lock();
|
77
|
+
if(self) {
|
78
|
+
std::dynamic_pointer_cast<RNSkClockValue>(self)->notifyUpdate(invalidated);
|
79
|
+
}
|
80
|
+
});
|
78
81
|
}
|
79
82
|
|
80
83
|
virtual void stopClock() {
|
@@ -100,15 +103,20 @@ protected:
|
|
100
103
|
return;
|
101
104
|
}
|
102
105
|
|
103
|
-
// Avoid moving on if we are being called after the dtor was started
|
104
106
|
// Ensure we call any updates from the draw loop on the javascript thread
|
105
107
|
getContext()->runOnJavascriptThread(
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
auto
|
110
|
-
|
111
|
-
|
108
|
+
// To ensure that this shared_ptr instance is not deallocated before we are done
|
109
|
+
// running the update lambda we pass a shared from this to the lambda scope.
|
110
|
+
[weakSelf = weak_from_this()]() {
|
111
|
+
auto self = weakSelf.lock();
|
112
|
+
if(self) {
|
113
|
+
auto selfClockValue = std::dynamic_pointer_cast<RNSkClockValue>(self);
|
114
|
+
if(selfClockValue->getState() == RNSkClockState::Running) {
|
115
|
+
auto now = std::chrono::high_resolution_clock::now();
|
116
|
+
auto deltaFromStart = std::chrono::duration_cast<std::chrono::milliseconds>(now - selfClockValue->_start).count();
|
117
|
+
selfClockValue->tick(selfClockValue->_runtime, static_cast<double>(deltaFromStart));
|
118
|
+
}
|
119
|
+
}
|
112
120
|
});
|
113
121
|
}
|
114
122
|
|
@@ -127,7 +135,7 @@ protected:
|
|
127
135
|
size_t _identifier;
|
128
136
|
std::chrono::time_point<std::chrono::steady_clock> _start;
|
129
137
|
std::chrono::time_point<std::chrono::steady_clock> _stop;
|
130
|
-
std::atomic<RNSkClockState> _state;
|
138
|
+
std::atomic<RNSkClockState> _state = { RNSkClockState::NotStarted };
|
131
139
|
};
|
132
140
|
|
133
141
|
}
|
@@ -39,6 +39,11 @@ public:
|
|
39
39
|
jsi::detail::throwJSError(runtime, "Expected array of dependencies as second parameter");
|
40
40
|
}
|
41
41
|
|
42
|
+
// Get callback for calculating result
|
43
|
+
_callback = std::make_shared<jsi::Function>(arguments[0].asObject(runtime).asFunction(runtime));
|
44
|
+
}
|
45
|
+
|
46
|
+
void initializeDependencies(jsi::Runtime &runtime, const jsi::Value *arguments, size_t count) {
|
42
47
|
// Save dependencies
|
43
48
|
std::vector<std::shared_ptr<RNSkReadonlyValue>> dependencies;
|
44
49
|
|
@@ -59,21 +64,23 @@ public:
|
|
59
64
|
dependencies.push_back(value);
|
60
65
|
}
|
61
66
|
|
62
|
-
// Get callback for calculating result
|
63
|
-
_callback = std::make_shared<jsi::Function>(arguments[0].asObject(runtime).asFunction(runtime));
|
64
|
-
|
65
67
|
// register change handler on dependencies
|
66
68
|
_unsubscribers.reserve(_unsubscribers.size() + size);
|
67
69
|
for(const auto &dep: dependencies) {
|
68
|
-
|
69
|
-
|
70
|
+
_unsubscribers.push_back(dep->addListener([weakSelf = weak_from_this()](jsi::Runtime& runtime) {
|
71
|
+
auto self = weakSelf.lock();
|
72
|
+
if(self) {
|
73
|
+
auto selfAsThis = std::dynamic_pointer_cast<RNSkDerivedValue>(self);
|
74
|
+
selfAsThis->dependencyUpdated(runtime);
|
75
|
+
}
|
76
|
+
}));
|
70
77
|
}
|
71
78
|
|
72
79
|
// Set initial value
|
73
80
|
dependencyUpdated(runtime);
|
74
81
|
}
|
75
82
|
|
76
|
-
~RNSkDerivedValue() {
|
83
|
+
virtual ~RNSkDerivedValue() {
|
77
84
|
// Unregister listeners
|
78
85
|
for(const auto &unsubscribe: _unsubscribers) {
|
79
86
|
unsubscribe();
|