Skip to content

Commit

Permalink
feat: refactor rendering functions and structs
Browse files Browse the repository at this point in the history
- add new structs `drawablecontext`, `rendercontentparams`, `renderdrawableparams`
- make changes to the `draw_content` and `draw_mask` functions
- update the `drawcontext` struct
- modify the `renderer` struct and its methods
  • Loading branch information
falcucci committed Sep 17, 2024
1 parent 366be8f commit c26c55f
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 78 deletions.
63 changes: 43 additions & 20 deletions src/drawable_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,25 @@ pub(crate) struct DrawablePipeline {
render_mask_pipeline: Option<RenderPipeline>,
}

pub(crate) struct DrawableContext<'a> {
pub queue: &'a Queue,
pub universal_bind_group: &'a BindGroup,
}

pub(crate) struct RenderContentParams<'a> {
pub constants: ShaderConstants,
pub resources: &'a Resources,
pub clip: Option<Rect<u32>>,
pub batch: &'a PrimitiveBatch,
}

pub(crate) struct RenderDrawableParams<'a> {
pub constants: ShaderConstants,
pub resources: &'a Resources,
pub clip: Option<Rect<u32>>,
pub batch: &'a PrimitiveBatch,
}

impl DrawablePipeline {
pub fn new<T: Drawable + 'static>(Renderer { device, .. }: &Renderer, drawable: T) -> Self {
let drawable = Box::new(drawable);
Expand Down Expand Up @@ -184,51 +203,55 @@ impl DrawablePipeline {

pub fn draw_content<'b, 'a: 'b>(
&'a mut self,
queue: &Queue,
draw_context: &DrawableContext,
render_pass: &mut RenderPass<'b>,
constants: ShaderConstants,
universal_bind_group: &'a BindGroup,
resources: &Resources,
clip: Option<Rect<u32>>,
batch: &PrimitiveBatch,
render_params: &RenderContentParams<'a>,
) {
render_pass.set_pipeline(self.render_content_pipeline.as_ref().unwrap());

render_pass.set_push_constants(
ShaderStages::VERTEX_FRAGMENT,
0,
bytemuck::cast_slice(&[constants]),
bytemuck::cast_slice(&[render_params.constants]),
);

render_pass.set_bind_group(0, &self.bind_group, &[]);
render_pass.set_bind_group(1, universal_bind_group, &[]);
render_pass.set_bind_group(1, draw_context.universal_bind_group, &[]);

self.drawable
.draw(queue, render_pass, constants, resources, clip, batch);
self.drawable.draw(
draw_context.queue,
render_pass,
render_params.constants,
render_params.resources,
render_params.clip,
render_params.batch,
);
}

pub fn draw_mask<'b, 'a: 'b>(
&'a mut self,
queue: &Queue,
draw_context: &DrawableContext,
render_pass: &mut RenderPass<'b>,
constants: ShaderConstants,
universal_bind_group: &'a BindGroup,
resources: &Resources,
clip: Option<Rect<u32>>,
batch: &PrimitiveBatch,
render_params: &RenderDrawableParams<'a>,
) {
render_pass.set_pipeline(self.render_mask_pipeline.as_ref().unwrap());

render_pass.set_push_constants(
ShaderStages::VERTEX_FRAGMENT,
0,
bytemuck::cast_slice(&[constants]),
bytemuck::cast_slice(&[render_params.constants]),
);

render_pass.set_bind_group(0, &self.bind_group, &[]);
render_pass.set_bind_group(1, universal_bind_group, &[]);
render_pass.set_bind_group(1, draw_context.universal_bind_group, &[]);

self.drawable
.draw(queue, render_pass, constants, resources, clip, batch);
self.drawable.draw(
draw_context.queue,
render_pass,
render_params.constants,
render_params.resources,
render_params.clip,
render_params.batch,
);
}
}
116 changes: 67 additions & 49 deletions src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@ use wgpu_profiler::{GpuProfiler, GpuProfilerSettings};
use crate::{
default_drawables::{BlurState, GlyphState, PathState, QuadState, SpriteState},
drawable::Drawable,
drawable_pipeline::DrawablePipeline,
drawable_pipeline::{
DrawableContext, DrawablePipeline, RenderContentParams, RenderDrawableParams,
},
drawable_reference::ATLAS_SIZE,
shader::{ShaderConstants, ShaderLoader},
LayerContents, Resources, Scene,
};

pub struct DrawContext<'a> {
pub encoder: &'a mut CommandEncoder,
pub first: &'a mut bool,
pub frame: &'a Texture,
pub frame_view: &'a TextureView,
}

pub struct Renderer {
pub adapter: Adapter,
pub device: Device,
Expand Down Expand Up @@ -332,12 +341,16 @@ impl Renderer {
&scene.resources,
);

let draw_context = DrawContext {
encoder: &mut encoder,
first: &mut first,
frame,
frame_view: &frame_view,
};

self.draw_content(
&layer.contents,
&mut encoder,
&mut first,
frame,
&frame_view,
draw_context,
layer.clip,
constants,
&scene.resources,
Expand Down Expand Up @@ -427,15 +440,19 @@ impl Renderer {
drawable_scope.set_scissor_rect(x, y, w, h);
}

drawable.draw_mask(
&self.queue,
&mut drawable_scope,
let draw_context = DrawableContext {
queue: &self.queue,
universal_bind_group: &self.universal_mask_bind_group,
};

let render_params = RenderDrawableParams {
constants,
&self.universal_mask_bind_group,
resources,
clip,
batch,
);
};

drawable.draw_mask(&draw_context, &mut drawable_scope, &render_params);
}
}
} else {
Expand Down Expand Up @@ -486,17 +503,16 @@ impl Renderer {
pub fn draw_content(
&mut self,
contents: &LayerContents,
encoder: &mut CommandEncoder,
first: &mut bool,
frame: &Texture,
frame_view: &TextureView,
context: DrawContext,
clip: Option<Rect<u32>>,
constants: ShaderConstants,
resources: &Resources,
) {
let mut content_scope = self.profiler.scope("content", encoder, &self.device);
let mut content_scope = self
.profiler
.scope("content", context.encoder, &self.device);

if *first {
if *context.first {
content_scope.scoped_render_pass(
"Clear Offscreen Texture",
&self.device,
Expand All @@ -518,31 +534,29 @@ impl Renderer {
} else {
'offscreen_copy: for batch in contents.primitives.iter() {
for drawable in self.drawables.iter() {
if drawable.has_work(batch) {
if drawable.requires_offscreen_copy() {
let mut copy_scope =
content_scope.scope("Copy Frame to Offscreen", &self.device);
copy_scope.copy_texture_to_texture(
ImageCopyTexture {
texture: frame,
mip_level: 0,
origin: Origin3d::ZERO,
aspect: Default::default(),
},
ImageCopyTexture {
texture: &self.offscreen_texture.texture,
mip_level: 0,
origin: Origin3d::ZERO,
aspect: Default::default(),
},
Extent3d {
width: self.width,
height: self.height,
depth_or_array_layers: 1,
},
);
break 'offscreen_copy;
}
if drawable.has_work(batch) && drawable.requires_offscreen_copy() {
let mut copy_scope =
content_scope.scope("Copy Frame to Offscreen", &self.device);
copy_scope.copy_texture_to_texture(
ImageCopyTexture {
texture: context.frame,
mip_level: 0,
origin: Origin3d::ZERO,
aspect: Default::default(),
},
ImageCopyTexture {
texture: &self.offscreen_texture.texture,
mip_level: 0,
origin: Origin3d::ZERO,
aspect: Default::default(),
},
Extent3d {
width: self.width,
height: self.height,
depth_or_array_layers: 1,
},
);
break 'offscreen_copy;
}
}
}
Expand All @@ -555,7 +569,7 @@ impl Renderer {
}

// The first drawable should clear the output texture
let attachment_op = if *first {
let attachment_op = if *context.first {
Operations::<Color> {
load: LoadOp::<_>::Clear(Color::WHITE),
store: StoreOp::Store,
Expand All @@ -573,7 +587,7 @@ impl Renderer {
RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[Some(RenderPassColorAttachment {
view: frame_view,
view: context.frame_view,
resolve_target: None,
ops: attachment_op,
})],
Expand All @@ -596,17 +610,21 @@ impl Renderer {
drawable_scope.set_scissor_rect(x, y, w, h);
}

drawable.draw_content(
&self.queue,
&mut drawable_scope,
let draw_context = DrawableContext {
queue: &self.queue,
universal_bind_group: &self.universal_content_bind_group,
};

let render_params = RenderContentParams {
constants,
&self.universal_content_bind_group,
resources,
clip,
batch,
);
};

drawable.draw_content(&draw_context, &mut drawable_scope, &render_params);

*first = false;
*context.first = false;
}
}
}
Expand Down
10 changes: 1 addition & 9 deletions src/scene/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ impl Layer {
}
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
pub struct LayerContents {
#[serde(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
Expand Down Expand Up @@ -324,14 +324,6 @@ impl LayerContents {
}
}

impl Default for LayerContents {
fn default() -> Self {
Self {
primitives: Vec::new(),
}
}
}

#[derive(Clone, Debug)]
pub enum PrimitiveBatch {
Mutable(MutablePrimitiveBatch),
Expand Down

0 comments on commit c26c55f

Please sign in to comment.