Skip to main content

MultiThreadedDispatcher

Struct MultiThreadedDispatcher 

Source
pub(crate) struct MultiThreadedDispatcher {
Show 18 fields bucketer: Mutex<CommandBucketer>, clip_context: ClipContext, recorder: CommandRecorder<RecordedFill>, strip_storage: StripStorage, thread_pool: ThreadPool, allocation_group: AllocationGroup, batch_cost: f32, task_sender: Option<Sender<RenderTask>>, workers: Arc<ThreadLocal<RefCell<Worker>>>, recorded_command_receiver: Option<Receiver<RecordedCommandTask>>, alpha_storage: MaybePresent<Vec<Vec<u8>>>, task_idx: u32, num_threads: u16, strip_generator: StripGenerator, level: Level, flushed: bool, allocations: Allocations, layer_depth: usize,
}
Expand description

A dispatcher for multi-threaded rendering.

A small note for future contributors: Unfortunately, the logic of this dispatcher as well as the lifecycle of the different fields of the dispatcher can be a bit hard to grasp. The reason for this is that since we have to do a lot of communication across the thread boundary, we have to work with lots of Option and core::mem::take operations, to ensure that we are not needlessly cloning objects.

The below comments will hopefully help with understanding the overall structure and lifecycles a bit better.

Fields§

§bucketer: Mutex<CommandBucketer>§clip_context: ClipContext§recorder: CommandRecorder<RecordedFill>§strip_storage: StripStorage§thread_pool: ThreadPool

The thread pool that is used for dispatching tasks.

§allocation_group: AllocationGroup§batch_cost: f32

The cost of the current batch.

§task_sender: Option<Sender<RenderTask>>

The sender used to dispatch new rendering tasks from the main thread.

This field will be set once we call the init method. This field will be set back to None when running flush to drop the value and thus indicate to receivers that no more rendering tasks will be dispatched from that point onward.

§workers: Arc<ThreadLocal<RefCell<Worker>>>

Contains one worker object for each thread.

The workers will be initialized once when building the multi-threaded dispatcher via MultiThreadedDispatcher::new.

§recorded_command_receiver: Option<Receiver<RecordedCommandTask>>

The receiver for commands generated by worker threads, used to record them on the main thread.

Similarly to task_sender, this value is set to None initially, and will only be set once we actually call the init method after registering a task.

§alpha_storage: MaybePresent<Vec<Vec<u8>>>

The storage for alpha values.

Similarly to the single-threaded dispatcher, we want to be able to reuse the allocation holding the alpha values across multiple runs of reset. However, we have the problem that during path rendering, each thread needs to have its own allocation. We also need to be able to move the allocation back and forth between the threads (during path rendering) and the main thread (during fine rasterization). Because of this, we wrap it in this MaybePresent struct.

During initialization, each thread will “take” the vector allocation out of its slot (the vector has a length of num_threads, so each thread has a slot belonging to itself) and will put it back to its slot after flushing. Then, during fine rasterization, we take all slots out of the MaybePresent object so that we can easily access each buffer when running the commands without having to go through the mutex. After fine rasterization, the slots are put back into the MaybePresent object.

§task_idx: u32

The task index that will be assigned to the next rendering task.

Since we are rendering the paths on different threads, we need to make sure that they come back in the right order. The task_idx is used to keep track of that order.

§num_threads: u16

The number of threads active in the thread pool.

§strip_generator: StripGenerator

The strip generator for the main thread, used for clip path rasterization.

§level: Level§flushed: bool§allocations: Allocations§layer_depth: usize

Implementations§

Source§

impl MultiThreadedDispatcher

Source

pub(crate) fn new( width: u16, height: u16, num_threads: u16, level: Level, ) -> Self

Source

fn rasterize_u8( &self, target: PixmapMut<'_>, scene_width: u16, scene_height: u16, settings: RasterizerSettings, encoded_paints: &[EncodedPaint], image_resolver: &dyn ImageResolver, )

Source

fn init(&mut self)

Source

fn register_task(&mut self, task: RenderTaskType)

Source

fn flush_tasks(&mut self)

Source

fn bump_task_idx(&mut self) -> u32

Source

fn send_pending_tasks(&mut self)

Source

fn append_strips(&mut self, strips: &[Strip]) -> Range<usize>

Source

fn record_finished_commands(&mut self, abort_empty: bool)

Source

fn rasterize_with<S: Simd, F: FineKernel<S>>( &self, simd: S, target: PixmapMut<'_>, scene_width: u16, scene_height: u16, settings: RasterizerSettings, encoded_paints: &[EncodedPaint], image_resolver: &dyn ImageResolver, )

Trait Implementations§

Source§

impl Debug for MultiThreadedDispatcher

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Dispatcher for MultiThreadedDispatcher

Source§

fn has_layers(&self) -> bool

Source§

fn fill_path( &mut self, path: &BezPath, fill_rule: Fill, transform: Affine, paint: Paint, blend_mode: BlendMode, aliasing_threshold: Option<u8>, mask: Option<Mask>, )

Source§

fn stroke_path( &mut self, path: &BezPath, stroke: &Stroke, transform: Affine, paint: Paint, blend_mode: BlendMode, aliasing_threshold: Option<u8>, mask: Option<Mask>, )

Source§

fn fill_rect_fast( &mut self, rect: &Rect, paint: Paint, blend_mode: BlendMode, mask: Option<Mask>, )

Fill a pixel-aligned rectangle with the current paint.
Source§

fn push_layer( &mut self, clip_path: Option<&BezPath>, fill_rule: Fill, clip_transform: Affine, blend_mode: BlendMode, opacity: f32, aliasing_threshold: Option<u8>, mask: Option<Mask>, filter_data: Option<FilterData>, )

Source§

fn pop_layer(&mut self)

Source§

fn reset(&mut self, width: u16, height: u16)

Source§

fn flush(&mut self)

Source§

fn rasterize( &self, target: PixmapMut<'_>, scene_width: u16, scene_height: u16, settings: RasterizerSettings, encoded_paints: &[EncodedPaint], image_resolver: &dyn ImageResolver, )

Source§

fn push_clip_path( &mut self, path: &BezPath, fill_rule: Fill, transform: Affine, aliasing_threshold: Option<u8>, )

Source§

fn pop_clip_path(&mut self)

Source§

fn is_multi_threaded(&self) -> bool

Source§

impl Drop for MultiThreadedDispatcher

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.