@shopify/react-native-skia 2.9.1-next.1 → 2.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/cpp/jni/JniWebGPUView.cpp +52 -7
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUSurfaceView.java +3 -1
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUTextureView.java +11 -5
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUView.java +10 -7
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUViewAPI.java +7 -2
- package/android/src/main/java/com/shopify/reactnative/skia/WebGPUViewManager.java +1 -1
- package/apple/WebGPUMetalView.mm +49 -6
- package/cpp/api/JsiSkParagraphStyle.h +20 -10
- package/cpp/api/JsiSkStrutStyle.h +18 -8
- package/cpp/api/JsiSkTextStyle.h +34 -24
- package/cpp/rnskia/RNSkManager.cpp +6 -0
- package/cpp/rnwgpu/SurfaceRegistry.h +469 -131
- package/cpp/rnwgpu/api/GPUAdapter.cpp +10 -3
- package/cpp/rnwgpu/api/GPUAdapter.h +5 -4
- package/cpp/rnwgpu/api/GPUBuffer.cpp +12 -2
- package/cpp/rnwgpu/api/GPUBuffer.h +3 -2
- package/cpp/rnwgpu/api/GPUCanvasContext.cpp +33 -19
- package/cpp/rnwgpu/api/GPUCanvasContext.h +3 -1
- package/cpp/rnwgpu/api/GPUDevice.cpp +32 -17
- package/cpp/rnwgpu/api/GPUDevice.h +9 -7
- package/cpp/rnwgpu/api/GPUQueue.cpp +6 -2
- package/cpp/rnwgpu/api/GPUQueue.h +3 -3
- package/cpp/rnwgpu/api/GPUShaderModule.cpp +7 -2
- package/cpp/rnwgpu/api/GPUShaderModule.h +3 -3
- package/cpp/rnwgpu/api/RNWebGPU.h +20 -0
- package/cpp/rnwgpu/async/RuntimeContext.cpp +5 -0
- package/cpp/rnwgpu/async/RuntimeContext.h +15 -2
- package/lib/commonjs/views/WebGPUCanvas.d.ts +1 -0
- package/lib/commonjs/views/WebGPUCanvas.js +13 -0
- package/lib/commonjs/views/WebGPUCanvas.js.map +1 -1
- package/lib/module/views/WebGPUCanvas.d.ts +1 -0
- package/lib/module/views/WebGPUCanvas.js +14 -1
- package/lib/module/views/WebGPUCanvas.js.map +1 -1
- package/lib/typescript/src/views/WebGPUCanvas.d.ts +1 -0
- package/package.json +7 -7
- package/src/views/WebGPUCanvas.tsx +17 -1
- package/cpp/dawn/include/dawn/dawn_proc.h +0 -53
- package/cpp/dawn/include/dawn/dawn_proc_table.h +0 -330
- package/cpp/dawn/include/dawn/dawn_thread_dispatch_proc.h +0 -47
- package/cpp/dawn/include/dawn/dawn_version.h +0 -41
- package/cpp/dawn/include/dawn/native/D3D11Backend.h +0 -65
- package/cpp/dawn/include/dawn/native/D3D12Backend.h +0 -86
- package/cpp/dawn/include/dawn/native/D3DBackend.h +0 -56
- package/cpp/dawn/include/dawn/native/DawnNative.h +0 -369
- package/cpp/dawn/include/dawn/native/MetalBackend.h +0 -56
- package/cpp/dawn/include/dawn/native/NullBackend.h +0 -39
- package/cpp/dawn/include/dawn/native/OpenGLBackend.h +0 -89
- package/cpp/dawn/include/dawn/native/VulkanBackend.h +0 -183
- package/cpp/dawn/include/dawn/native/WebGPUBackend.h +0 -49
- package/cpp/dawn/include/dawn/native/dawn_native_export.h +0 -49
- package/cpp/dawn/include/dawn/platform/DawnPlatform.h +0 -210
- package/cpp/dawn/include/dawn/platform/dawn_platform_export.h +0 -49
- package/cpp/dawn/include/dawn/replay/Replay.h +0 -99
- package/cpp/dawn/include/dawn/replay/dawn_replay_export.h +0 -49
- package/cpp/dawn/include/dawn/webgpu_cpp_print.h +0 -2844
- package/cpp/dawn/include/tint/tint.h +0 -90
- package/cpp/dawn/include/webgpu/webgpu.h +0 -4987
- package/cpp/dawn/include/webgpu/webgpu_cpp.h +0 -10080
- package/cpp/dawn/include/webgpu/webgpu_cpp_chained_struct.h +0 -57
- package/cpp/dawn/include/webgpu/webgpu_enum_class_bitmasks.h +0 -161
- package/cpp/dawn/include/webgpu/webgpu_glfw.h +0 -88
- package/cpp/skia/src/gpu/graphite/ContextOptionsPriv.h +0 -45
- package/cpp/skia/src/gpu/graphite/ResourceTypes.h +0 -360
- package/cpp/skia/src/gpu/graphite/TextureProxyView.h +0 -105
- package/libs/.graphite +0 -1
|
@@ -2,9 +2,35 @@
|
|
|
2
2
|
#include <jni.h>
|
|
3
3
|
|
|
4
4
|
#ifdef SK_GRAPHITE
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <utility>
|
|
7
|
+
|
|
8
|
+
#include <ReactCommon/CallInvoker.h>
|
|
9
|
+
|
|
5
10
|
#include "rnskia/RNDawnContext.h"
|
|
6
11
|
#include "rnwgpu/SurfaceRegistry.h"
|
|
12
|
+
#include "rnwgpu/async/RuntimeContext.h"
|
|
7
13
|
#include "webgpu/webgpu_cpp.h"
|
|
14
|
+
|
|
15
|
+
namespace {
|
|
16
|
+
// Applies a surface attach latched by the platform UI thread (see
|
|
17
|
+
// SurfaceInfo::applyPendingAttach) from the JS thread. Surface attaches are
|
|
18
|
+
// normally adopted at the next frame boundary by whichever thread renders;
|
|
19
|
+
// this flush covers contexts that are not actively rendering (static
|
|
20
|
+
// content), so the last offscreen frame still makes it on screen. Mirrors
|
|
21
|
+
// react-native-webgpu's RNWebGPUManager::flushPendingSurfaceTransition.
|
|
22
|
+
void flushPendingSurfaceTransition(std::shared_ptr<rnwgpu::SurfaceInfo> info) {
|
|
23
|
+
if (info == nullptr) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
auto invoker = rnwgpu::async::RuntimeContext::mainCallInvoker();
|
|
27
|
+
if (invoker == nullptr) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
invoker->invokeAsync(
|
|
31
|
+
[info = std::move(info)] { info->applyPendingAttach(); });
|
|
32
|
+
}
|
|
33
|
+
} // namespace
|
|
8
34
|
#endif
|
|
9
35
|
|
|
10
36
|
extern "C" JNIEXPORT void JNICALL
|
|
@@ -12,7 +38,12 @@ Java_com_shopify_reactnative_skia_WebGPUView_onSurfaceCreate(
|
|
|
12
38
|
JNIEnv *env, jobject thiz, jobject jSurface, jint contextId, jfloat width,
|
|
13
39
|
jfloat height) {
|
|
14
40
|
#ifdef SK_GRAPHITE
|
|
41
|
+
// ANativeWindow_fromSurface acquires a reference; SurfaceInfo releases it
|
|
42
|
+
// (via the releaser below) once it is done with the window.
|
|
15
43
|
auto window = ANativeWindow_fromSurface(env, jSurface);
|
|
44
|
+
if (window == nullptr) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
16
47
|
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
17
48
|
auto &dawnContext = RNSkia::DawnContext::getInstance();
|
|
18
49
|
auto gpu = dawnContext.getWGPUInstance();
|
|
@@ -24,10 +55,17 @@ Java_com_shopify_reactnative_skia_WebGPUView_onSurfaceCreate(
|
|
|
24
55
|
surfaceDescriptor.nextInChain = &androidSurfaceDesc;
|
|
25
56
|
auto surface = gpu.CreateSurface(&surfaceDescriptor);
|
|
26
57
|
|
|
27
|
-
registry
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
58
|
+
// Find-or-create + attach runs atomically under the registry lock so a
|
|
59
|
+
// concurrent destroyContext cannot orphan this surface.
|
|
60
|
+
auto info = registry.attachSurface(
|
|
61
|
+
contextId, gpu, static_cast<int>(width), static_cast<int>(height), window,
|
|
62
|
+
surface, [](void *nativeSurface) {
|
|
63
|
+
ANativeWindow_release(static_cast<ANativeWindow *>(nativeSurface));
|
|
64
|
+
});
|
|
65
|
+
// The attach is adopted at the next frame boundary by the rendering thread;
|
|
66
|
+
// schedule a flush so contexts that are not currently rendering still pick
|
|
67
|
+
// it up (and present their last offscreen frame).
|
|
68
|
+
flushPendingSurfaceTransition(info);
|
|
31
69
|
#endif
|
|
32
70
|
}
|
|
33
71
|
|
|
@@ -57,11 +95,18 @@ Java_com_shopify_reactnative_skia_WebGPUView_switchToOffscreenSurface(
|
|
|
57
95
|
}
|
|
58
96
|
|
|
59
97
|
extern "C" JNIEXPORT void JNICALL
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
98
|
+
Java_com_shopify_reactnative_skia_WebGPUView_onViewDestroyed(JNIEnv *env,
|
|
99
|
+
jobject thiz,
|
|
100
|
+
jint contextId) {
|
|
63
101
|
#ifdef SK_GRAPHITE
|
|
102
|
+
// The view dies with its Canvas (contextIds are never reused), so view
|
|
103
|
+
// teardown retires the registry entry. The JS-side cleanup
|
|
104
|
+
// (RNWebGPU.destroyContext) only handles entries that never had a native
|
|
105
|
+
// surface; see RNWebGPU::destroyContext for the ownership split.
|
|
64
106
|
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
107
|
+
if (auto info = registry.getSurfaceInfo(contextId)) {
|
|
108
|
+
info->detachSurface();
|
|
109
|
+
}
|
|
65
110
|
registry.removeSurfaceInfo(contextId);
|
|
66
111
|
#endif
|
|
67
112
|
}
|
|
@@ -21,7 +21,9 @@ public class WebGPUSurfaceView extends SurfaceView implements SurfaceHolder.Call
|
|
|
21
21
|
@Override
|
|
22
22
|
protected void onDetachedFromWindow() {
|
|
23
23
|
super.onDetachedFromWindow();
|
|
24
|
-
|
|
24
|
+
// surfaceDestroyed() normally fires during detach as well; going offscreen
|
|
25
|
+
// is idempotent, so this is just a safety net for paths where it does not.
|
|
26
|
+
mApi.surfaceOffscreen();
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
@Override
|
|
@@ -11,6 +11,7 @@ import androidx.annotation.NonNull;
|
|
|
11
11
|
public class WebGPUTextureView extends TextureView implements TextureView.SurfaceTextureListener {
|
|
12
12
|
|
|
13
13
|
WebGPUViewAPI mApi;
|
|
14
|
+
private Surface mSurface;
|
|
14
15
|
|
|
15
16
|
public WebGPUTextureView(Context context, WebGPUViewAPI api) {
|
|
16
17
|
super(context);
|
|
@@ -21,19 +22,24 @@ public class WebGPUTextureView extends TextureView implements TextureView.Surfac
|
|
|
21
22
|
|
|
22
23
|
@Override
|
|
23
24
|
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int width, int height) {
|
|
24
|
-
|
|
25
|
-
mApi.surfaceCreated(
|
|
25
|
+
mSurface = new Surface(surfaceTexture);
|
|
26
|
+
mApi.surfaceCreated(mSurface);
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
@Override
|
|
29
30
|
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int width, int height) {
|
|
30
|
-
|
|
31
|
-
mApi.surfaceChanged(surface);
|
|
31
|
+
mApi.surfaceChanged(mSurface);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
@Override
|
|
35
35
|
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
|
|
36
|
-
|
|
36
|
+
// Detach first (synchronous through JNI) so the native side has dropped
|
|
37
|
+
// its window reference before we release ours.
|
|
38
|
+
mApi.surfaceOffscreen();
|
|
39
|
+
if (mSurface != null) {
|
|
40
|
+
mSurface.release();
|
|
41
|
+
mSurface = null;
|
|
42
|
+
}
|
|
37
43
|
return true;
|
|
38
44
|
}
|
|
39
45
|
|
|
@@ -61,16 +61,19 @@ public class WebGPUView extends ReactViewGroup implements WebGPUViewAPI {
|
|
|
61
61
|
onSurfaceChanged(surface, mContextId, width, height);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
@Override
|
|
65
|
-
public void surfaceDestroyed() {
|
|
66
|
-
onSurfaceDestroy(mContextId);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
64
|
@Override
|
|
70
65
|
public void surfaceOffscreen() {
|
|
71
66
|
switchToOffscreenSurface(mContextId);
|
|
72
67
|
}
|
|
73
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Called from WebGPUViewManager.onDropViewInstance when React removes this
|
|
71
|
+
* view: the view dies with its Canvas, so it retires the registry entry.
|
|
72
|
+
*/
|
|
73
|
+
public void destroy() {
|
|
74
|
+
onViewDestroyed(mContextId);
|
|
75
|
+
}
|
|
76
|
+
|
|
74
77
|
@DoNotStrip
|
|
75
78
|
private native void onSurfaceCreate(
|
|
76
79
|
Surface surface,
|
|
@@ -88,8 +91,8 @@ public class WebGPUView extends ReactViewGroup implements WebGPUViewAPI {
|
|
|
88
91
|
);
|
|
89
92
|
|
|
90
93
|
@DoNotStrip
|
|
91
|
-
private native void
|
|
94
|
+
private native void switchToOffscreenSurface(int contextId);
|
|
92
95
|
|
|
93
96
|
@DoNotStrip
|
|
94
|
-
private native void
|
|
97
|
+
private native void onViewDestroyed(int contextId);
|
|
95
98
|
}
|
|
@@ -2,13 +2,18 @@ package com.shopify.reactnative.skia;
|
|
|
2
2
|
|
|
3
3
|
import android.view.Surface;
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Surface lifecycle events a WebGPU child view reports. The registry entry
|
|
7
|
+
* itself is owned by the JS Canvas component (created lazily, removed via
|
|
8
|
+
* RNWebGPU.destroyContext on unmount); views only attach and detach surfaces.
|
|
9
|
+
* A detached context keeps rendering into an offscreen texture whose content
|
|
10
|
+
* is blitted onto the next attached surface.
|
|
11
|
+
*/
|
|
5
12
|
public interface WebGPUViewAPI {
|
|
6
13
|
|
|
7
14
|
void surfaceCreated(Surface surface);
|
|
8
15
|
|
|
9
16
|
void surfaceChanged(Surface surface);
|
|
10
17
|
|
|
11
|
-
void surfaceDestroyed();
|
|
12
|
-
|
|
13
18
|
void surfaceOffscreen();
|
|
14
19
|
}
|
|
@@ -53,6 +53,6 @@ public class WebGPUViewManager extends ReactViewManager implements SkiaWebGPUVie
|
|
|
53
53
|
@Override
|
|
54
54
|
public void onDropViewInstance(@NonNull ReactViewGroup view) {
|
|
55
55
|
super.onDropViewInstance(view);
|
|
56
|
-
((WebGPUView) view).
|
|
56
|
+
((WebGPUView) view).destroy();
|
|
57
57
|
}
|
|
58
58
|
}
|
package/apple/WebGPUMetalView.mm
CHANGED
|
@@ -5,8 +5,30 @@
|
|
|
5
5
|
#import "webgpu/webgpu_cpp.h"
|
|
6
6
|
#import <QuartzCore/CAMetalLayer.h>
|
|
7
7
|
|
|
8
|
+
#import <ReactCommon/CallInvoker.h>
|
|
9
|
+
|
|
8
10
|
#import "rnskia/RNDawnContext.h"
|
|
9
11
|
#import "rnwgpu/SurfaceRegistry.h"
|
|
12
|
+
#import "rnwgpu/async/RuntimeContext.h"
|
|
13
|
+
|
|
14
|
+
namespace {
|
|
15
|
+
// Applies a surface attach latched by the platform UI thread (see
|
|
16
|
+
// SurfaceInfo::applyPendingAttach) from the JS thread. Surface attaches are
|
|
17
|
+
// normally adopted at the next frame boundary by whichever thread renders;
|
|
18
|
+
// this flush covers contexts that are not actively rendering (static
|
|
19
|
+
// content), so the last offscreen frame still makes it on screen. Mirrors
|
|
20
|
+
// react-native-webgpu's RNWebGPUManager::flushPendingSurfaceTransition.
|
|
21
|
+
void flushPendingSurfaceTransition(std::shared_ptr<rnwgpu::SurfaceInfo> info) {
|
|
22
|
+
if (info == nullptr) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
auto invoker = rnwgpu::async::RuntimeContext::mainCallInvoker();
|
|
26
|
+
if (invoker == nullptr) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
invoker->invokeAsync([info = std::move(info)] { info->applyPendingAttach(); });
|
|
30
|
+
}
|
|
31
|
+
} // namespace
|
|
10
32
|
|
|
11
33
|
@implementation WebGPUMetalView {
|
|
12
34
|
BOOL _isConfigured;
|
|
@@ -29,7 +51,11 @@
|
|
|
29
51
|
|
|
30
52
|
- (void)configure {
|
|
31
53
|
auto size = self.frame.size;
|
|
32
|
-
|
|
54
|
+
// Retain the layer for as long as SurfaceInfo holds the pointer: the
|
|
55
|
+
// latched attach (and the flush lambda that adopts it) can outlive this
|
|
56
|
+
// view, e.g. across a dev reload where the registry is cleared before
|
|
57
|
+
// dealloc runs. Balanced by the releaser below.
|
|
58
|
+
void *nativeSurface = (void *)CFBridgingRetain(self.layer);
|
|
33
59
|
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
34
60
|
auto &dawnContext = RNSkia::DawnContext::getInstance();
|
|
35
61
|
auto gpu = dawnContext.getWGPUInstance();
|
|
@@ -41,10 +67,21 @@
|
|
|
41
67
|
surfaceDescriptor.nextInChain = &metalSurfaceDesc;
|
|
42
68
|
auto surface = gpu.CreateSurface(&surfaceDescriptor);
|
|
43
69
|
|
|
44
|
-
registry
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
70
|
+
// Find-or-create + attach runs atomically under the registry lock so a
|
|
71
|
+
// concurrent destroyContext cannot orphan this surface.
|
|
72
|
+
auto info = registry.attachSurface(
|
|
73
|
+
[_contextId intValue], gpu, size.width, size.height, nativeSurface,
|
|
74
|
+
surface, [](void *layer) {
|
|
75
|
+
// The releaser can run on the rendering thread; CALayer teardown
|
|
76
|
+
// belongs on the main thread.
|
|
77
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
78
|
+
CFBridgingRelease(layer);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
// The attach is adopted at the next frame boundary by the rendering thread;
|
|
82
|
+
// schedule a flush so contexts that are not currently rendering still pick
|
|
83
|
+
// it up (and present their last offscreen frame).
|
|
84
|
+
flushPendingSurfaceTransition(info);
|
|
48
85
|
}
|
|
49
86
|
|
|
50
87
|
- (void)update {
|
|
@@ -57,8 +94,14 @@
|
|
|
57
94
|
}
|
|
58
95
|
|
|
59
96
|
- (void)dealloc {
|
|
97
|
+
// The view dies with its Canvas (contextIds are never reused), so view
|
|
98
|
+
// teardown retires the registry entry. The JS-side cleanup
|
|
99
|
+
// (RNWebGPU.destroyContext) only handles entries that never had a native
|
|
100
|
+
// surface; see RNWebGPU::destroyContext for the ownership split.
|
|
60
101
|
auto ®istry = rnwgpu::SurfaceRegistry::getInstance();
|
|
61
|
-
|
|
102
|
+
if (auto info = registry.getSurfaceInfo([_contextId intValue])) {
|
|
103
|
+
info->detachSurface();
|
|
104
|
+
}
|
|
62
105
|
registry.removeSurfaceInfo([_contextId intValue]);
|
|
63
106
|
}
|
|
64
107
|
|
|
@@ -42,6 +42,16 @@ public:
|
|
|
42
42
|
textHeightBehavior?: SkTextHeightBehavior;
|
|
43
43
|
textStyle?: SkTextStyle;
|
|
44
44
|
*/
|
|
45
|
+
// A property set to undefined or null is treated as absent, like on web.
|
|
46
|
+
static bool hasValue(jsi::Runtime &runtime, const jsi::Object &object,
|
|
47
|
+
const char *name) {
|
|
48
|
+
if (!object.hasProperty(runtime, name)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
auto propValue = object.getProperty(runtime, name);
|
|
52
|
+
return !propValue.isUndefined() && !propValue.isNull();
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
static para::ParagraphStyle fromValue(jsi::Runtime &runtime,
|
|
46
56
|
const jsi::Value &value) {
|
|
47
57
|
para::ParagraphStyle retVal;
|
|
@@ -59,52 +69,52 @@ public:
|
|
|
59
69
|
|
|
60
70
|
auto object = value.asObject(runtime);
|
|
61
71
|
|
|
62
|
-
if (
|
|
72
|
+
if (hasValue(runtime, object, "disableHinting")) {
|
|
63
73
|
auto propValue = object.getProperty(runtime, "disableHinting");
|
|
64
74
|
if (asBool(runtime, propValue)) {
|
|
65
75
|
retVal.turnHintingOff();
|
|
66
76
|
}
|
|
67
77
|
}
|
|
68
|
-
if (
|
|
78
|
+
if (hasValue(runtime, object, "ellipsis")) {
|
|
69
79
|
auto propValue = object.getProperty(runtime, "ellipsis");
|
|
70
80
|
auto inStr = propValue.asString(runtime).utf8(runtime);
|
|
71
81
|
std::u16string uStr;
|
|
72
82
|
fromUTF8(inStr, uStr);
|
|
73
83
|
retVal.setEllipsis(uStr);
|
|
74
84
|
}
|
|
75
|
-
if (
|
|
85
|
+
if (hasValue(runtime, object, "heightMultiplier")) {
|
|
76
86
|
auto propValue = object.getProperty(runtime, "heightMultiplier");
|
|
77
87
|
retVal.setHeight(propValue.asNumber());
|
|
78
88
|
}
|
|
79
|
-
if (
|
|
89
|
+
if (hasValue(runtime, object, "maxLines")) {
|
|
80
90
|
auto propValue = object.getProperty(runtime, "maxLines");
|
|
81
91
|
if (propValue.asNumber() != 0) {
|
|
82
92
|
retVal.setMaxLines(propValue.asNumber());
|
|
83
93
|
}
|
|
84
94
|
}
|
|
85
|
-
if (
|
|
95
|
+
if (hasValue(runtime, object, "replaceTabCharacters")) {
|
|
86
96
|
auto propValue = object.getProperty(runtime, "replaceTabCharacters");
|
|
87
97
|
retVal.setReplaceTabCharacters(asBool(runtime, propValue));
|
|
88
98
|
}
|
|
89
|
-
if (
|
|
99
|
+
if (hasValue(runtime, object, "textAlign")) {
|
|
90
100
|
auto propValue = object.getProperty(runtime, "textAlign");
|
|
91
101
|
retVal.setTextAlign(static_cast<para::TextAlign>(propValue.asNumber()));
|
|
92
102
|
}
|
|
93
|
-
if (
|
|
103
|
+
if (hasValue(runtime, object, "textDirection")) {
|
|
94
104
|
auto propValue = object.getProperty(runtime, "textDirection");
|
|
95
105
|
retVal.setTextDirection(
|
|
96
106
|
static_cast<para::TextDirection>(propValue.asNumber()));
|
|
97
107
|
}
|
|
98
|
-
if (
|
|
108
|
+
if (hasValue(runtime, object, "textHeightBehavior")) {
|
|
99
109
|
auto propValue = object.getProperty(runtime, "textHeightBehavior");
|
|
100
110
|
retVal.setTextHeightBehavior(
|
|
101
111
|
static_cast<para::TextHeightBehavior>(propValue.asNumber()));
|
|
102
112
|
}
|
|
103
|
-
if (
|
|
113
|
+
if (hasValue(runtime, object, "strutStyle")) {
|
|
104
114
|
auto propValue = object.getProperty(runtime, "strutStyle");
|
|
105
115
|
retVal.setStrutStyle(JsiSkStrutStyle::fromValue(runtime, propValue));
|
|
106
116
|
}
|
|
107
|
-
if (
|
|
117
|
+
if (hasValue(runtime, object, "textStyle")) {
|
|
108
118
|
auto propValue = object.getProperty(runtime, "textStyle");
|
|
109
119
|
retVal.setTextStyle(JsiSkTextStyle::fromValue(runtime, propValue));
|
|
110
120
|
}
|
|
@@ -32,6 +32,16 @@ bool asBool(jsi::Runtime &runtime, const jsi::Value &value) {
|
|
|
32
32
|
*/
|
|
33
33
|
class JsiSkStrutStyle {
|
|
34
34
|
public:
|
|
35
|
+
// A property set to undefined or null is treated as absent, like on web.
|
|
36
|
+
static bool hasValue(jsi::Runtime &runtime, const jsi::Object &object,
|
|
37
|
+
const char *name) {
|
|
38
|
+
if (!object.hasProperty(runtime, name)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
auto propValue = object.getProperty(runtime, name);
|
|
42
|
+
return !propValue.isUndefined() && !propValue.isNull();
|
|
43
|
+
}
|
|
44
|
+
|
|
35
45
|
static para::StrutStyle fromValue(jsi::Runtime &runtime,
|
|
36
46
|
const jsi::Value &value) {
|
|
37
47
|
// Read values from the argument - expected to be a TextStyle shaped object
|
|
@@ -52,11 +62,11 @@ public:
|
|
|
52
62
|
|
|
53
63
|
para::StrutStyle retVal;
|
|
54
64
|
|
|
55
|
-
if (
|
|
65
|
+
if (hasValue(runtime, object, "strutEnabled")) {
|
|
56
66
|
auto propValue = object.getProperty(runtime, "strutEnabled");
|
|
57
67
|
retVal.setStrutEnabled(asBool(runtime, propValue));
|
|
58
68
|
}
|
|
59
|
-
if (
|
|
69
|
+
if (hasValue(runtime, object, "fontFamilies")) {
|
|
60
70
|
auto propValue = object.getProperty(runtime, "fontFamilies")
|
|
61
71
|
.asObject(runtime)
|
|
62
72
|
.asArray(runtime);
|
|
@@ -70,28 +80,28 @@ public:
|
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
82
|
|
|
73
|
-
if (
|
|
83
|
+
if (hasValue(runtime, object, "fontStyle")) {
|
|
74
84
|
auto propValue = object.getProperty(runtime, "fontStyle");
|
|
75
85
|
retVal.setFontStyle(*JsiSkFontStyle::fromValue(runtime, propValue).get());
|
|
76
86
|
}
|
|
77
|
-
if (
|
|
87
|
+
if (hasValue(runtime, object, "fontSize")) {
|
|
78
88
|
auto propValue = object.getProperty(runtime, "fontSize");
|
|
79
89
|
retVal.setFontSize(propValue.asNumber());
|
|
80
90
|
}
|
|
81
|
-
if (
|
|
91
|
+
if (hasValue(runtime, object, "heightMultiplier")) {
|
|
82
92
|
auto propValue = object.getProperty(runtime, "heightMultiplier");
|
|
83
93
|
retVal.setHeight(propValue.asNumber());
|
|
84
94
|
retVal.setHeightOverride(true);
|
|
85
95
|
}
|
|
86
|
-
if (
|
|
96
|
+
if (hasValue(runtime, object, "halfLeading")) {
|
|
87
97
|
auto propValue = object.getProperty(runtime, "halfLeading");
|
|
88
98
|
retVal.setHalfLeading(asBool(runtime, propValue));
|
|
89
99
|
}
|
|
90
|
-
if (
|
|
100
|
+
if (hasValue(runtime, object, "leading")) {
|
|
91
101
|
auto propValue = object.getProperty(runtime, "leading");
|
|
92
102
|
retVal.setLeading(propValue.asNumber());
|
|
93
103
|
}
|
|
94
|
-
if (
|
|
104
|
+
if (hasValue(runtime, object, "forceStrutHeight")) {
|
|
95
105
|
auto propValue = object.getProperty(runtime, "forceStrutHeight");
|
|
96
106
|
retVal.setForceStrutHeight(asBool(runtime, propValue));
|
|
97
107
|
}
|
package/cpp/api/JsiSkTextStyle.h
CHANGED
|
@@ -26,6 +26,16 @@ namespace para = skia::textlayout;
|
|
|
26
26
|
*/
|
|
27
27
|
class JsiSkTextStyle {
|
|
28
28
|
public:
|
|
29
|
+
// A property set to undefined or null is treated as absent, like on web.
|
|
30
|
+
static bool hasValue(jsi::Runtime &runtime, const jsi::Object &object,
|
|
31
|
+
const char *name) {
|
|
32
|
+
if (!object.hasProperty(runtime, name)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
auto propValue = object.getProperty(runtime, name);
|
|
36
|
+
return !propValue.isUndefined() && !propValue.isNull();
|
|
37
|
+
}
|
|
38
|
+
|
|
29
39
|
static para::TextStyle fromValue(jsi::Runtime &runtime,
|
|
30
40
|
const jsi::Value &value) {
|
|
31
41
|
|
|
@@ -43,35 +53,35 @@ public:
|
|
|
43
53
|
|
|
44
54
|
auto object = value.asObject(runtime);
|
|
45
55
|
|
|
46
|
-
if (
|
|
56
|
+
if (hasValue(runtime, object, "backgroundColor")) {
|
|
47
57
|
auto propValue = object.getProperty(runtime, "backgroundColor");
|
|
48
58
|
SkPaint p;
|
|
49
59
|
p.setColor(JsiSkColor::fromValue(runtime, propValue));
|
|
50
60
|
retVal.setBackgroundPaint(p);
|
|
51
61
|
}
|
|
52
|
-
if (
|
|
62
|
+
if (hasValue(runtime, object, "color")) {
|
|
53
63
|
auto propValue = object.getProperty(runtime, "color");
|
|
54
64
|
retVal.setColor(JsiSkColor::fromValue(runtime, propValue));
|
|
55
65
|
}
|
|
56
|
-
if (
|
|
66
|
+
if (hasValue(runtime, object, "decoration")) {
|
|
57
67
|
auto propValue = object.getProperty(runtime, "decoration");
|
|
58
68
|
retVal.setDecoration(
|
|
59
69
|
static_cast<para::TextDecoration>(propValue.asNumber()));
|
|
60
70
|
}
|
|
61
|
-
if (
|
|
71
|
+
if (hasValue(runtime, object, "decorationColor")) {
|
|
62
72
|
auto propValue = object.getProperty(runtime, "decorationColor");
|
|
63
73
|
retVal.setDecorationColor(JsiSkColor::fromValue(runtime, propValue));
|
|
64
74
|
}
|
|
65
|
-
if (
|
|
75
|
+
if (hasValue(runtime, object, "decorationThickness")) {
|
|
66
76
|
auto propValue = object.getProperty(runtime, "decorationThickness");
|
|
67
77
|
retVal.setDecorationThicknessMultiplier(propValue.asNumber());
|
|
68
78
|
}
|
|
69
|
-
if (
|
|
79
|
+
if (hasValue(runtime, object, "decorationStyle")) {
|
|
70
80
|
auto propValue = object.getProperty(runtime, "decorationStyle");
|
|
71
81
|
retVal.setDecorationStyle(
|
|
72
82
|
static_cast<para::TextDecorationStyle>(propValue.asNumber()));
|
|
73
83
|
}
|
|
74
|
-
if (
|
|
84
|
+
if (hasValue(runtime, object, "fontFamilies")) {
|
|
75
85
|
auto propValue = object.getProperty(runtime, "fontFamilies")
|
|
76
86
|
.asObject(runtime)
|
|
77
87
|
.asArray(runtime);
|
|
@@ -85,7 +95,7 @@ public:
|
|
|
85
95
|
}
|
|
86
96
|
retVal.setFontFamilies(families);
|
|
87
97
|
}
|
|
88
|
-
if (
|
|
98
|
+
if (hasValue(runtime, object, "fontFeatures")) {
|
|
89
99
|
auto propValue = object.getProperty(runtime, "fontFeatures")
|
|
90
100
|
.asObject(runtime)
|
|
91
101
|
.asArray(runtime);
|
|
@@ -100,58 +110,58 @@ public:
|
|
|
100
110
|
retVal.addFontFeature(SkString(name), value);
|
|
101
111
|
}
|
|
102
112
|
}
|
|
103
|
-
if (
|
|
113
|
+
if (hasValue(runtime, object, "fontSize")) {
|
|
104
114
|
auto propValue = object.getProperty(runtime, "fontSize");
|
|
105
115
|
retVal.setFontSize(propValue.asNumber());
|
|
106
116
|
}
|
|
107
|
-
if (
|
|
117
|
+
if (hasValue(runtime, object, "fontStyle")) {
|
|
108
118
|
auto propValue =
|
|
109
119
|
object.getProperty(runtime, "fontStyle").asObject(runtime);
|
|
110
120
|
auto weight = static_cast<SkFontStyle::Weight>(
|
|
111
|
-
|
|
121
|
+
hasValue(runtime, propValue, "weight")
|
|
112
122
|
? propValue.getProperty(runtime, "weight").asNumber()
|
|
113
123
|
: static_cast<double>(SkFontStyle::Weight::kNormal_Weight));
|
|
114
124
|
|
|
115
125
|
auto width = static_cast<SkFontStyle::Width>(
|
|
116
|
-
|
|
126
|
+
hasValue(runtime, propValue, "width")
|
|
117
127
|
? propValue.getProperty(runtime, "width").asNumber()
|
|
118
128
|
: static_cast<double>(SkFontStyle::Width::kNormal_Width));
|
|
119
129
|
|
|
120
130
|
auto slant = static_cast<SkFontStyle::Slant>(
|
|
121
|
-
|
|
131
|
+
hasValue(runtime, propValue, "slant")
|
|
122
132
|
? propValue.getProperty(runtime, "slant").asNumber()
|
|
123
133
|
: static_cast<double>(SkFontStyle::Slant::kUpright_Slant));
|
|
124
134
|
|
|
125
135
|
retVal.setFontStyle(SkFontStyle(weight, width, slant));
|
|
126
136
|
}
|
|
127
|
-
if (
|
|
137
|
+
if (hasValue(runtime, object, "foregroundColor")) {
|
|
128
138
|
auto propValue = object.getProperty(runtime, "foregroundColor");
|
|
129
139
|
SkPaint p;
|
|
130
140
|
p.setColor(JsiSkColor::fromValue(runtime, propValue));
|
|
131
141
|
retVal.setForegroundColor(p);
|
|
132
142
|
}
|
|
133
|
-
if (
|
|
143
|
+
if (hasValue(runtime, object, "heightMultiplier")) {
|
|
134
144
|
auto propValue = object.getProperty(runtime, "heightMultiplier");
|
|
135
145
|
retVal.setHeight(propValue.asNumber());
|
|
136
146
|
retVal.setHeightOverride(true);
|
|
137
147
|
}
|
|
138
|
-
if (
|
|
148
|
+
if (hasValue(runtime, object, "halfLeading")) {
|
|
139
149
|
auto propValue = object.getProperty(runtime, "halfLeading");
|
|
140
150
|
retVal.setHalfLeading(propValue.getBool());
|
|
141
151
|
}
|
|
142
|
-
if (
|
|
152
|
+
if (hasValue(runtime, object, "letterSpacing")) {
|
|
143
153
|
auto propValue = object.getProperty(runtime, "letterSpacing");
|
|
144
154
|
retVal.setLetterSpacing(propValue.asNumber());
|
|
145
155
|
}
|
|
146
|
-
if (
|
|
156
|
+
if (hasValue(runtime, object, "wordSpacing")) {
|
|
147
157
|
auto propValue = object.getProperty(runtime, "wordSpacing");
|
|
148
158
|
retVal.setWordSpacing(propValue.asNumber());
|
|
149
159
|
}
|
|
150
|
-
if (
|
|
160
|
+
if (hasValue(runtime, object, "locale")) {
|
|
151
161
|
auto propValue = object.getProperty(runtime, "locale");
|
|
152
162
|
retVal.setLocale(SkString(propValue.asString(runtime).utf8(runtime)));
|
|
153
163
|
}
|
|
154
|
-
if (
|
|
164
|
+
if (hasValue(runtime, object, "shadows")) {
|
|
155
165
|
auto propValue = object.getProperty(runtime, "shadows")
|
|
156
166
|
.asObject(runtime)
|
|
157
167
|
.asArray(runtime);
|
|
@@ -159,24 +169,24 @@ public:
|
|
|
159
169
|
retVal.resetShadows();
|
|
160
170
|
for (size_t i = 0; i < size; ++i) {
|
|
161
171
|
auto element = propValue.getValueAtIndex(runtime, i).asObject(runtime);
|
|
162
|
-
auto color =
|
|
172
|
+
auto color = hasValue(runtime, element, "color")
|
|
163
173
|
? JsiSkColor::fromValue(
|
|
164
174
|
runtime, element.getProperty(runtime, "color"))
|
|
165
175
|
: SK_ColorBLACK;
|
|
166
176
|
SkPoint offset =
|
|
167
|
-
|
|
177
|
+
hasValue(runtime, element, "offset")
|
|
168
178
|
? *JsiSkPoint::fromValue(runtime,
|
|
169
179
|
element.getProperty(runtime, "offset"))
|
|
170
180
|
.get()
|
|
171
181
|
: SkPoint::Make(0, 0);
|
|
172
182
|
auto blurSigma =
|
|
173
|
-
|
|
183
|
+
hasValue(runtime, element, "blurRadius")
|
|
174
184
|
? element.getProperty(runtime, "blurRadius").asNumber()
|
|
175
185
|
: 0;
|
|
176
186
|
retVal.addShadow(para::TextShadow(color, offset, blurSigma));
|
|
177
187
|
}
|
|
178
188
|
}
|
|
179
|
-
if (
|
|
189
|
+
if (hasValue(runtime, object, "textBaseline")) {
|
|
180
190
|
auto propValue = object.getProperty(runtime, "textBaseline");
|
|
181
191
|
retVal.setTextBaseline(
|
|
182
192
|
static_cast<para::TextBaseline>(propValue.asNumber()));
|
|
@@ -51,6 +51,12 @@ RNSkManager::RNSkManager(
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
RNSkManager::~RNSkManager() {
|
|
54
|
+
#ifdef SK_GRAPHITE
|
|
55
|
+
// Drop all canvas registry entries: after a reload the JS side restarts its
|
|
56
|
+
// contextId counter, and stale entries would alias new canvases onto dead
|
|
57
|
+
// surfaces.
|
|
58
|
+
rnwgpu::SurfaceRegistry::getInstance().clear();
|
|
59
|
+
#endif
|
|
54
60
|
// Free up any references
|
|
55
61
|
_viewApi = nullptr;
|
|
56
62
|
_jsRuntime = nullptr;
|