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: ThreadPoolThe thread pool that is used for dispatching tasks.
allocation_group: AllocationGroup§batch_cost: f32The 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: u32The 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: u16The number of threads active in the thread pool.
strip_generator: StripGeneratorThe strip generator for the main thread, used for clip path rasterization.
level: Level§flushed: bool§allocations: Allocations§layer_depth: usizeImplementations§
Source§impl MultiThreadedDispatcher
impl MultiThreadedDispatcher
pub(crate) fn new( width: u16, height: u16, num_threads: u16, level: Level, ) -> Self
fn rasterize_u8( &self, target: PixmapMut<'_>, scene_width: u16, scene_height: u16, settings: RasterizerSettings, encoded_paints: &[EncodedPaint], image_resolver: &dyn ImageResolver, )
fn init(&mut self)
fn register_task(&mut self, task: RenderTaskType)
fn flush_tasks(&mut self)
fn bump_task_idx(&mut self) -> u32
fn send_pending_tasks(&mut self)
fn append_strips(&mut self, strips: &[Strip]) -> Range<usize>
fn record_finished_commands(&mut self, abort_empty: bool)
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
impl Debug for MultiThreadedDispatcher
Source§impl Dispatcher for MultiThreadedDispatcher
impl Dispatcher for MultiThreadedDispatcher
fn has_layers(&self) -> bool
fn fill_path( &mut self, path: &BezPath, fill_rule: Fill, transform: Affine, paint: Paint, blend_mode: BlendMode, aliasing_threshold: Option<u8>, mask: Option<Mask>, )
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>,
)
fn fill_rect_fast( &mut self, rect: &Rect, paint: Paint, blend_mode: BlendMode, mask: Option<Mask>, )
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>, )
fn pop_layer(&mut self)
fn reset(&mut self, width: u16, height: u16)
fn flush(&mut self)
fn rasterize( &self, target: PixmapMut<'_>, scene_width: u16, scene_height: u16, settings: RasterizerSettings, encoded_paints: &[EncodedPaint], image_resolver: &dyn ImageResolver, )
fn push_clip_path( &mut self, path: &BezPath, fill_rule: Fill, transform: Affine, aliasing_threshold: Option<u8>, )
fn pop_clip_path(&mut self)
fn is_multi_threaded(&self) -> bool
Source§impl Drop for MultiThreadedDispatcher
impl Drop for MultiThreadedDispatcher
Auto Trait Implementations§
impl !Freeze for MultiThreadedDispatcher
impl !RefUnwindSafe for MultiThreadedDispatcher
impl Send for MultiThreadedDispatcher
impl Sync for MultiThreadedDispatcher
impl Unpin for MultiThreadedDispatcher
impl UnsafeUnpin for MultiThreadedDispatcher
impl !UnwindSafe for MultiThreadedDispatcher
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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