Skip to content

Commit 867c591

Browse files
committed
Add Renderer::tick for polling concurrent work
1 parent dca3339 commit 867c591

File tree

11 files changed

+92
-42
lines changed

11 files changed

+92
-42
lines changed

core/src/renderer.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ pub trait Renderer {
6161
/// Fills a [`Quad`] with the provided [`Background`].
6262
fn fill_quad(&mut self, quad: Quad, background: impl Into<Background>);
6363

64-
/// Resets the [`Renderer`] to start drawing in the `new_bounds` from scratch.
65-
fn reset(&mut self, new_bounds: Rectangle);
66-
6764
/// Creates an [`image::Allocation`] for the given [`image::Handle`] and calls the given callback with it.
6865
fn allocate_image(
6966
&self,
@@ -72,6 +69,14 @@ pub trait Renderer {
7269
+ Send
7370
+ 'static,
7471
);
72+
73+
/// Resets the [`Renderer`] to start drawing in the `new_bounds` from scratch.
74+
fn reset(&mut self, new_bounds: Rectangle);
75+
76+
/// Polls any concurrent computations that may be pending in the [`Renderer`].
77+
///
78+
/// By default, it does nothing.
79+
fn tick(&mut self) {}
7580
}
7681

7782
/// A polygon with four sides.

core/src/renderer/null.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ impl Renderer for () {
1616

1717
fn end_transformation(&mut self) {}
1818

19-
fn reset(&mut self, _new_bounds: Rectangle) {}
20-
2119
fn fill_quad(
2220
&mut self,
2321
_quad: renderer::Quad,
@@ -35,6 +33,8 @@ impl Renderer for () {
3533
#[allow(unsafe_code)]
3634
callback(Ok(unsafe { image::allocate(handle, Size::new(100, 100)) }));
3735
}
36+
37+
fn reset(&mut self, _new_bounds: Rectangle) {}
3838
}
3939

4040
impl text::Renderer for () {

graphics/src/shell.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@ impl Shell {
1616
struct Headless;
1717

1818
impl Notifier for Headless {
19+
fn tick(&self) {}
1920
fn request_redraw(&self) {}
20-
2121
fn invalidate_layout(&self) {}
2222
}
2323

2424
Self::new(Headless)
2525
}
2626

27+
/// Requests for [`Renderer::tick`](crate::core::Renderer::tick) to
28+
/// be called by the [`Shell`].
29+
pub fn tick(&self) {
30+
self.0.tick();
31+
}
32+
2733
/// Requests for all windows of the [`Shell`] to be redrawn.
2834
pub fn request_redraw(&self) {
2935
self.0.request_redraw();
@@ -37,6 +43,10 @@ impl Shell {
3743

3844
/// A type that can notify a shell of certain events.
3945
pub trait Notifier: Send + Sync + 'static {
46+
/// Requests for [`Renderer::tick`](crate::core::Renderer::tick) to
47+
/// be called by the [`Shell`].
48+
fn tick(&self);
49+
4050
/// Requests for all windows of the [`Shell`] to be redrawn.
4151
fn request_redraw(&self);
4252

renderer/src/fallback.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ where
4646
delegate!(self, renderer, renderer.fill_quad(quad, background.into()));
4747
}
4848

49-
fn reset(&mut self, new_bounds: Rectangle) {
50-
delegate!(self, renderer, renderer.reset(new_bounds));
51-
}
52-
5349
fn start_layer(&mut self, bounds: Rectangle) {
5450
delegate!(self, renderer, renderer.start_layer(bounds));
5551
}
@@ -79,6 +75,14 @@ where
7975
) {
8076
delegate!(self, renderer, renderer.allocate_image(handle, callback));
8177
}
78+
79+
fn tick(&mut self) {
80+
delegate!(self, renderer, renderer.tick());
81+
}
82+
83+
fn reset(&mut self, new_bounds: Rectangle) {
84+
delegate!(self, renderer, renderer.reset(new_bounds));
85+
}
8286
}
8387

8488
impl<A, B> core::text::Renderer for Renderer<A, B>

runtime/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,12 @@ pub enum Action<T> {
5656
/// Run a system action.
5757
System(system::Action),
5858

59-
/// An image action.
59+
/// Run an image action.
6060
Image(image::Action),
6161

62+
/// Poll any resources that may have pending computations.
63+
Tick,
64+
6265
/// Recreate all user interfaces and redraw all windows.
6366
Reload,
6467

@@ -86,6 +89,7 @@ impl<T> Action<T> {
8689
Action::Window(action) => Err(Action::Window(action)),
8790
Action::System(action) => Err(Action::System(action)),
8891
Action::Image(action) => Err(Action::Image(action)),
92+
Action::Tick => Err(Action::Tick),
8993
Action::Reload => Err(Action::Reload),
9094
Action::Exit => Err(Action::Exit),
9195
}
@@ -111,6 +115,7 @@ where
111115
Action::Window(_) => write!(f, "Action::Window"),
112116
Action::System(action) => write!(f, "Action::System({action:?})"),
113117
Action::Image(_) => write!(f, "Action::Image"),
118+
Action::Tick => write!(f, "Action::Tick"),
114119
Action::Reload => write!(f, "Action::Reload"),
115120
Action::Exit => write!(f, "Action::Exit"),
116121
}

test/src/emulator.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ impl<P: Program + 'static> Emulator<P> {
261261
// TODO
262262
dbg!(action);
263263
}
264+
iced_runtime::Action::Tick => {
265+
// TODO
266+
}
264267
runtime::Action::Exit => {
265268
// TODO
266269
}

tiny_skia/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,6 @@ impl core::Renderer for Renderer {
225225
layer.draw_quad(quad, background.into(), transformation);
226226
}
227227

228-
fn reset(&mut self, new_bounds: Rectangle) {
229-
self.layers.reset(new_bounds);
230-
}
231-
232228
fn allocate_image(
233229
&self,
234230
_handle: &core::image::Handle,
@@ -244,6 +240,10 @@ impl core::Renderer for Renderer {
244240
#[cfg(not(feature = "image"))]
245241
callback(Err(core::image::Error::Unsupported))
246242
}
243+
244+
fn reset(&mut self, new_bounds: Rectangle) {
245+
self.layers.reset(new_bounds);
246+
}
247247
}
248248

249249
impl core::text::Renderer for Renderer {

wgpu/src/image/cache.rs

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl Cache {
8787
let _ = self.raster.pending.insert(handle.id(), vec![callback]);
8888

8989
#[cfg(not(target_arch = "wasm32"))]
90-
self.worker.load(handle);
90+
self.worker.load(handle, true);
9191
}
9292

9393
#[cfg(feature = "image")]
@@ -307,7 +307,7 @@ impl Cache {
307307
}
308308

309309
#[cfg(feature = "image")]
310-
fn receive(&mut self) {
310+
pub fn receive(&mut self) {
311311
#[cfg(not(target_arch = "wasm32"))]
312312
while let Ok(work) = self.worker.try_recv() {
313313
use crate::image::raster::Memory;
@@ -401,7 +401,7 @@ fn load_image<'a>(
401401
let _ = pending.insert(handle.id(), Vec::from_iter(callback));
402402

403403
#[cfg(not(target_arch = "wasm32"))]
404-
worker.load(handle);
404+
worker.load(handle, false);
405405
}
406406
}
407407

@@ -460,8 +460,11 @@ mod worker {
460460
}
461461
}
462462

463-
pub fn load(&self, handle: &image::Handle) {
464-
let _ = self.jobs.send(Job::Load(handle.clone()));
463+
pub fn load(&self, handle: &image::Handle, is_allocation: bool) {
464+
let _ = self.jobs.send(Job::Load {
465+
handle: handle.clone(),
466+
is_allocation,
467+
});
465468
}
466469

467470
pub fn upload(&self, handle: &image::Handle, image: raster::Image) {
@@ -502,7 +505,10 @@ mod worker {
502505

503506
#[derive(Debug)]
504507
enum Job {
505-
Load(image::Handle),
508+
Load {
509+
handle: image::Handle,
510+
is_allocation: bool,
511+
},
506512
Upload {
507513
handle: image::Handle,
508514
rgba: image::Bytes,
@@ -537,22 +543,26 @@ mod worker {
537543
};
538544

539545
match job {
540-
Job::Load(handle) => {
541-
match crate::graphics::image::load(&handle) {
542-
Ok(image) => self.upload(
543-
handle,
544-
image.width(),
545-
image.height(),
546-
image.into_raw(),
547-
Shell::invalidate_layout,
548-
),
549-
Err(error) => {
550-
let _ = self
551-
.output
552-
.send(Work::Error { handle, error });
553-
}
546+
Job::Load {
547+
handle,
548+
is_allocation,
549+
} => match crate::graphics::image::load(&handle) {
550+
Ok(image) => self.upload(
551+
handle,
552+
image.width(),
553+
image.height(),
554+
image.into_raw(),
555+
if is_allocation {
556+
Shell::tick
557+
} else {
558+
Shell::invalidate_layout
559+
},
560+
),
561+
Err(error) => {
562+
let _ =
563+
self.output.send(Work::Error { handle, error });
554564
}
555-
}
565+
},
556566
Job::Upload {
557567
handle,
558568
rgba,

wgpu/src/lib.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -695,10 +695,6 @@ impl core::Renderer for Renderer {
695695
layer.draw_quad(quad, background.into(), transformation);
696696
}
697697

698-
fn reset(&mut self, new_bounds: Rectangle) {
699-
self.layers.reset(new_bounds);
700-
}
701-
702698
fn allocate_image(
703699
&self,
704700
_handle: &core::image::Handle,
@@ -711,6 +707,15 @@ impl core::Renderer for Renderer {
711707
.borrow_mut()
712708
.allocate_image(_handle, _callback);
713709
}
710+
711+
fn tick(&mut self) {
712+
#[cfg(feature = "image")]
713+
self.image_cache.get_mut().receive();
714+
}
715+
716+
fn reset(&mut self, new_bounds: Rectangle) {
717+
self.layers.reset(new_bounds);
718+
}
714719
}
715720

716721
impl core::text::Renderer for Renderer {

winit/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,6 +1348,7 @@ fn run_action<'a, P, C>(
13481348
C: Compositor<Renderer = P::Renderer> + 'static,
13491349
P::Theme: theme::Base,
13501350
{
1351+
use crate::core::Renderer as _;
13511352
use crate::runtime::clipboard;
13521353
use crate::runtime::window;
13531354

@@ -1732,8 +1733,6 @@ fn run_action<'a, P, C>(
17321733
}
17331734
Action::Image(action) => match action {
17341735
image::Action::Allocate(handle, sender) => {
1735-
use core::Renderer as _;
1736-
17371736
// TODO: Shared image cache in compositor
17381737
if let Some((_id, window)) = window_manager.iter_mut().next() {
17391738
window.renderer.allocate_image(
@@ -1753,6 +1752,11 @@ fn run_action<'a, P, C>(
17531752
let _ = channel.send(Ok(()));
17541753
}
17551754
}
1755+
Action::Tick => {
1756+
for (_id, window) in window_manager.iter_mut() {
1757+
window.renderer.tick();
1758+
}
1759+
}
17561760
Action::Reload => {
17571761
for (id, window) in window_manager.iter_mut() {
17581762
let Some(ui) = interfaces.remove(&id) else {

0 commit comments

Comments
 (0)