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

Parameterize BitMapBackend with Generic Pixel #76

Closed
wants to merge 3 commits into from

Conversation

0b01
Copy link

@0b01 0b01 commented Oct 30, 2019

Closes #70

@0b01 0b01 changed the title Generic Pixel type for BitMapBackend Parameterize BitMapBackend with Generic Pixel Oct 30, 2019
pub(super) use std::path::Path;
pub(super) type BorrowedImage<'a> = ImageBuffer<Rgb<u8>, &'a mut [u8]>;
pub(super) type BorrowedImage<'a, P> = ImageBuffer<P, &'a mut [u8]>;
Copy link
Author

Choose a reason for hiding this comment

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

Note: bounds on generic parameters are not enforced in type aliases.

rust-lang/rust#21903

Copy link
Member

@38 38 left a comment

Choose a reason for hiding this comment

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

Hi there,
Thanks for the PR. I went through the code, and come up a few things.

  1. This is a fundamentally breaking change, which we should definitely avoid
  2. This change should break compilation if the image_encode feature isn't optin
  3. The BitMapBackend isn't use image crate for pixel manipulation, because of the performance.

You may not realized, the BitMapBackend isn't fully relies on image. Only the image encoding part do.
Which means even if there's no image crate dependecies, this backend still works for FrameBuffer use cases.

Another think is, this backend is optimized for speed. And this is very important for some of the realtime rendering, especially some embed use cases. As you can see, there's a lot of trick has been done to accelerate the pixel manipulation. Compare to the one uses image crate's pixel manipulation API, this backend is 10X faster than that.

Even we work out an acceptable API change, the performance regression is still another concern of using image crate for pixel manipulations.

I would suggest you dig into the fast rect fill code and discuss with me.

I am very happy to talk and please let me know if you have any ideas.

@@ -147,7 +147,7 @@ And the following code draws a quadratic function. `src/main.rs`,
```rust
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area();
let root = BitMapBackend::<image::Rgb<u8>>::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area();
Copy link
Member

Choose a reason for hiding this comment

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

This is breaking change, isn't it ? If this is the case, we need to at least do something on that. AFAK, BitMapImage is one of the most widely used backend. So a lot of impact will going on

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for the quick review. There are too many breaking changes in this PR and I didn't notice that color is directly coupled with buffer manipulation.

@@ -107,7 +107,7 @@ fn draw_func_2x1_inplace_parallel(c: &mut Criterion) {
let mut buffer = vec![0u8; (W * H * 3) as usize];
c.bench_function("parallel::draw_func_2x1_inplace", |b| {
b.iter(|| {
let mut back = BitMapBackend::with_buffer(&mut buffer, (W, H));
let mut back = BitMapBackend::<image::Rgb<u8>>::with_buffer(&mut buffer, (W, H));
Copy link
Member

Choose a reason for hiding this comment

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

As I previously mentioned, this change breaks too much.

@@ -111,7 +111,8 @@ impl<'a> Buffer<'a> {
}

/// The backend that drawing a bitmap
pub struct BitMapBackend<'a> {
pub struct BitMapBackend<'a, P: 'static + Pixel<Subpixel=u8>> {
Copy link
Member

Choose a reason for hiding this comment

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

This should breaks WASM build, or BitMap backend without image_encode feature opt in.

@@ -151,6 +153,7 @@ impl<'a> BitMapBackend<'a> {
frame_delay: u32,
) -> Result<Self, BitMapBackendError> {
Ok(Self {
_pix: PhantomData,
Copy link
Member

Choose a reason for hiding this comment

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

And I believe this change doesn't support pixel format other than RGB888, unless we change the fast pixel manipulation code as well. See function blend_rect_fast, fill_rect_fast

@0b01
Copy link
Author

0b01 commented Oct 30, 2019

Too many breaking changes. Abandoning PR.

@0b01 0b01 closed this Oct 30, 2019
@0b01 0b01 deleted the dynpixel branch October 30, 2019 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request] Different Pixel Format for BitMapBackend?
2 participants