Skip to content

Do we want a SurfaceConfiguration builder? #338

@madsmtm

Description

@madsmtm

In #321, I've added Surface::configure that takes width, height and AlphaMode. This is necessary because changing those properties requires re-creating the underlying buffers, which is costly, and as such you'll want to do it at once (instead of e.g. having set_width/set_height/set_alpha_mode that each re-creates the buffers).

#317 will add PixelFormat to that as well, and any solution of #29 is probably going to require at least one more parameter. #320 might be in this category as well, I'm a bit unsure.

Do we want to introduce a SurfaceConfiguration struct to help with this, similar to wgpu's? That would allow more easily falling back to default values for parameters that the user doesn't care about:

surface.configure(SurfaceConfiguration {
    width: NonZero::new(width).unwrap(),
    height: NonZero::new(height).unwrap(),
    alpha_mode: AlphaMode::Premultiplied,
    .. // rest is default
})?;

An alternative would be to make configuration happen internally in buffer_mut, something like:

impl Surface<'_> {
    pub fn set_size(width: NonZero<u32>, height: NonZero<u32>) /* does not return an error */ {
         self.width = Some(width);
         self.height = Some(height);
    }

    pub fn set_alpha_mode(alpha_mode: AlphaMode) {
        self.alpha_mode = alpha_mode;
    }

    pub fn set_pixel_format(pixel_format: PixelFormat) {
        self.pixel_format = pixel_format;
    }

    // ...

    pub fn buffer_mut(&mut self) -> Result<Buffer<'_>, SoftbufferError> {
        let width = self.width.expect("must set width before calling `buffer_mut`");
        let height = self.height.expect("must set height before calling `buffer_mut`");
        self.inner.configure(width, height, self.alpha_mode, self.pixel_format, ...)?;
        self.inner.buffer_mut()
    }
}

This is already what the Wayland backend does internally, so might help make things more cross-platform? Or maybe there are disadvantages to this that I'm not seeing? E.g. maybe resizing in WindowEvent::Resized might help to reduce latency (it could probably be scheduled such that there was a little bit extra time to resize the buffers before WindowEvent::RequestedRedraw)?

Wrt. error handling, there's probably value in separating the "configure" errors from the "get buffer" errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions