Introduce explicit image::allocate API
This commit is contained in:
parent
6fa54f7f6b
commit
23039e758e
15 changed files with 355 additions and 51 deletions
|
|
@ -4,8 +4,10 @@ pub use bytes::Bytes;
|
|||
use crate::{Radians, Rectangle, Size};
|
||||
|
||||
use rustc_hash::FxHasher;
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
/// A raster image that can be drawn.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
|
@ -227,6 +229,56 @@ pub enum FilterMethod {
|
|||
Nearest,
|
||||
}
|
||||
|
||||
/// A memory allocation of a [`Handle`], often in GPU memory.
|
||||
///
|
||||
/// Renderers tend to decode and upload image data concurrently to
|
||||
/// avoid blocking the user interface. This means that when you use a
|
||||
/// [`Handle`] in a widget, there may be a slight frame delay until it
|
||||
/// is finally visible. If you are animating images, this can cause
|
||||
/// undesirable flicker.
|
||||
///
|
||||
/// When you obtain an [`Allocation`] explicitly, you get the guarantee
|
||||
/// that using a [`Handle`] will draw the corresponding [`Image`]
|
||||
/// immediately in the next frame.
|
||||
///
|
||||
/// This guarantee is valid as long as you hold an [`Allocation`].
|
||||
/// Only when you drop all its clones, the renderer may choose to free
|
||||
/// the memory of the [`Handle`]. Be careful!
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Allocation(Arc<Memory>);
|
||||
|
||||
/// Some memory taken by an [`Allocation`].
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Memory(Handle);
|
||||
|
||||
impl Allocation {
|
||||
/// Returns a weak reference to the [`Memory`] of the [`Allocation`].
|
||||
pub fn downgrade(&self) -> Weak<Memory> {
|
||||
Arc::downgrade(&self.0)
|
||||
}
|
||||
|
||||
/// Upgrades a [`Weak`] memory reference to an [`Allocation`].
|
||||
pub fn upgrade(weak: &Weak<Memory>) -> Option<Allocation> {
|
||||
Weak::upgrade(weak).map(Allocation)
|
||||
}
|
||||
|
||||
/// Returns the [`Handle`] of this [`Allocation`].
|
||||
pub fn handle(&self) -> &Handle {
|
||||
&self.0.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new [`Allocation`] for the given handle.
|
||||
///
|
||||
/// This should only be used internally by renderer implementations.
|
||||
///
|
||||
/// # Safety
|
||||
/// Must only be created once the [`Handle`] is allocated in memory.
|
||||
#[allow(unsafe_code)]
|
||||
pub unsafe fn allocate(handle: &Handle) -> Allocation {
|
||||
Allocation(Arc::new(Memory(handle.clone())))
|
||||
}
|
||||
|
||||
/// A [`Renderer`] that can render raster graphics.
|
||||
///
|
||||
/// [renderer]: crate::renderer
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#[cfg(debug_assertions)]
|
||||
mod null;
|
||||
|
||||
use crate::image;
|
||||
use crate::{
|
||||
Background, Border, Color, Font, Pixels, Rectangle, Shadow, Size,
|
||||
Transformation, Vector,
|
||||
|
|
@ -62,6 +63,13 @@ pub trait Renderer {
|
|||
|
||||
/// Resets the [`Renderer`] to start drawing in the `new_bounds` from scratch.
|
||||
fn reset(&mut self, new_bounds: Rectangle);
|
||||
|
||||
/// Creates an [`image::Allocation`] for the given [`image::Handle`] and calls the given callback with it.
|
||||
fn allocate_image(
|
||||
&mut self,
|
||||
handle: &image::Handle,
|
||||
callback: impl FnOnce(image::Allocation) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
/// A polygon with four sides.
|
||||
|
|
|
|||
|
|
@ -24,6 +24,15 @@ impl Renderer for () {
|
|||
_background: impl Into<Background>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn allocate_image(
|
||||
&mut self,
|
||||
handle: &image::Handle,
|
||||
callback: impl FnOnce(image::Allocation) + Send + 'static,
|
||||
) {
|
||||
#[allow(unsafe_code)]
|
||||
callback(unsafe { image::allocate(handle) });
|
||||
}
|
||||
}
|
||||
|
||||
impl text::Renderer for () {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue