Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gpui: Enable MSAA to Path render for Anti-Aliasing #22812

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

huacnlee
Copy link
Contributor

@huacnlee huacnlee commented Jan 8, 2025

Closes #20762

Release Notes:

  • N/A

Enable MSAA for Anti-Aliasing to Path (cx.paint_path) for drawing a better vector graphics.

cargo run -p gpui --example gradient --features macos-blade
cargo run -p gpui --example gradient

cargo run -p gpui --example painting --features macos-blade
cargo run -p gpui --example painting

Before

image

After

image

TODO

  • Support Metal.
  • Detect system support to set up sample count.
  • Fix extra lines between Path vertices

Ref kvark/blade#213

Ask @kvark to review.

I am not sure if there is anything I missed. I modified it according to the particle example of Blade project. But the difference is that after the first MSAA render, I did not do it a second time, I tested it and found it was not necessary.

Before

if let mut pass = self.command_encoder.render(
    "draw particles with msaa resolve",
    gpu::RenderTargetSet {
        colors: &[gpu::RenderTarget {
            view: self.msaa_view.unwrap(),
            init_op: gpu::InitOp::Clear(gpu::TextureColor::OpaqueBlack),
            finish_op: gpu::FinishOp::ResolveTo(frame_view),
        }],
        depth_stencil: None,
    },
) {
    self.particle_system
        .draw(&mut pass, screen_desc.physical_size);
}
if let mut pass = self.command_encoder.render(
    "draw ui",
    gpu::RenderTargetSet {
        colors: &[gpu::RenderTarget {
            view: frame_view,
            init_op: gpu::InitOp::Load,
            finish_op: gpu::FinishOp::Store,
        }],
        depth_stencil: None,
    },
) {
    self.gui_painter
        .paint(&mut pass, gui_primitives, screen_desc, &self.context);
}

After

if let mut pass = self.command_encoder.render(
    "draw particles with msaa resolve",
    gpu::RenderTargetSet {
        colors: &[gpu::RenderTarget {
            view: self.msaa_view.unwrap(),
            init_op: gpu::InitOp::Clear(gpu::TextureColor::OpaqueBlack),
            finish_op: gpu::FinishOp::ResolveTo(frame_view),
        }],
        depth_stencil: None,
    },
) {
    self.particle_system
        .draw(&mut pass, screen_desc.physical_size);
    self.gui_painter
        .paint(&mut pass, gui_primitives, screen_desc, &self.context);
}

It looks no difference?

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Jan 8, 2025
crates/gpui/Cargo.toml Outdated Show resolved Hide resolved
@huacnlee huacnlee changed the title gpui: Enable blade MSAA for Anti-Aliasing gpui: Enable MSAA for Anti-Aliasing Jan 8, 2025
@huacnlee
Copy link
Contributor Author

huacnlee commented Jan 8, 2025

After turning on MSAA, an unexpected connection line will appear between the start point of the Path drawing and other corners.

Like this:

image

@huacnlee huacnlee changed the title gpui: Enable MSAA for Anti-Aliasing gpui: Enable MSAA to Path render for Anti-Aliasing Jan 8, 2025
@huacnlee
Copy link
Contributor Author

huacnlee commented Jan 9, 2025

Try a Shader change to use gather

Improve path_sprite_fragment to use gather to sample avg with 4 points.

✅ UPDATE: Is looks like not need to do this, reverted this change.

Before

SCR-20250109-jrpz image

After

SCR-20250109-jrva SCR-20250109-jzyq

Same case in Sketch

image

@huacnlee
Copy link
Contributor Author

huacnlee commented Jan 9, 2025

After turning on MSAA, an unexpected connection line will appear between the start point of the Path drawing and other corners.

Like this:

image

I'm stuck with this line problem. I've been looking for possible reasons for the past two days, but still can't solve it. 🤔

kvark pushed a commit to kvark/blade that referenced this pull request Jan 10, 2025
There need a method to check if the system supports a specific sample
count.

Ref zed-industries/zed#22812 need this feature
to setup sample_count.
Copy link
Contributor

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

@@ -128,7 +129,7 @@ struct BladePipelines {
}

impl BladePipelines {
fn new(gpu: &gpu::Context, surface_info: gpu::SurfaceInfo) -> Self {
fn new(gpu: &gpu::Context, surface_info: gpu::SurfaceInfo, sample_count: u32) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the argument should say explicitly that it's only for the path rasterization, e.g. path_sample_count


// TODO: Determine on non-macOS platforms, until Blade supports querying sample counts.
#[cfg(not(target_os = "macos"))]
let sample_count = 4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you really need the query? pretty sure the sample count of 4 is universally supported on all platforms

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, here is a reference:

https://developer.apple.com/documentation/metal/mtldevice/1433355-supportstexturesamplecount

Sample Count Devices
1 All devices
2 All iOS devices
All tvOS devices
Some macOS devices
4 All devices
8 Some macOS devices

}

impl BladeAtlas {
pub(crate) fn new(gpu: &Arc<gpu::Context>) -> Self {
pub(crate) fn new(gpu: &Arc<gpu::Context>, sample_count: u32) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit wasteful. We only want MSAA atlas tiles for things that actually require MSAA.
The atlas contains texture of different formats via AtlasTextureKind.
A general way to implement it is to turn BladeAtlasStorage into basically a HashMap<BladeAtlasKey, AtlasTextureList<BladeAtlasTexture>>, where BladeAtlasKey would be a combination of both AtlasTextureKind and the sample count.

A less general way would be to just make it explicitly path_sample_count, so that it only affects the rasterized path.
Honestly, I think this is a better way due to its simplicity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense.

I have changed only Path kind to create msaa_texutre

let mut pass = self.command_encoder.render(
"paths",
let frame_view = tex_info.raw_view;
let render_target = if let Some(msaa_view) = tex_info.msaa_view {
gpu::RenderTargetSet {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be slightly different

let color_target = if let Some(msaa_view) = tex_info.msaa_view {
gpu::RenderTarget {
                        view: tex_info.raw_view,
                        view: msaa_view,
                        init_op: gpu::InitOp::Clear(gpu::TextureColor::OpaqueBlack),
                        finish_op: gpu::FinishOp::ResolveTo(frame_view),
                    }
} else {
gpu::RenderTarget {
                        view: frame_view,
                        init_op: gpu::InitOp::Clear(gpu::TextureColor::OpaqueBlack),
                        finish_op: gpu::FinishOp::Store,
                    }
}

Copy link
Contributor Author

@huacnlee huacnlee Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you means should rename render_target to color_target? Or is other I missed?

Because the code that you given, there have a mistake (duplicate view), so I'm not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed The user has signed the Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

gpui: Improve paint_path draw straight line to anti-aliasing
2 participants