@shopify/react-native-skia 0.1.120 → 0.1.123
Sign up to get free protection for your applications and to get access to all the features.
- package/android/CMakeLists.txt +33 -17
- package/android/build.gradle +81 -34
- 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/PlatformContext.java +1 -1
- 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 +4 -7
- package/cpp/rnskia/RNSkDrawView.cpp +77 -116
- package/cpp/rnskia/RNSkDrawView.h +5 -35
- 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/values/RNSkClockValue.h +19 -11
- package/cpp/rnskia/values/RNSkDerivedValue.h +1 -1
- package/cpp/rnskia/values/RNSkReadonlyValue.h +15 -15
- package/cpp/utils/RNSkTimingInfo.h +13 -1
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.h +5 -7
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.mm +25 -10
- package/ios/RNSkia-iOS/SkiaDrawView.mm +21 -15
- package/lib/commonjs/renderer/Canvas.js +3 -3
- 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/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/Paint.js +6 -1
- package/lib/commonjs/renderer/processors/Paint.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/module/renderer/Canvas.js +2 -2
- 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/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/Paint.js +6 -1
- package/lib/module/renderer/processors/Paint.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/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/package.json +1 -1
- package/scripts/install-npm.js +1 -1
- package/src/renderer/Canvas.tsx +2 -2
- package/src/renderer/components/Paint.tsx +2 -2
- package/src/renderer/components/shapes/Path.tsx +12 -4
- package/src/renderer/nodes/Node.ts +3 -3
- package/src/renderer/processors/Paint.ts +5 -0
- 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
@@ -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,14 +94,6 @@ 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
|
*/
|
@@ -115,14 +105,9 @@ protected:
|
|
115
105
|
virtual int getHeight() { return -1; };
|
116
106
|
|
117
107
|
/**
|
118
|
-
|
119
|
-
*/
|
120
|
-
volatile bool isInvalidated() { return _isInvalidated; }
|
121
|
-
|
122
|
-
/**
|
123
|
-
Override to be notified on invalidation
|
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
|
@@ -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
|
{
|
@@ -38,7 +37,7 @@ public:
|
|
38
37
|
update(_runtime, static_cast<double>(0));
|
39
38
|
}
|
40
39
|
|
41
|
-
~RNSkClockValue() {
|
40
|
+
virtual ~RNSkClockValue() {
|
42
41
|
stopClock();
|
43
42
|
}
|
44
43
|
|
@@ -73,8 +72,12 @@ public:
|
|
73
72
|
_start += timeSinceStop;
|
74
73
|
|
75
74
|
_state = RNSkClockState::Running;
|
76
|
-
|
77
|
-
|
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
|
|
@@ -4,9 +4,7 @@
|
|
4
4
|
#include <algorithm>
|
5
5
|
#include <functional>
|
6
6
|
#include <chrono>
|
7
|
-
#include <mutex>
|
8
7
|
#include <unordered_map>
|
9
|
-
#include <utility>
|
10
8
|
#include <memory>
|
11
9
|
|
12
10
|
#include <jsi/jsi.h>
|
@@ -22,16 +20,15 @@ using namespace facebook;
|
|
22
20
|
Implements a readonly Value that is updated every time the screen is redrawn. Its value will be the
|
23
21
|
number of milliseconds since the animation value was started.
|
24
22
|
*/
|
25
|
-
class RNSkReadonlyValue : public JsiSkHostObject
|
23
|
+
class RNSkReadonlyValue : public JsiSkHostObject,
|
24
|
+
public std::enable_shared_from_this<RNSkReadonlyValue>
|
26
25
|
{
|
27
26
|
public:
|
28
27
|
RNSkReadonlyValue(std::shared_ptr<RNSkPlatformContext> platformContext)
|
29
28
|
: JsiSkHostObject(platformContext),
|
30
29
|
_propNameId(jsi::PropNameID::forUtf8(*platformContext->getJsRuntime(), "value")) {}
|
31
30
|
|
32
|
-
~RNSkReadonlyValue() {
|
33
|
-
_invalidated = true;
|
34
|
-
}
|
31
|
+
virtual ~RNSkReadonlyValue() { }
|
35
32
|
|
36
33
|
JSI_PROPERTY_GET(__typename__) {
|
37
34
|
return jsi::String::createFromUtf8(runtime, "RNSkValue");
|
@@ -43,8 +40,7 @@ public:
|
|
43
40
|
|
44
41
|
JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(RNSkReadonlyValue, __typename__),
|
45
42
|
JSI_EXPORT_PROP_GET(RNSkReadonlyValue, current))
|
46
|
-
|
47
|
-
|
43
|
+
|
48
44
|
JSI_HOST_FUNCTION(addListener) {
|
49
45
|
if(!arguments[0].isObject() || !arguments[0].asObject(runtime).isFunction(runtime)) {
|
50
46
|
jsi::detail::throwJSError(runtime, "Expected function as first parameter.");
|
@@ -52,8 +48,13 @@ public:
|
|
52
48
|
}
|
53
49
|
auto callback = std::make_shared<jsi::Function>(arguments[0].asObject(runtime).asFunction(runtime));
|
54
50
|
|
55
|
-
auto unsubscribe = addListener([
|
56
|
-
|
51
|
+
auto unsubscribe = addListener([weakSelf = weak_from_this(),
|
52
|
+
callback = std::move(callback)](jsi::Runtime& runtime){
|
53
|
+
auto self = weakSelf.lock();
|
54
|
+
if(self) {
|
55
|
+
auto selfReadonlyValue = std::dynamic_pointer_cast<RNSkReadonlyValue>(self);
|
56
|
+
callback->call(runtime, selfReadonlyValue->get_current(runtime));
|
57
|
+
}
|
57
58
|
});
|
58
59
|
|
59
60
|
return jsi::Function::createFromHostFunction(runtime,
|
@@ -76,9 +77,10 @@ public:
|
|
76
77
|
std::lock_guard<std::mutex> lock(_mutex);
|
77
78
|
auto listenerId = _listenerId++;
|
78
79
|
_listeners.emplace(listenerId, cb);
|
79
|
-
return [
|
80
|
-
|
81
|
-
|
80
|
+
return [weakSelf = weak_from_this(), listenerId]() {
|
81
|
+
auto self = weakSelf.lock();
|
82
|
+
if(self) {
|
83
|
+
self->removeListener(listenerId);
|
82
84
|
}
|
83
85
|
};
|
84
86
|
}
|
@@ -128,8 +130,6 @@ protected:
|
|
128
130
|
_listeners.erase(listenerId);
|
129
131
|
}
|
130
132
|
|
131
|
-
std::atomic<bool> _invalidated = { false };
|
132
|
-
|
133
133
|
private:
|
134
134
|
jsi::PropNameID _propNameId;
|
135
135
|
std::shared_ptr<jsi::Object> _valueHolder;
|
@@ -1,5 +1,6 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
+
#include <RNSkLog.h>
|
3
4
|
#include <chrono>
|
4
5
|
|
5
6
|
#define NUMBER_OF_DURATION_SAMPLES 10
|
@@ -12,7 +13,7 @@ using ms = duration<float, std::milli>;
|
|
12
13
|
|
13
14
|
class RNSkTimingInfo {
|
14
15
|
public:
|
15
|
-
RNSkTimingInfo() {
|
16
|
+
RNSkTimingInfo(const std::string &name): _name(std::move(name)) {
|
16
17
|
reset();
|
17
18
|
}
|
18
19
|
|
@@ -25,6 +26,7 @@ public:
|
|
25
26
|
_prevFpsTimer = -1;
|
26
27
|
_frameCount = 0;
|
27
28
|
_lastFrameCount = -1;
|
29
|
+
_didSkip = false;
|
28
30
|
}
|
29
31
|
|
30
32
|
void beginTiming() {
|
@@ -35,6 +37,14 @@ public:
|
|
35
37
|
time_point<steady_clock> stop = high_resolution_clock::now();
|
36
38
|
addLastDuration(duration_cast<milliseconds>(stop - _start).count());
|
37
39
|
tick(stop);
|
40
|
+
if(_didSkip) {
|
41
|
+
_didSkip = false;
|
42
|
+
RNSkLogger::logToConsole("%s: Skipped frame. Previous frame time: %lldms", _name.c_str(), _lastDuration);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
void markSkipped() {
|
47
|
+
_didSkip = true;
|
38
48
|
}
|
39
49
|
|
40
50
|
long getAverage() { return static_cast<long>(_average); }
|
@@ -86,6 +96,8 @@ private:
|
|
86
96
|
long _prevFpsTimer;
|
87
97
|
double _frameCount;
|
88
98
|
double _lastFrameCount;
|
99
|
+
double _didSkip;
|
100
|
+
std::string _name;
|
89
101
|
};
|
90
102
|
|
91
103
|
} // namespace RNSkia
|
@@ -21,20 +21,18 @@
|
|
21
21
|
class RNSkDrawViewImpl : public RNSkia::RNSkDrawView {
|
22
22
|
public:
|
23
23
|
RNSkDrawViewImpl(std::shared_ptr<RNSkia::RNSkPlatformContext> context);
|
24
|
+
~RNSkDrawViewImpl();
|
24
25
|
|
25
|
-
|
26
|
+
CALayer* getLayer() { return _layer; }
|
26
27
|
|
27
|
-
|
28
|
+
void setSize(int width, int height);
|
28
29
|
|
29
30
|
protected:
|
30
31
|
int getWidth() override { return _width * _context->getPixelDensity(); };
|
31
|
-
int getHeight() override { return _height * _context->getPixelDensity(); };
|
32
|
-
void onInvalidated() override {
|
33
|
-
setNativeDrawFunc(nullptr);
|
34
|
-
};
|
32
|
+
int getHeight() override { return _height * _context->getPixelDensity(); };
|
35
33
|
|
36
34
|
private:
|
37
|
-
void
|
35
|
+
void drawPicture(const sk_sp<SkPicture> picture) override;
|
38
36
|
bool createSkiaSurface();
|
39
37
|
|
40
38
|
int _nativeId;
|
@@ -19,19 +19,34 @@ sk_sp<GrDirectContext> RNSkDrawViewImpl::_skContext = nullptr;
|
|
19
19
|
|
20
20
|
RNSkDrawViewImpl::RNSkDrawViewImpl(std::shared_ptr<RNSkia::RNSkPlatformContext> context):
|
21
21
|
_context(context), RNSkia::RNSkDrawView(context) {
|
22
|
-
|
23
22
|
#pragma clang diagnostic push
|
24
23
|
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
25
|
-
|
24
|
+
_layer = [CAMetalLayer layer];
|
26
25
|
#pragma clang diagnostic pop
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
_layer.framebufferOnly = NO;
|
28
|
+
_layer.device = _device;
|
29
|
+
_layer.opaque = false;
|
30
|
+
_layer.contentsScale = _context->getPixelDensity();
|
31
|
+
_layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
32
|
+
}
|
33
|
+
|
34
|
+
RNSkDrawViewImpl::~RNSkDrawViewImpl() {
|
35
|
+
if([[NSThread currentThread] isMainThread]) {
|
36
|
+
_layer = NULL;
|
37
|
+
} else {
|
38
|
+
__block auto tempLayer = _layer;
|
39
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
40
|
+
// By using the tempLayer variable in the block we capture it and it will be
|
41
|
+
// released after the block has finished. This way the CAMetalLayer dealloc will
|
42
|
+
// only be called on the main thread. Problem: this destructor might be called from
|
43
|
+
// releasing the RNSkDrawViewImpl from a thread capture (after dtor has started),
|
44
|
+
// which would cause the CAMetalLayer dealloc to be called on another thread which
|
45
|
+
// causes a crash.
|
46
|
+
// https://github.com/Shopify/react-native-skia/issues/398
|
47
|
+
tempLayer = tempLayer;
|
48
|
+
});
|
49
|
+
}
|
35
50
|
}
|
36
51
|
|
37
52
|
void RNSkDrawViewImpl::setSize(int width, int height) {
|
@@ -44,7 +59,7 @@ void RNSkDrawViewImpl::setSize(int width, int height) {
|
|
44
59
|
requestRedraw();
|
45
60
|
}
|
46
61
|
|
47
|
-
void RNSkDrawViewImpl::
|
62
|
+
void RNSkDrawViewImpl::drawPicture(const sk_sp<SkPicture> picture) {
|
48
63
|
if(_width == -1 && _height == -1) {
|
49
64
|
return;
|
50
65
|
}
|
@@ -26,53 +26,59 @@
|
|
26
26
|
_nativeId = 0;
|
27
27
|
_debugMode = false;
|
28
28
|
_drawingMode = RNSkia::RNSkDrawingMode::Default;
|
29
|
+
|
29
30
|
// Listen to notifications about module invalidation
|
31
|
+
__unsafe_unretained SkiaDrawView *weakSelf = self;
|
30
32
|
auto nc = [NSNotificationCenter defaultCenter];
|
31
33
|
[nc addObserverForName:RCTBridgeWillInvalidateModulesNotification
|
32
34
|
object:nil
|
33
35
|
queue:nil
|
34
36
|
usingBlock:^(NSNotification *notification){
|
35
37
|
// Remove local variables
|
36
|
-
|
38
|
+
if(weakSelf != nullptr) {
|
39
|
+
weakSelf->_manager = nullptr;
|
40
|
+
}
|
37
41
|
}];
|
38
42
|
}
|
39
43
|
return self;
|
40
44
|
}
|
41
45
|
|
42
|
-
- (void)dealloc {
|
43
|
-
if(_manager != nullptr) {
|
44
|
-
_manager->unregisterSkiaDrawView(_nativeId);
|
45
|
-
}
|
46
|
-
}
|
47
|
-
|
48
46
|
#pragma mark Lifecycle
|
49
47
|
|
50
|
-
- (void)
|
51
|
-
[super willMoveToWindow: newWindow];
|
52
|
-
|
48
|
+
- (void) willMoveToSuperview:(UIView *)newWindow {
|
53
49
|
if (newWindow == NULL) {
|
54
50
|
// Remove implementation view when the parent view is not set
|
55
51
|
if(_impl != nullptr) {
|
52
|
+
[_impl->getLayer() removeFromSuperlayer];
|
53
|
+
|
56
54
|
if(_nativeId != 0 && _manager != nullptr) {
|
57
55
|
_manager->setSkiaDrawView(_nativeId, nullptr);
|
58
56
|
}
|
59
|
-
|
57
|
+
|
60
58
|
_impl = nullptr;
|
61
59
|
}
|
62
60
|
} else {
|
63
61
|
// Create implementation view when the parent view is set
|
64
62
|
if(_impl == nullptr && _manager != nullptr) {
|
65
63
|
_impl = std::make_shared<RNSkDrawViewImpl>(_manager->getPlatformContext());
|
66
|
-
[self.layer addSublayer:_impl->getLayer()];
|
64
|
+
[self.layer addSublayer: _impl->getLayer()];
|
67
65
|
if(_nativeId != 0) {
|
68
|
-
_manager->setSkiaDrawView(_nativeId, _impl
|
66
|
+
_manager->setSkiaDrawView(_nativeId, _impl);
|
69
67
|
}
|
70
68
|
_impl->setDrawingMode(_drawingMode);
|
71
|
-
_impl->setShowDebugOverlays(_debugMode);
|
69
|
+
_impl->setShowDebugOverlays(_debugMode);
|
72
70
|
}
|
73
71
|
}
|
74
72
|
}
|
75
73
|
|
74
|
+
- (void) dealloc {
|
75
|
+
auto nc = [NSNotificationCenter defaultCenter];
|
76
|
+
[nc removeObserver:self name:RCTBridgeWillInvalidateModulesNotification object:nil];
|
77
|
+
if(_manager != nullptr && _nativeId != 0) {
|
78
|
+
_manager->unregisterSkiaDrawView(_nativeId);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
76
82
|
#pragma mark Layout
|
77
83
|
|
78
84
|
- (void) layoutSubviews {
|
@@ -103,7 +109,7 @@
|
|
103
109
|
_nativeId = nativeId;
|
104
110
|
|
105
111
|
if(_impl != nullptr) {
|
106
|
-
_manager->registerSkiaDrawView(nativeId, _impl
|
112
|
+
_manager->registerSkiaDrawView(nativeId, _impl);
|
107
113
|
}
|
108
114
|
}
|
109
115
|
|
@@ -15,6 +15,8 @@ var _skia = require("../skia");
|
|
15
15
|
|
16
16
|
var _useValue = require("../values/hooks/useValue");
|
17
17
|
|
18
|
+
var _Paint = require("../skia/Paint/Paint");
|
19
|
+
|
18
20
|
var _HostConfig = require("./HostConfig");
|
19
21
|
|
20
22
|
var _processors = require("./processors");
|
@@ -109,9 +111,7 @@ const Canvas = /*#__PURE__*/(0, _react.forwardRef)((_ref, forwardedRef) => {
|
|
109
111
|
};
|
110
112
|
}
|
111
113
|
|
112
|
-
const paint =
|
113
|
-
|
114
|
-
paint.setAntiAlias(true);
|
114
|
+
const paint = (0, _Paint.SkiaPaint)();
|
115
115
|
const ctx = {
|
116
116
|
width,
|
117
117
|
height,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["Canvas.tsx"],"names":["CanvasContext","React","createContext","useCanvasSize","canvas","Error","skiaReconciler","skHostConfig","injectIntoDevTools","bundleType","version","rendererPackageName","render","element","root","container","updateContainer","depMgr","subscribe","useCanvasRef","defaultFontMgr","Skia","FontMgr","RefDefault","Canvas","forwardedRef","children","style","debug","mode","onTouch","fontMgr","canvasCtx","width","height","innerRef","ref","useCombinedRefs","tick","setTick","redraw","t","Container","DependencyManager","createContainer","onDraw","info","timestamp","touches","current","paint","
|
1
|
+
{"version":3,"sources":["Canvas.tsx"],"names":["CanvasContext","React","createContext","useCanvasSize","canvas","Error","skiaReconciler","skHostConfig","injectIntoDevTools","bundleType","version","rendererPackageName","render","element","root","container","updateContainer","depMgr","subscribe","useCanvasRef","defaultFontMgr","Skia","FontMgr","RefDefault","Canvas","forwardedRef","children","style","debug","mode","onTouch","fontMgr","canvasCtx","width","height","innerRef","ref","useCombinedRefs","tick","setTick","redraw","t","Container","DependencyManager","createContainer","onDraw","info","timestamp","touches","current","paint","ctx","opacity","center","draw","unsubscribe","refs","targetRef","useRef","useEffect","forEach"],"mappings":"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","sourcesContent":["import React, {\n useEffect,\n useState,\n useCallback,\n useMemo,\n useContext,\n forwardRef,\n useRef,\n} from \"react\";\nimport type {\n RefObject,\n ReactNode,\n ComponentProps,\n MutableRefObject,\n ForwardedRef,\n} from \"react\";\nimport type { OpaqueRoot } from \"react-reconciler\";\nimport ReactReconciler from \"react-reconciler\";\n\nimport { SkiaView, useDrawCallback } from \"../views\";\nimport type { TouchHandler } from \"../views\";\nimport { Skia } from \"../skia\";\nimport type { FontMgr } from \"../skia/FontMgr/FontMgr\";\nimport { useValue } from \"../values/hooks/useValue\";\nimport type { SkiaReadonlyValue } from \"../values/types\";\nimport { SkiaPaint } from \"../skia/Paint/Paint\";\n\nimport { debug as hostDebug, skHostConfig } from \"./HostConfig\";\n// import { debugTree } from \"./nodes\";\nimport { vec } from \"./processors\";\nimport { Container } from \"./nodes\";\nimport { DependencyManager } from \"./DependencyManager\";\n\nconst CanvasContext = React.createContext<SkiaReadonlyValue<{\n width: number;\n height: number;\n}> | null>(null);\n\nexport const useCanvasSize = () => {\n const canvas = useContext(CanvasContext);\n if (!canvas) {\n throw new Error(\"Canvas context is not available\");\n }\n return canvas;\n};\n\nexport const skiaReconciler = ReactReconciler(skHostConfig);\n\nskiaReconciler.injectIntoDevTools({\n bundleType: 1,\n version: \"0.0.1\",\n rendererPackageName: \"react-native-skia\",\n});\n\nconst render = (element: ReactNode, root: OpaqueRoot, container: Container) => {\n skiaReconciler.updateContainer(element, root, null, () => {\n hostDebug(\"updateContainer\");\n\n container.depMgr.subscribe();\n });\n};\n\nexport const useCanvasRef = () => useRef<SkiaView>(null);\n\nexport interface CanvasProps extends ComponentProps<typeof SkiaView> {\n ref?: RefObject<SkiaView>;\n children: ReactNode;\n onTouch?: TouchHandler;\n fontMgr?: FontMgr;\n}\n\nconst defaultFontMgr = Skia.FontMgr.RefDefault();\n\nexport const Canvas = forwardRef<SkiaView, CanvasProps>(\n ({ children, style, debug, mode, onTouch, fontMgr }, forwardedRef) => {\n const canvasCtx = useValue({ width: 0, height: 0 });\n const innerRef = useCanvasRef();\n const ref = useCombinedRefs(forwardedRef, innerRef);\n const [tick, setTick] = useState(0);\n const redraw = useCallback(() => setTick((t) => t + 1), []);\n\n const container = useMemo(\n () => new Container(new DependencyManager(ref), redraw),\n [redraw, ref]\n );\n\n const root = useMemo(\n () => skiaReconciler.createContainer(container, 0, false, null),\n [container]\n );\n // Render effect\n useEffect(() => {\n render(\n <CanvasContext.Provider value={canvasCtx}>\n {children}\n </CanvasContext.Provider>,\n root,\n container\n );\n }, [children, root, redraw, container, canvasCtx]);\n\n // Draw callback\n const onDraw = useDrawCallback(\n (canvas, info) => {\n // TODO: if tree is empty (count === 1) maybe we should not render?\n const { width, height, timestamp } = info;\n if (onTouch) {\n onTouch(info.touches);\n }\n if (\n width !== canvasCtx.current.width ||\n height !== canvasCtx.current.height\n ) {\n canvasCtx.current = { width, height };\n }\n const paint = SkiaPaint();\n const ctx = {\n width,\n height,\n timestamp,\n canvas,\n paint,\n opacity: 1,\n ref,\n center: vec(width / 2, height / 2),\n fontMgr: fontMgr ?? defaultFontMgr,\n };\n container.draw(ctx);\n },\n [tick, onTouch]\n );\n\n useEffect(() => {\n return () => {\n container.depMgr.unsubscribe();\n };\n }, [container]);\n\n return (\n <SkiaView\n ref={ref}\n style={style}\n onDraw={onDraw}\n mode={mode}\n debug={debug}\n />\n );\n }\n);\n\n/**\n * Combines a list of refs into a single ref. This can be used to provide\n * both a forwarded ref and an internal ref keeping the same functionality\n * on both of the refs.\n * @param refs Array of refs to combine\n * @returns A single ref that can be used in a ref prop.\n */\nconst useCombinedRefs = <T,>(\n ...refs: Array<MutableRefObject<T> | ForwardedRef<T>>\n) => {\n const targetRef = React.useRef<T>(null);\n React.useEffect(() => {\n refs.forEach((ref) => {\n if (ref) {\n if (typeof ref === \"function\") {\n ref(targetRef.current);\n } else {\n ref.current = targetRef.current;\n }\n }\n });\n }, [refs]);\n return targetRef;\n};\n"]}
|
@@ -23,7 +23,7 @@ const usePaintRef = () => (0, _react.useRef)(null);
|
|
23
23
|
|
24
24
|
exports.usePaintRef = usePaintRef;
|
25
25
|
const Paint = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
26
|
-
const paint = (0, _react.useMemo)(() => _skia.
|
26
|
+
const paint = (0, _react.useMemo)(() => (0, _skia.SkiaPaint)(), []);
|
27
27
|
(0, _react.useImperativeHandle)(ref, () => paint, [paint]);
|
28
28
|
const onDeclare = (0, _react.useMemo)(() => (0, _nodes.createDeclaration)((paintProps, children, ctx) => (0, _processors.processPaint)(paint, ctx.opacity, paintProps, children)), [paint]);
|
29
29
|
return /*#__PURE__*/_react.default.createElement("skDeclaration", _extends({
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["Paint.tsx"],"names":["usePaintRef","Paint","props","ref","paint","
|
1
|
+
{"version":3,"sources":["Paint.tsx"],"names":["usePaintRef","Paint","props","ref","paint","onDeclare","paintProps","children","ctx","opacity"],"mappings":";;;;;;;AACA;;AAGA;;AAEA;;AACA;;;;;;;;AAEO,MAAMA,WAAW,GAAG,MAAM,mBAAgB,IAAhB,CAA1B;;;AAMA,MAAMC,KAAK,gBAAG,uBACnB,CAACC,KAAD,EAAQC,GAAR,KAAgB;AACd,QAAMC,KAAK,GAAG,oBAAQ,MAAM,sBAAd,EAA2B,EAA3B,CAAd;AACA,kCAAoBD,GAApB,EAAyB,MAAMC,KAA/B,EAAsC,CAACA,KAAD,CAAtC;AACA,QAAMC,SAAS,GAAG,oBAChB,MACE,8BAA8B,CAACC,UAAD,EAAaC,QAAb,EAAuBC,GAAvB,KAC5B,8BAAaJ,KAAb,EAAoBI,GAAG,CAACC,OAAxB,EAAiCH,UAAjC,EAA6CC,QAA7C,CADF,CAFc,EAKhB,CAACH,KAAD,CALgB,CAAlB;AAOA,sBAAO;AAAe,IAAA,SAAS,EAAEC;AAA1B,KAAyCH,KAAzC,EAAP;AACD,CAZkB,CAAd","sourcesContent":["import type { ReactNode } from \"react\";\nimport React, { useRef, useMemo, forwardRef, useImperativeHandle } from \"react\";\n\nimport type { SkPaint } from \"../../skia\";\nimport { SkiaPaint } from \"../../skia\";\nimport type { CustomPaintProps, AnimatedProps } from \"../processors\";\nimport { processPaint } from \"../processors\";\nimport { createDeclaration } from \"../nodes\";\n\nexport const usePaintRef = () => useRef<SkPaint>(null);\n\nexport interface PaintProps extends Omit<CustomPaintProps, \"paint\"> {\n children?: ReactNode | ReactNode[];\n}\n\nexport const Paint = forwardRef<SkPaint, AnimatedProps<PaintProps>>(\n (props, ref) => {\n const paint = useMemo(() => SkiaPaint(), []);\n useImperativeHandle(ref, () => paint, [paint]);\n const onDeclare = useMemo(\n () =>\n createDeclaration<PaintProps>((paintProps, children, ctx) =>\n processPaint(paint, ctx.opacity, paintProps, children)\n ),\n [paint]\n );\n return <skDeclaration onDeclare={onDeclare} {...props} />;\n }\n);\n"]}
|
@@ -11,6 +11,8 @@ var _nodes = require("../../nodes");
|
|
11
11
|
|
12
12
|
var _processors = require("../../processors");
|
13
13
|
|
14
|
+
var _skia = require("../../../skia");
|
15
|
+
|
14
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
15
17
|
|
16
18
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
@@ -24,15 +26,21 @@ const onDraw = (0, _nodes.createDrawing)((_ref, _ref2) => {
|
|
24
26
|
start,
|
25
27
|
end,
|
26
28
|
stroke,
|
29
|
+
fillType,
|
27
30
|
...pathProps
|
28
31
|
} = _ref2;
|
29
32
|
const hasStartOffset = start !== 0;
|
30
|
-
const hasEndOffset =
|
33
|
+
const hasEndOffset = end !== 1;
|
31
34
|
const hasStrokeOptions = stroke !== undefined;
|
32
|
-
const
|
35
|
+
const hasFillType = !!fillType;
|
36
|
+
const willMutatePath = hasStartOffset || hasEndOffset || hasStrokeOptions || hasFillType;
|
33
37
|
const pristinePath = (0, _processors.processPath)(pathProps.path);
|
34
38
|
const path = willMutatePath ? pristinePath.copy() : pristinePath;
|
35
39
|
|
40
|
+
if (hasFillType) {
|
41
|
+
path.setFillType(_skia.FillType[(0, _processors.enumKey)(fillType)]);
|
42
|
+
}
|
43
|
+
|
36
44
|
if (hasStrokeOptions) {
|
37
45
|
path.stroke(stroke);
|
38
46
|
}
|