@shopify/react-native-skia 0.1.141 → 0.1.142
Sign up to get free protection for your applications and to get access to all the features.
- package/android/cpp/rnskia-android/RNSkDrawViewImpl.cpp +2 -2
- package/android/cpp/rnskia-android/RNSkDrawViewImpl.h +1 -1
- package/android/cpp/rnskia-android/SkiaOpenGLRenderer.cpp +15 -16
- package/android/cpp/rnskia-android/SkiaOpenGLRenderer.h +2 -2
- package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawView.java +69 -27
- package/cpp/rnskia/RNSkDrawView.cpp +66 -66
- package/cpp/rnskia/RNSkDrawView.h +22 -6
- package/cpp/rnskia/RNSkJsiViewApi.h +2 -2
- package/cpp/rnskia/values/RNSkComputedValue.h +10 -7
- package/cpp/rnskia/values/RNSkReadonlyValue.h +21 -2
- package/cpp/rnskia/values/RNSkValue.h +1 -0
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.h +1 -1
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.mm +2 -2
- package/ios/RNSkia-iOS/SkiaDrawView.mm +4 -0
- package/lib/commonjs/mock/index.js +3 -1
- package/lib/commonjs/mock/index.js.map +1 -1
- package/lib/commonjs/renderer/DependencyManager.js +1 -1
- package/lib/commonjs/renderer/DependencyManager.js.map +1 -1
- package/lib/commonjs/renderer/processors/Animations/Animations.js +18 -5
- package/lib/commonjs/renderer/processors/Animations/Animations.js.map +1 -1
- package/lib/commonjs/skia/core/Data.js +10 -22
- package/lib/commonjs/skia/core/Data.js.map +1 -1
- package/lib/commonjs/skia/core/Font.js +2 -3
- package/lib/commonjs/skia/core/Font.js.map +1 -1
- package/lib/commonjs/skia/core/Image.js.map +1 -1
- package/lib/commonjs/skia/core/SVG.js.map +1 -1
- package/lib/commonjs/skia/core/Typeface.js.map +1 -1
- package/lib/commonjs/skia/types/Data/Data.js +5 -0
- package/lib/commonjs/skia/types/Data/Data.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.js +9 -7
- package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkPath.js +7 -5
- package/lib/commonjs/skia/web/JsiSkPath.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkRRect.js +8 -0
- package/lib/commonjs/skia/web/JsiSkRRect.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkRect.js +2 -2
- package/lib/commonjs/skia/web/JsiSkRect.js.map +1 -1
- package/lib/commonjs/values/hooks/useComputedValue.js +6 -2
- package/lib/commonjs/values/hooks/useComputedValue.js.map +1 -1
- package/lib/commonjs/values/index.js +13 -0
- package/lib/commonjs/values/index.js.map +1 -1
- package/lib/commonjs/values/selector.js +24 -0
- package/lib/commonjs/values/selector.js.map +1 -0
- package/lib/commonjs/values/web/RNSkComputedValue.js +8 -0
- package/lib/commonjs/values/web/RNSkComputedValue.js.map +1 -1
- package/lib/commonjs/values/web/RNSkReadonlyValue.js +4 -0
- package/lib/commonjs/values/web/RNSkReadonlyValue.js.map +1 -1
- package/lib/module/mock/index.js +2 -1
- package/lib/module/mock/index.js.map +1 -1
- package/lib/module/renderer/DependencyManager.js +2 -2
- package/lib/module/renderer/DependencyManager.js.map +1 -1
- package/lib/module/renderer/processors/Animations/Animations.js +13 -4
- package/lib/module/renderer/processors/Animations/Animations.js.map +1 -1
- package/lib/module/skia/core/Data.js +10 -20
- package/lib/module/skia/core/Data.js.map +1 -1
- package/lib/module/skia/core/Font.js +2 -3
- package/lib/module/skia/core/Font.js.map +1 -1
- package/lib/module/skia/core/Image.js.map +1 -1
- package/lib/module/skia/core/SVG.js.map +1 -1
- package/lib/module/skia/core/Typeface.js.map +1 -1
- package/lib/module/skia/types/Data/Data.js +1 -1
- package/lib/module/skia/types/Data/Data.js.map +1 -1
- package/lib/module/skia/web/JsiSkCanvas.js +8 -7
- package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/module/skia/web/JsiSkPath.js +6 -5
- package/lib/module/skia/web/JsiSkPath.js.map +1 -1
- package/lib/module/skia/web/JsiSkRRect.js +8 -0
- package/lib/module/skia/web/JsiSkRRect.js.map +1 -1
- package/lib/module/skia/web/JsiSkRect.js +2 -2
- package/lib/module/skia/web/JsiSkRect.js.map +1 -1
- package/lib/module/values/hooks/useComputedValue.js +7 -3
- package/lib/module/values/hooks/useComputedValue.js.map +1 -1
- package/lib/module/values/index.js +1 -0
- package/lib/module/values/index.js.map +1 -1
- package/lib/module/values/selector.js +15 -0
- package/lib/module/values/selector.js.map +1 -0
- package/lib/module/values/web/RNSkComputedValue.js +8 -0
- package/lib/module/values/web/RNSkComputedValue.js.map +1 -1
- package/lib/module/values/web/RNSkReadonlyValue.js +4 -0
- package/lib/module/values/web/RNSkReadonlyValue.js.map +1 -1
- package/lib/typescript/src/renderer/processors/Animations/Animations.d.ts +7 -2
- package/lib/typescript/src/skia/core/Data.d.ts +3 -5
- package/lib/typescript/src/skia/core/Font.d.ts +2 -2
- package/lib/typescript/src/skia/core/Image.d.ts +2 -2
- package/lib/typescript/src/skia/core/SVG.d.ts +2 -2
- package/lib/typescript/src/skia/core/Typeface.d.ts +2 -2
- package/lib/typescript/src/skia/types/Data/Data.d.ts +10 -3
- package/lib/typescript/src/skia/web/JsiSkRRect.d.ts +1 -0
- package/lib/typescript/src/skia/web/JsiSkRect.d.ts +1 -1
- package/lib/typescript/src/values/index.d.ts +1 -0
- package/lib/typescript/src/values/selector.d.ts +14 -0
- package/lib/typescript/src/values/types.d.ts +4 -0
- package/lib/typescript/src/values/web/RNSkComputedValue.d.ts +1 -0
- package/lib/typescript/src/values/web/RNSkReadonlyValue.d.ts +1 -0
- package/package.json +2 -2
- package/src/mock/index.ts +2 -1
- package/src/renderer/DependencyManager.tsx +5 -2
- package/src/renderer/processors/Animations/Animations.ts +27 -5
- package/src/skia/core/Data.ts +20 -51
- package/src/skia/core/Font.ts +4 -5
- package/src/skia/core/Image.ts +2 -2
- package/src/skia/core/SVG.ts +2 -2
- package/src/skia/core/Typeface.ts +2 -2
- package/src/skia/types/Data/Data.ts +11 -1
- package/src/skia/web/JsiSkCanvas.ts +22 -10
- package/src/skia/web/JsiSkPath.ts +14 -5
- package/src/skia/web/JsiSkRRect.ts +11 -0
- package/src/skia/web/JsiSkRect.ts +2 -5
- package/src/values/hooks/useComputedValue.ts +6 -3
- package/src/values/index.ts +1 -0
- package/src/values/selector.ts +24 -0
- package/src/values/types.ts +4 -0
- package/src/values/web/RNSkComputedValue.ts +6 -0
- package/src/values/web/RNSkReadonlyValue.ts +4 -0
@@ -65,9 +65,9 @@ namespace RNSkia {
|
|
65
65
|
requestRedraw();
|
66
66
|
}
|
67
67
|
|
68
|
-
void RNSkDrawViewImpl::
|
68
|
+
void RNSkDrawViewImpl::renderToSkiaCanvas(const std::function<void(SkCanvas*)>& cb) {
|
69
69
|
if(_renderer != nullptr) {
|
70
|
-
_renderer->run(
|
70
|
+
_renderer->run(cb, _scaledWidth, _scaledHeight);
|
71
71
|
}
|
72
72
|
}
|
73
73
|
}
|
@@ -32,7 +32,7 @@ namespace RNSkia {
|
|
32
32
|
|
33
33
|
float getScaledHeight() override { return _scaledHeight; };
|
34
34
|
|
35
|
-
void
|
35
|
+
void renderToSkiaCanvas(const std::function<void(SkCanvas*)>&) override;
|
36
36
|
|
37
37
|
private:
|
38
38
|
bool createSkiaSurface();
|
@@ -20,12 +20,12 @@ namespace RNSkia
|
|
20
20
|
return threadContexts.at(threadId);
|
21
21
|
}
|
22
22
|
|
23
|
-
SkiaOpenGLRenderer::SkiaOpenGLRenderer(ANativeWindow *surface, size_t renderId):
|
24
|
-
|
25
|
-
|
23
|
+
SkiaOpenGLRenderer::SkiaOpenGLRenderer(ANativeWindow *surface, size_t renderId) : _surfaceTexture(surface),
|
24
|
+
_renderId(renderId)
|
25
|
+
{
|
26
26
|
}
|
27
27
|
|
28
|
-
void SkiaOpenGLRenderer::run(const
|
28
|
+
void SkiaOpenGLRenderer::run(const std::function<void(SkCanvas *)> &cb, int width, int height)
|
29
29
|
{
|
30
30
|
switch (_renderState)
|
31
31
|
{
|
@@ -51,7 +51,7 @@ namespace RNSkia
|
|
51
51
|
return;
|
52
52
|
}
|
53
53
|
|
54
|
-
if (
|
54
|
+
if (cb != nullptr)
|
55
55
|
{
|
56
56
|
// Reset Skia Context since it might be modified by another Skia View during
|
57
57
|
// rendering.
|
@@ -62,11 +62,10 @@ namespace RNSkia
|
|
62
62
|
glClear(GL_COLOR_BUFFER_BIT);
|
63
63
|
|
64
64
|
// Draw picture into surface
|
65
|
-
_skSurface->getCanvas()
|
65
|
+
cb(_skSurface->getCanvas());
|
66
66
|
|
67
67
|
// Flush
|
68
|
-
_skSurface->
|
69
|
-
getThreadDrawingContext()->skContext->flush();
|
68
|
+
_skSurface->flush();
|
70
69
|
|
71
70
|
if (!eglSwapBuffers(getThreadDrawingContext()->glDisplay, _glSurface))
|
72
71
|
{
|
@@ -180,10 +179,10 @@ namespace RNSkia
|
|
180
179
|
EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
|
181
180
|
|
182
181
|
getThreadDrawingContext()->glContext = eglCreateContext(
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
182
|
+
getThreadDrawingContext()->glDisplay,
|
183
|
+
getThreadDrawingContext()->glConfig,
|
184
|
+
NULL,
|
185
|
+
contextAttribs);
|
187
186
|
|
188
187
|
if (getThreadDrawingContext()->glContext == EGL_NO_CONTEXT)
|
189
188
|
{
|
@@ -239,10 +238,10 @@ namespace RNSkia
|
|
239
238
|
// Create the opengl surface
|
240
239
|
_glSurface =
|
241
240
|
eglCreateWindowSurface(
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
241
|
+
getThreadDrawingContext()->glDisplay,
|
242
|
+
getThreadDrawingContext()->glConfig,
|
243
|
+
_surfaceTexture,
|
244
|
+
nullptr);
|
246
245
|
|
247
246
|
if (_glSurface == EGL_NO_SURFACE)
|
248
247
|
{
|
@@ -52,11 +52,11 @@ namespace RNSkia
|
|
52
52
|
* renderer. All OpenGL/Skia context operations are done on a separate thread which must
|
53
53
|
* be the same for all calls to the render method.
|
54
54
|
*
|
55
|
-
* @param
|
55
|
+
* @param callback Render callback
|
56
56
|
* @param width Width of surface to render if there is a picture
|
57
57
|
* @param height Height of surface to render if there is a picture
|
58
58
|
*/
|
59
|
-
void run(const
|
59
|
+
void run(const std::function<void(SkCanvas*)> &cb, int width, int height);
|
60
60
|
|
61
61
|
/**
|
62
62
|
* Sets the state to finishing. Next time the renderer will be called it
|
@@ -2,7 +2,6 @@ package com.shopify.reactnative.skia;
|
|
2
2
|
|
3
3
|
import android.content.Context;
|
4
4
|
import android.graphics.SurfaceTexture;
|
5
|
-
import android.util.Log;
|
6
5
|
import android.view.Surface;
|
7
6
|
import android.view.TextureView;
|
8
7
|
import android.view.MotionEvent;
|
@@ -52,41 +51,84 @@ public class SkiaDrawView extends TextureView implements TextureView.SurfaceText
|
|
52
51
|
|
53
52
|
void onViewRemoved() {
|
54
53
|
mViewRemoved = true;
|
54
|
+
// We can only reset the native side when the view was removed from screen.
|
55
|
+
// releasing the surface can also be done when the view is hidden and then
|
56
|
+
// we should only release the surface - and keep the native part around.
|
57
|
+
if(mSurface == null) {
|
58
|
+
mHybridData.resetNative();
|
59
|
+
}
|
55
60
|
}
|
56
61
|
|
57
62
|
@Override
|
58
63
|
public boolean onTouchEvent(MotionEvent ev) {
|
59
|
-
|
60
|
-
int
|
64
|
+
// https://developer.android.com/training/gestures/multi
|
65
|
+
int action = ev.getActionMasked();
|
66
|
+
|
61
67
|
MotionEvent.PointerCoords r = new MotionEvent.PointerCoords();
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
68
|
+
|
69
|
+
double[] points;
|
70
|
+
|
71
|
+
// If this is a pointer_up/down event we need to handle it a bit specialized
|
72
|
+
switch (action) {
|
73
|
+
case MotionEvent.ACTION_POINTER_DOWN:
|
74
|
+
case MotionEvent.ACTION_POINTER_UP: {
|
75
|
+
points = new double[5];
|
76
|
+
int pointerIndex = ev.getActionIndex();
|
77
|
+
ev.getPointerCoords(pointerIndex, r);
|
78
|
+
points[0] = r.x;
|
79
|
+
points[1] = r.y;
|
80
|
+
points[2] = ev.getPressure(pointerIndex);
|
81
|
+
points[3] = motionActionToType(action);
|
82
|
+
points[4] = ev.getPointerId(pointerIndex);
|
83
|
+
|
84
|
+
updateTouchPoints(points);
|
85
|
+
|
86
|
+
break;
|
87
|
+
}
|
88
|
+
default: {
|
89
|
+
// For the rest we can just handle it like expected
|
90
|
+
int count = ev.getPointerCount();
|
91
|
+
int pointerIndex = 0;
|
92
|
+
points = new double[5 * count];
|
93
|
+
for (int i = 0; i < count; i++) {
|
94
|
+
ev.getPointerCoords(i, r);
|
95
|
+
points[pointerIndex++] = r.x;
|
96
|
+
points[pointerIndex++] = r.y;
|
97
|
+
points[pointerIndex++] = ev.getPressure(i);
|
98
|
+
points[pointerIndex++] = motionActionToType(action);
|
99
|
+
points[pointerIndex++] = ev.getPointerId(i);
|
100
|
+
}
|
101
|
+
|
102
|
+
updateTouchPoints(points);
|
103
|
+
|
104
|
+
break;
|
83
105
|
}
|
84
|
-
points[i+4] = ev.getPointerId(i);
|
85
106
|
}
|
86
|
-
|
107
|
+
|
87
108
|
return true;
|
88
109
|
}
|
89
110
|
|
111
|
+
private static int motionActionToType(int action) {
|
112
|
+
int actionType = 3;
|
113
|
+
switch (action) {
|
114
|
+
case MotionEvent.ACTION_DOWN:
|
115
|
+
case MotionEvent.ACTION_POINTER_DOWN:
|
116
|
+
actionType = 0;
|
117
|
+
break;
|
118
|
+
case MotionEvent.ACTION_MOVE:
|
119
|
+
actionType = 1;
|
120
|
+
break;
|
121
|
+
case MotionEvent.ACTION_UP:
|
122
|
+
case MotionEvent.ACTION_POINTER_UP:
|
123
|
+
actionType = 2;
|
124
|
+
break;
|
125
|
+
case MotionEvent.ACTION_CANCEL:
|
126
|
+
actionType = 3;
|
127
|
+
break;
|
128
|
+
}
|
129
|
+
return actionType;
|
130
|
+
}
|
131
|
+
|
90
132
|
@Override
|
91
133
|
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
92
134
|
mSurface = new Surface(surface);
|
@@ -104,7 +146,7 @@ public class SkiaDrawView extends TextureView implements TextureView.SurfaceText
|
|
104
146
|
// https://developer.android.com/reference/android/view/TextureView.SurfaceTextureListener#onSurfaceTextureDestroyed(android.graphics.SurfaceTexture)
|
105
147
|
// Invoked when the specified SurfaceTexture is about to be destroyed. If returns true,
|
106
148
|
// no rendering should happen inside the surface texture after this method is invoked.
|
107
|
-
//
|
149
|
+
// When returning false, the client needs to call SurfaceTexture#release().
|
108
150
|
return false;
|
109
151
|
}
|
110
152
|
|
@@ -54,7 +54,63 @@ void RNSkDrawView::setNativeId(size_t nativeId) {
|
|
54
54
|
beginDrawingLoop();
|
55
55
|
}
|
56
56
|
|
57
|
-
void RNSkDrawView::
|
57
|
+
void RNSkDrawView::callJsDrawCallback(int width, int height, double timestamp) {
|
58
|
+
if(_drawCallback == nullptr) {
|
59
|
+
return;
|
60
|
+
}
|
61
|
+
|
62
|
+
// Reset timing info
|
63
|
+
_jsTimingInfo.reset();
|
64
|
+
_gpuTimingInfo.reset();
|
65
|
+
|
66
|
+
auto runtime = getPlatformContext()->getJsRuntime();
|
67
|
+
|
68
|
+
// Update info parameter
|
69
|
+
_infoObject->beginDrawOperation(width, height, timestamp);
|
70
|
+
|
71
|
+
// Set up arguments array
|
72
|
+
std::vector<jsi::Value> args(2);
|
73
|
+
args[0] = jsi::Object::createFromHostObject(*runtime, _jsiCanvas);
|
74
|
+
args[1] = jsi::Object::createFromHostObject(*runtime, _infoObject);
|
75
|
+
|
76
|
+
// To be able to call the drawing function we'll wrap it once again
|
77
|
+
_drawCallback->call(*runtime,
|
78
|
+
static_cast<const jsi::Value *>(args.data()),
|
79
|
+
(size_t)2);
|
80
|
+
|
81
|
+
// Reset touches
|
82
|
+
_infoObject->endDrawOperation();
|
83
|
+
|
84
|
+
// Draw debug overlays
|
85
|
+
if (_showDebugOverlay) {
|
86
|
+
|
87
|
+
// Display average rendering timer
|
88
|
+
auto jsAvg = _jsTimingInfo.getAverage();
|
89
|
+
//auto jsFps = _jsTimingInfo.getFps();
|
90
|
+
|
91
|
+
auto gpuAvg = _gpuTimingInfo.getAverage();
|
92
|
+
//auto gpuFps = _gpuTimingInfo.getFps();
|
93
|
+
|
94
|
+
auto total = jsAvg + gpuAvg;
|
95
|
+
|
96
|
+
// Build string
|
97
|
+
std::ostringstream stream;
|
98
|
+
stream << "js: " << jsAvg << "ms gpu: " << gpuAvg << "ms " << " total: " << total << "ms";
|
99
|
+
|
100
|
+
std::string debugString = stream.str();
|
101
|
+
|
102
|
+
// Set up debug font/paints
|
103
|
+
auto font = SkFont();
|
104
|
+
font.setSize(14);
|
105
|
+
auto paint = SkPaint();
|
106
|
+
paint.setColor(SkColors::kRed);
|
107
|
+
_jsiCanvas->getCanvas()->drawSimpleText(
|
108
|
+
debugString.c_str(), debugString.size(), SkTextEncoding::kUTF8, 8,
|
109
|
+
18, font, paint);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
void RNSkDrawView::setDrawCallback(std::shared_ptr<FunctionWrapper> callback) {
|
58
114
|
|
59
115
|
if (callback == nullptr) {
|
60
116
|
_drawCallback = nullptr;
|
@@ -62,69 +118,9 @@ void RNSkDrawView::setDrawCallback(std::shared_ptr<jsi::Function> callback) {
|
|
62
118
|
endDrawingLoop();
|
63
119
|
return;
|
64
120
|
}
|
65
|
-
|
66
|
-
//
|
67
|
-
|
68
|
-
_gpuTimingInfo.reset();
|
69
|
-
|
70
|
-
// Create draw drawCallback wrapper
|
71
|
-
_drawCallback = std::make_shared<RNSkDrawCallback>(
|
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
|
-
}
|
126
|
-
}
|
127
|
-
});
|
121
|
+
|
122
|
+
// Save callback
|
123
|
+
_drawCallback = callback;
|
128
124
|
|
129
125
|
// Request redraw
|
130
126
|
requestRedraw();
|
@@ -144,7 +140,7 @@ void RNSkDrawView::drawInCanvas(std::shared_ptr<JsiSkCanvas> canvas,
|
|
144
140
|
skCanvas->scale(pd, pd);
|
145
141
|
|
146
142
|
// Call draw function.
|
147
|
-
(
|
143
|
+
callJsDrawCallback(width / pd, height / pd, time);
|
148
144
|
|
149
145
|
// Restore and flush canvas
|
150
146
|
skCanvas->restore();
|
@@ -203,6 +199,8 @@ void RNSkDrawView::performDraw() {
|
|
203
199
|
|
204
200
|
// Finish drawing operations
|
205
201
|
auto p = recorder.finishRecordingAsPicture();
|
202
|
+
|
203
|
+
_jsiCanvas->setCanvas(nullptr);
|
206
204
|
|
207
205
|
// Calculate duration
|
208
206
|
_jsTimingInfo.stopTiming();
|
@@ -217,7 +215,9 @@ void RNSkDrawView::performDraw() {
|
|
217
215
|
if (self) {
|
218
216
|
// Draw the picture recorded on the real GPU canvas
|
219
217
|
self->_gpuTimingInfo.beginTiming();
|
220
|
-
self->
|
218
|
+
self->renderToSkiaCanvas([p = std::move(p)](SkCanvas* canvas) {
|
219
|
+
canvas->drawPicture(p);
|
220
|
+
});
|
221
221
|
self->_gpuTimingInfo.stopTiming();
|
222
222
|
}
|
223
223
|
// Unlock GPU drawing
|
@@ -16,7 +16,7 @@
|
|
16
16
|
#pragma clang diagnostic push
|
17
17
|
#pragma clang diagnostic ignored "-Wdocumentation"
|
18
18
|
|
19
|
-
#include <
|
19
|
+
#include <SkCanvas.h>
|
20
20
|
|
21
21
|
#pragma clang diagnostic pop
|
22
22
|
|
@@ -33,6 +33,16 @@ using RNSkDrawCallback =
|
|
33
33
|
|
34
34
|
enum RNSkDrawingMode { Default, Continuous };
|
35
35
|
|
36
|
+
class FunctionWrapper {
|
37
|
+
public:
|
38
|
+
FunctionWrapper(jsi::Function &&func): _func(std::move(func)) {}
|
39
|
+
jsi::Value call(jsi::Runtime& runtime, const jsi::Value* args, size_t count) {
|
40
|
+
return _func.call(runtime, args, count);
|
41
|
+
}
|
42
|
+
private:
|
43
|
+
jsi::Function _func;
|
44
|
+
};
|
45
|
+
|
36
46
|
class RNSkDrawView: public std::enable_shared_from_this<RNSkDrawView> {
|
37
47
|
public:
|
38
48
|
/**
|
@@ -60,7 +70,7 @@ public:
|
|
60
70
|
/**
|
61
71
|
* Installs the draw callback for the view
|
62
72
|
*/
|
63
|
-
void setDrawCallback(std::shared_ptr<
|
73
|
+
void setDrawCallback(std::shared_ptr<FunctionWrapper> callback);
|
64
74
|
|
65
75
|
/**
|
66
76
|
Sets the native id of the view
|
@@ -105,9 +115,9 @@ protected:
|
|
105
115
|
virtual float getScaledHeight() = 0;
|
106
116
|
|
107
117
|
/**
|
108
|
-
Override to render
|
118
|
+
Override to render to a canvas
|
109
119
|
*/
|
110
|
-
virtual void
|
120
|
+
virtual void renderToSkiaCanvas(const std::function<void(SkCanvas*)>&) = 0;
|
111
121
|
|
112
122
|
/**
|
113
123
|
* @return The platformcontext
|
@@ -116,7 +126,13 @@ protected:
|
|
116
126
|
return _platformContext;
|
117
127
|
}
|
118
128
|
|
119
|
-
private:
|
129
|
+
private:
|
130
|
+
/**
|
131
|
+
* Calls the JS draw callback. This is the JS function that does the actual drawing so this
|
132
|
+
* method must be called from the JS thread.
|
133
|
+
*/
|
134
|
+
void callJsDrawCallback(int width, int height, double timestamp);
|
135
|
+
|
120
136
|
/**
|
121
137
|
Starts beginDrawCallback loop if the drawing mode is continuous
|
122
138
|
*/
|
@@ -143,7 +159,7 @@ private:
|
|
143
159
|
/**
|
144
160
|
* Stores the draw drawCallback
|
145
161
|
*/
|
146
|
-
std::shared_ptr<
|
162
|
+
std::shared_ptr<FunctionWrapper> _drawCallback;
|
147
163
|
|
148
164
|
/**
|
149
165
|
* Stores a pointer to the jsi wrapper for the canvas. The reason for
|
@@ -19,7 +19,7 @@ using CallbackInfo = struct CallbackInfo {
|
|
19
19
|
drawCallback = nullptr;
|
20
20
|
view = nullptr;
|
21
21
|
}
|
22
|
-
std::shared_ptr<
|
22
|
+
std::shared_ptr<FunctionWrapper> drawCallback;
|
23
23
|
std::shared_ptr<RNSkDrawView> view;
|
24
24
|
};
|
25
25
|
|
@@ -61,7 +61,7 @@ public:
|
|
61
61
|
if (arguments[1].isUndefined()) {
|
62
62
|
info->drawCallback = nullptr;
|
63
63
|
} else {
|
64
|
-
info->drawCallback = std::make_shared<
|
64
|
+
info->drawCallback = std::make_shared<FunctionWrapper>(
|
65
65
|
arguments[1].asObject(runtime).asFunction(runtime));
|
66
66
|
}
|
67
67
|
|
@@ -43,6 +43,16 @@ public:
|
|
43
43
|
_callback = std::make_shared<jsi::Function>(arguments[0].asObject(runtime).asFunction(runtime));
|
44
44
|
}
|
45
45
|
|
46
|
+
void invalidate() override {
|
47
|
+
RNSkReadonlyValue::invalidate();
|
48
|
+
|
49
|
+
// Unregister listeners
|
50
|
+
for(const auto &unsubscribe: _unsubscribers) {
|
51
|
+
unsubscribe();
|
52
|
+
}
|
53
|
+
_unsubscribers.clear();
|
54
|
+
}
|
55
|
+
|
46
56
|
void initializeDependencies(jsi::Runtime &runtime, const jsi::Value *arguments, size_t count) {
|
47
57
|
// Save dependencies
|
48
58
|
std::vector<std::shared_ptr<RNSkReadonlyValue>> dependencies;
|
@@ -80,13 +90,6 @@ public:
|
|
80
90
|
dependencyUpdated(runtime);
|
81
91
|
}
|
82
92
|
|
83
|
-
virtual ~RNSkComputedValue() {
|
84
|
-
// Unregister listeners
|
85
|
-
for(const auto &unsubscribe: _unsubscribers) {
|
86
|
-
unsubscribe();
|
87
|
-
}
|
88
|
-
}
|
89
|
-
|
90
93
|
private:
|
91
94
|
void dependencyUpdated(jsi::Runtime &runtime) {
|
92
95
|
// Calculate new value
|
@@ -30,7 +30,9 @@ public:
|
|
30
30
|
_valueHolder(std::make_unique<JsiSimpleValueWrapper>(*platformContext->getJsRuntime()))
|
31
31
|
{ }
|
32
32
|
|
33
|
-
virtual ~RNSkReadonlyValue() {
|
33
|
+
virtual ~RNSkReadonlyValue() {
|
34
|
+
invalidate();
|
35
|
+
}
|
34
36
|
|
35
37
|
JSI_PROPERTY_GET(__typename__) {
|
36
38
|
return jsi::String::createFromUtf8(runtime, "RNSkValue");
|
@@ -68,7 +70,15 @@ public:
|
|
68
70
|
});
|
69
71
|
}
|
70
72
|
|
71
|
-
|
73
|
+
|
74
|
+
|
75
|
+
JSI_HOST_FUNCTION(__invalidate) {
|
76
|
+
invalidate();
|
77
|
+
return jsi::Value::undefined();
|
78
|
+
}
|
79
|
+
|
80
|
+
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(RNSkReadonlyValue, addListener),
|
81
|
+
JSI_EXPORT_FUNC(RNSkReadonlyValue, __invalidate))
|
72
82
|
|
73
83
|
/**
|
74
84
|
* Adds a callback that will be called whenever the value changes
|
@@ -102,6 +112,15 @@ public:
|
|
102
112
|
}
|
103
113
|
}
|
104
114
|
|
115
|
+
/**
|
116
|
+
Override to implement invalidation logic for the value. In the base class this function
|
117
|
+
clears all subscribers.
|
118
|
+
*/
|
119
|
+
virtual void invalidate() {
|
120
|
+
std::lock_guard<std::mutex> lock(_mutex);
|
121
|
+
_listeners.clear();
|
122
|
+
}
|
123
|
+
|
105
124
|
jsi::Value getCurrent(jsi::Runtime &runtime) {
|
106
125
|
return _valueHolder->getCurrent(runtime);
|
107
126
|
}
|
@@ -32,7 +32,7 @@ protected:
|
|
32
32
|
float getScaledHeight() override { return _height * _context->getPixelDensity(); };
|
33
33
|
|
34
34
|
private:
|
35
|
-
void
|
35
|
+
void renderToSkiaCanvas(const std::function<void(SkCanvas*)>& cb) override;
|
36
36
|
bool createSkiaSurface();
|
37
37
|
|
38
38
|
int _nativeId;
|
@@ -60,7 +60,7 @@ void RNSkDrawViewImpl::setSize(int width, int height) {
|
|
60
60
|
requestRedraw();
|
61
61
|
}
|
62
62
|
|
63
|
-
void RNSkDrawViewImpl::
|
63
|
+
void RNSkDrawViewImpl::renderToSkiaCanvas(const std::function<void(SkCanvas*)>& cb) {
|
64
64
|
if(_width == -1 && _height == -1) {
|
65
65
|
return;
|
66
66
|
}
|
@@ -103,7 +103,7 @@ void RNSkDrawViewImpl::drawPicture(const sk_sp<SkPicture> picture) {
|
|
103
103
|
}
|
104
104
|
|
105
105
|
skSurface->getCanvas()->clear(SK_AlphaTRANSPARENT);
|
106
|
-
skSurface->getCanvas()
|
106
|
+
cb(skSurface->getCanvas());
|
107
107
|
|
108
108
|
id<MTLCommandBuffer> commandBuffer([_commandQueue commandBuffer]);
|
109
109
|
[commandBuffer presentDrawable:currentDrawable];
|
@@ -73,6 +73,10 @@
|
|
73
73
|
if(_manager != nullptr && _nativeId != 0) {
|
74
74
|
_manager->unregisterSkiaDrawView(_nativeId);
|
75
75
|
}
|
76
|
+
|
77
|
+
[[NSNotificationCenter defaultCenter] removeObserver:self name:RCTBridgeWillInvalidateModulesNotification object:nil];
|
78
|
+
|
79
|
+
assert(_impl == nullptr);
|
76
80
|
}
|
77
81
|
|
78
82
|
#pragma mark Layout
|
@@ -9,6 +9,8 @@ var Values = _interopRequireWildcard(require("../values/web"));
|
|
9
9
|
|
10
10
|
var ValuesHooks = _interopRequireWildcard(require("../values/hooks"));
|
11
11
|
|
12
|
+
var _selector = require("../values/selector");
|
13
|
+
|
12
14
|
var BaseSkia = _interopRequireWildcard(require("../skia/types"));
|
13
15
|
|
14
16
|
var _useSharedValueEffect = require("../external/reanimated/useSharedValueEffect");
|
@@ -64,7 +66,6 @@ const Mock = {
|
|
64
66
|
Skia,
|
65
67
|
...BaseSkia,
|
66
68
|
// 2. Hooks
|
67
|
-
useDataCollection: Noop,
|
68
69
|
useRawData: Noop,
|
69
70
|
useData: Noop,
|
70
71
|
useFont: Noop,
|
@@ -113,6 +114,7 @@ const Mock = {
|
|
113
114
|
// ValueExports
|
114
115
|
...Values,
|
115
116
|
...ValuesHooks,
|
117
|
+
Selector: _selector.Selector,
|
116
118
|
// Animations
|
117
119
|
...timingFunctions,
|
118
120
|
...springFunctions,
|