Skip to content

Commit 7aab160

Browse files
committed
chore(canvas): 2.0.2
1 parent 0ee270d commit 7aab160

118 files changed

Lines changed: 11053 additions & 11195 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.toml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ opt-level = "z"
5858
[workspace.dependencies.wgt]
5959
package = "wgpu-types"
6060
git = "https://github.com/triniwiz/wgpu"
61-
rev = "4fb84f5a325d73d21416a2244d1cc062925350ef"
61+
rev = "7e0f39f"
6262

6363

6464

@@ -77,8 +77,18 @@ canvas-c = { path = "./crates/canvas-c" }
7777
skia-safe = { version = "0.93.1", features = ["textlayout"] }
7878
itertools = "0.14.0"
7979
ustr = "1.1.0"
80-
wgpu-core = { git = "https://github.com/triniwiz/wgpu", rev = "4fb84f5a325d73d21416a2244d1cc062925350ef", features = ["wgsl"] }
81-
wgpu-hal = { git = "https://github.com/triniwiz/wgpu", rev = "4fb84f5a325d73d21416a2244d1cc062925350ef" }
80+
wgpu-core = { git = "https://github.com/triniwiz/wgpu", rev = "7e0f39f", features = ["wgsl"] }
81+
wgpu-hal = { git = "https://github.com/triniwiz/wgpu", rev = "7e0f39f" }
8282
ureq = "2.10.1"
8383
jni = "0.21.1"
84-
regex-lite = "0.1.9"
84+
regex-lite = "0.1.9"
85+
objc2 = { version = "0.6.3", default-features = false }
86+
objc2-core-foundation = { version = "0.3.2", default-features = false }
87+
objc2-metal = { version = "0.3.2", default-features = false, features = ["MTLCommandBuffer", "MTLCommandQueue", "MTLDrawable", "MTLPixelFormat", "MTLTexture", "MTLDevice", "objc2-core-foundation"] }
88+
objc2-foundation = { version = "0.3.2", features = ["NSGeometry", "NSData", "NSAutoreleasePool", "NSDictionary", "NSObject", "NSValue", "NSString"] }
89+
objc2-quartz-core = { version = "0.3.2", default-features = false, features = ["std",
90+
"objc2-core-foundation",
91+
"CALayer",
92+
"CAMetalLayer",
93+
"objc2-metal"] }
94+
core-foundation = "0.10.1"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
- [@nativescript/audio-context](packages/audio-context/README.md)
12
- [@nativescript/canvas](packages/canvas/README.md)
23
- [@nativescript/canvas-babylon](packages/canvas-babylon/README.md)
34
- [@nativescript/canvas-chartjs](packages/canvas-chartjs/README.md)

crates/canvas-2d/Cargo.toml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ version = "2.0.0"
44
edition = "2021"
55

66
[features]
7-
metal = ["skia-safe/metal", "canvas-core/metal"]
8-
gl = ["skia-safe/gl"]
7+
metal = ["skia-safe/metal", "canvas-core/mtl"]
8+
gl = ["skia-safe/gl", "canvas-core/gl"]
99
vulkan = ["skia-safe/vulkan", "canvas-core/vulkan"]
1010
default = ["gl"]
1111

1212
[dependencies]
13-
canvas-core = { workspace = true, features = ["2d"] }
13+
canvas-core = { workspace = true, features = ["2d", "gl"] }
1414
parking_lot.workspace = true
1515
ustr.workspace = true
1616
base64 = "0.22.1"
@@ -25,6 +25,10 @@ ash = { version = "0.38.0", optional = true, features = ["libloading"] }
2525
raw-window-handle.workspace = true
2626
bitflags = "2.6.0"
2727
regex-lite = { workspace = true }
28+
2829
[target.'cfg(any(target_os = "ios", target_os="macos"))'.dependencies]
2930
foreign-types-shared = "0.3.1"
30-
objc2-foundation = { version = "0.2.2", features = ["NSAutoreleasePool"] }
31+
objc2 = {workspace = true}
32+
objc2-foundation = { workspace = true }
33+
objc2-metal = { workspace = true }
34+
objc2-quartz-core = { workspace = true }

crates/canvas-2d/src/context/surface_metal.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use crate::context::paths::path::Path;
22
use crate::context::text_styles::text_direction::TextDirection;
33
use crate::context::{Context, State, SurfaceData, SurfaceEngine, SurfaceState};
4+
use canvas_core::context_attributes::ColorSpace;
45
use canvas_core::gpu::metal::MetalContext;
56
use foreign_types_shared::ForeignTypeRef;
7+
use objc2::rc::Retained;
8+
use objc2_metal::MTLTexture;
9+
use objc2_quartz_core::CAMetalDrawable;
610
use skia_safe::gpu::mtl::TextureInfo;
711
use skia_safe::{gpu, Color, ColorType};
812
use std::os::raw::c_void;
9-
use canvas_core::context_attributes::ColorSpace;
1013

1114
#[cfg(feature = "metal")]
1215
impl Context {
@@ -35,19 +38,19 @@ impl Context {
3538
None,
3639
) {
3740
surface.canvas().draw_color(Color::RED, None);
38-
41+
3942
// surface
4043
// .canvas()
4144
// .draw_image(snapshot, skia_safe::Point::new(0.0, 0.0), None);
42-
context.flush_surface(&mut surface);
43-
context.flush_submit_and_sync_cpu();
45+
context.flush_surface(&mut surface);
46+
context.flush_submit_and_sync_cpu();
4447

4548
return true;
4649
}
4750
}
4851
false
4952
}
50-
53+
5154
pub fn new_metal(
5255
view: *mut c_void,
5356
density: f32,
@@ -56,7 +59,7 @@ impl Context {
5659
font_color: i32,
5760
ppi: f32,
5861
direction: TextDirection,
59-
color_space: ColorSpace
62+
color_space: ColorSpace,
6063
) -> Self {
6164
let mtl_context = MetalContext::new(view);
6265
let backend = unsafe {
@@ -71,7 +74,8 @@ impl Context {
7174
let mut context = gpu::direct_contexts::make_metal(&backend, None).unwrap();
7275

7376
let drawable = mtl_context.drawable().unwrap();
74-
let info = unsafe { TextureInfo::new(drawable.texture().as_ptr() as gpu::mtl::Handle) };
77+
let info =
78+
unsafe { TextureInfo::new(Retained::as_ptr(&drawable.texture()) as gpu::mtl::Handle) };
7579
let bt = unsafe {
7680
gpu::backend_textures::make_mtl(
7781
(width as i32, height as i32),
@@ -103,7 +107,7 @@ impl Context {
103107
engine: SurfaceEngine::Metal,
104108
state: Default::default(),
105109
is_opaque: !alpha,
106-
color_space
110+
color_space,
107111
},
108112
surface,
109113
surface_state: Default::default(),
@@ -134,7 +138,7 @@ impl Context {
134138
font_color: i32,
135139
ppi: f32,
136140
direction: TextDirection,
137-
color_space: ColorSpace
141+
color_space: ColorSpace,
138142
) -> Self {
139143
let mut mtl_context = unsafe { MetalContext::new_device_queue(view, device, queue) };
140144
let backend = unsafe {
@@ -144,7 +148,7 @@ impl Context {
144148

145149
let mut context = gpu::direct_contexts::make_metal(&backend, None).unwrap();
146150
let drawable = mtl_context.current_drawable().unwrap();
147-
let info = unsafe { TextureInfo::new(drawable.texture().as_ptr() as gpu::mtl::Handle) };
151+
let info = unsafe { TextureInfo::new(Retained::as_ptr(&drawable.texture()) as gpu::mtl::Handle) };
148152
let bt = unsafe {
149153
gpu::backend_textures::make_mtl(
150154
(width as i32, height as i32),
@@ -176,7 +180,7 @@ impl Context {
176180
engine: SurfaceEngine::Metal,
177181
state: Default::default(),
178182
is_opaque: !alpha,
179-
color_space
183+
color_space,
180184
},
181185
surface,
182186
surface_state: Default::default(),
@@ -206,7 +210,7 @@ impl Context {
206210
font_color: i32,
207211
ppi: f32,
208212
direction: TextDirection,
209-
color_space: ColorSpace
213+
color_space: ColorSpace,
210214
) -> Self {
211215
let mtl_context = MetalContext::new_offscreen(width, height);
212216
let backend = unsafe {
@@ -221,7 +225,7 @@ impl Context {
221225
let mut context = gpu::direct_contexts::make_metal(&backend, None).unwrap();
222226

223227
let drawable = mtl_context.drawable().unwrap();
224-
let info = unsafe { TextureInfo::new(drawable.texture().as_ptr() as gpu::mtl::Handle) };
228+
let info = unsafe { TextureInfo::new(Retained::as_ptr(&drawable.texture()) as gpu::mtl::Handle) };
225229
let bt = unsafe {
226230
gpu::backend_textures::make_mtl(
227231
(width as i32, height as i32),
@@ -253,7 +257,7 @@ impl Context {
253257
engine: SurfaceEngine::Metal,
254258
state: Default::default(),
255259
is_opaque: !alpha,
256-
color_space
260+
color_space,
257261
},
258262
surface,
259263
surface_state: Default::default(),
@@ -293,7 +297,7 @@ impl Context {
293297
if let Some(drawable) = context.next_drawable() {
294298
info = unsafe {
295299
Some(TextureInfo::new(
296-
drawable.texture().as_ptr() as gpu::mtl::Handle
300+
Retained::as_ptr(&drawable.texture()) as gpu::mtl::Handle
297301
))
298302
};
299303
}
@@ -357,7 +361,7 @@ impl Context {
357361
let texture = drawable.texture();
358362
width = texture.width();
359363
height = texture.height();
360-
info = unsafe { Some(TextureInfo::new(texture.as_ptr() as gpu::mtl::Handle)) };
364+
info = unsafe { Some(TextureInfo::new(Retained::as_ptr(&drawable.texture()) as gpu::mtl::Handle)) };
361365
}
362366
}
363367

crates/canvas-c/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ image = { version = "0.25.5", optional = true }
3434
display-link = { version = "0.2.0" }
3535
wgpu-core = { workspace = true, features = ["wgsl", "metal"] }
3636
wgpu-hal = { workspace = true, features = ["metal"] }
37-
objc2-foundation = { version = "0.2.2", features = ["NSGeometry", "NSData", "NSAutoreleasePool"] }
38-
metal = { version = "0.30.0" }
37+
objc2-foundation = { workspace = true }
38+
objc2-metal = { workspace = true }
3939

4040
[target.'cfg(target_os="macos")'.dependencies]
4141
wgpu-core = { workspace = true, features = ["wgsl", "metal"] }
4242
wgpu-hal = { workspace = true, features = ["metal"] }
43-
metal = { version = "0.30.0" }
43+
objc2-metal = { workspace = true }
4444

4545
[target.'cfg(target_os="android")'.dependencies]
4646
ndk = { version = "0.7.0", features = ["bitmap"] }

crates/canvas-c/src/c2d/context.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ impl CanvasRenderingContext2D {
209209

210210
let mut flush = true;
211211

212-
// metal will execute the flush_and_render_to_surface in the draw call
212+
213213
#[cfg(feature = "metal")]
214214
{
215215
if self.engine == Engine::Metal {
@@ -311,7 +311,10 @@ pub extern "C" fn canvas_native_raf_release(value: *mut crate::Raf) {
311311
if value.is_null() {
312312
return;
313313
}
314-
let _ = unsafe { std::sync::Arc::decrement_strong_count(value) };
314+
canvas_native_raf_stop_and_clear(value, 100);
315+
unsafe {
316+
drop(Box::from_raw(value));
317+
}
315318
}
316319

317320
#[cfg(any(target_os = "android", target_os = "ios"))]
@@ -1343,8 +1346,7 @@ pub extern "C" fn canvas_native_context_set_fill_style(
13431346
context.context.set_fill_style(style.0.clone())
13441347
}
13451348

1346-
/// Move-semantics variant: takes ownership of the PaintStyle, avoiding clone.
1347-
/// The caller must NOT use or release the style pointer after this call.
1349+
13481350
#[no_mangle]
13491351
pub extern "C" fn canvas_native_context_set_fill_style_owned(
13501352
context: *mut CanvasRenderingContext2D,
@@ -1378,8 +1380,7 @@ pub extern "C" fn canvas_native_context_set_stroke_style(
13781380
context.context.set_stroke_style(style.0.clone())
13791381
}
13801382

1381-
/// Move-semantics variant: takes ownership of the PaintStyle, avoiding clone.
1382-
/// The caller must NOT use or release the style pointer after this call.
1383+
13831384
#[no_mangle]
13841385
pub extern "C" fn canvas_native_context_set_stroke_style_owned(
13851386
context: *mut CanvasRenderingContext2D,

crates/canvas-c/src/c2d/paint/gradient.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ pub extern "C" fn canvas_native_gradient_add_color_stop(
2323
}
2424
}
2525

26-
/// Add a color stop using pre-parsed RGBA values (0-255 each).
27-
/// Skips CSS color string parsing entirely.
2826
#[no_mangle]
2927
pub extern "C" fn canvas_native_gradient_add_color_stop_rgba(
3028
style: *mut PaintStyle,

crates/canvas-c/src/webgpu/enums.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ pub enum CanvasTextureViewDimension {
126126
}
127127

128128
impl CanvasTextureViewDimension {
129-
/// Get the texture dimension required of this texture view dimension.
130129
pub fn compatible_texture_dimension(self) -> CanvasTextureViewDimension {
131130
match self {
132131
Self::D1 => CanvasTextureViewDimension::D1,

crates/canvas-c/src/webgpu/error.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,15 @@ pub(crate) fn handle_error_fatal(
7373
cause: impl Error + Send + Sync + 'static,
7474
operation: &'static str,
7575
) {
76-
// panic!(
77-
// "Error in {operation}: {f}",
78-
// f = format_error(context, &cause)
79-
// );
80-
81-
// log::error!("Error in {operation}: {f}",
82-
// f = error);
83-
76+
// Print a detailed validation error tree to help debugging.
77+
let formatted = format_error(_global, &cause);
8478
let error = cause;
8579

8680
#[cfg(target_os = "android")]
87-
log::error!("Error in {operation}: {error}");
81+
log::error!("Error in {operation}: {error}\n{formatted}");
8882

8983
#[cfg(not(target_os = "android"))]
90-
println!("Error in {operation}: {error}");
91-
92-
93-
94-
// log::error!("Error in {operation}: {f}",
95-
// f = format_error(global, &cause))
84+
println!("Error in {operation}: {error}\n{formatted}");
9685
}
9786

9887
#[repr(C)]

crates/canvas-c/src/webgpu/gpu.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ impl Into<wgt::PowerPreference> for CanvasGPUPowerPreference {
2323
}
2424
}
2525

26-
/// - `Core` (default) — full WebGPU feature set.
27-
/// - `Compatibility` — relaxed capability set; on Android this selects the GLES
28-
/// backend which provides the widest device coverage (mirrors what a browser
29-
/// would do on devices that lack Vulkan 1.1+).
3026
#[repr(C)]
3127
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
3228
pub enum CanvasGPUFeatureLevel {
@@ -49,7 +45,6 @@ impl From<CanvasGPUFeatureLevel> for wgt::FeatureLevel {
4945
pub struct CanvasGPURequestAdapterOptions {
5046
pub power_preference: CanvasGPUPowerPreference,
5147
pub force_fallback_adapter: bool,
52-
/// Requested feature level. Defaults to `Core`.
5348
pub feature_level: CanvasGPUFeatureLevel,
5449
}
5550

@@ -181,38 +176,25 @@ pub unsafe extern "C" fn canvas_native_webgpu_request_adapter(
181176

182177
#[cfg(target_os = "android")]
183178
{
184-
// `Compatibility` feature level maps naturally to the GLES backend:
185-
// it provides the widest device coverage and matches the relaxed
186-
// capability set implied by the spec's compatibility level.
187179
if options.feature_level == CanvasGPUFeatureLevel::Compatibility {
188180
global.request_adapter(&opts, wgt::Backends::GL, None)
189181
} else {
190-
// Core: try Vulkan first, preferring hardware over software.
191182
let vulkan_adapter = global.request_adapter(&opts, wgt::Backends::VULKAN, None);
192183

193184
let is_hardware_vulkan = vulkan_adapter.as_ref().map_or(false, |id| {
194-
// device_type == Cpu means SwiftShader or similar software renderer.
195185
global.adapter_get_info(*id).device_type != wgt::DeviceType::Cpu
196186
});
197187

198188
if is_hardware_vulkan {
199-
// Hardware Vulkan — best case.
200189
vulkan_adapter
201190
} else {
202-
// No hardware Vulkan. Try GLES next (widest device support).
203191
let gl_adapter = global.request_adapter(&opts, wgt::Backends::GL, None);
204192
if gl_adapter.is_ok() {
205-
// GLES is available — prefer it over software Vulkan and drop
206-
// the software adapter to avoid a resource leak.
207193
if let Ok(id) = vulkan_adapter {
208194
global.adapter_drop(id);
209195
}
210196
gl_adapter
211197
} else {
212-
// GLES unavailable (e.g. Android emulator without host GPU).
213-
// Fall back to the software Vulkan adapter so the caller gets
214-
// *something* rather than null — the JS layer can decide whether
215-
// to proceed or retry with featureLevel:'compatibility'.
216198
vulkan_adapter
217199
}
218200
}
@@ -227,10 +209,6 @@ pub unsafe extern "C" fn canvas_native_webgpu_request_adapter(
227209

228210
let adapter = adapter_id.map(|adapter_id| {
229211
let mut features = build_features(global.adapter_features(adapter_id));
230-
// "core-features-and-limits" is a WebGPU spec marker that signals the device
231-
// was created with Core feature level (all mandatory WebGPU features/limits).
232-
// Compatibility mode explicitly opts out of this guarantee, so the feature
233-
// must be absent when featureLevel == Compatibility.
234212
if options.feature_level != CanvasGPUFeatureLevel::Compatibility {
235213
features.push("core-features-and-limits");
236214
}

0 commit comments

Comments
 (0)