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

Problem on ESP platform with Embassy #5219

Open
KortanZ opened this issue May 12, 2024 · 9 comments
Open

Problem on ESP platform with Embassy #5219

KortanZ opened this issue May 12, 2024 · 9 comments

Comments

@KortanZ
Copy link

KortanZ commented May 12, 2024

I'm using ESP32C3 and following the Official MCU guide to build a demo. It works but i encounter two problems.

My Cargo.toml slint part

[dependencies.slint]
version = "1.5.1"
default-features = false
features = ["compat-1-2", "unsafe-single-threaded", "libm", "renderer-software"]
[build-dependencies]
slint-build = "1.5.1"

My .slint file

import { VerticalBox, Switch } from "std-widgets.slint";
export component Demo inherits Window{
    width: 128px;
    height: 128px;
    in-out property<bool> check: false;
    background: sw.checked ? #db073d:#07dba5;
    VerticalBox {
        alignment: center;
        Text {
            text: "Bg color test";
            font-size: 15px;
            horizontal-alignment: center;
        }
        sw := Switch {
            checked: check;
            text: "Switch";
        }
        Slider {
            minimum: 0;
            value: sw.checked ? 0 : 100;
            maximum: 100;
        }
    }
}

I'm using linebuffer method with super loop approach by following the guide.

  1. Can't use Slider widget, when add Slider in my .slint, compiler will error out with:

    called Result::unwrap() on an Err value: CompileError(["/home/kortan/Documents/code/rust/esp32/slint/ui/main.slint:21: Unknown type Slider"])

  2. When toggled switch, not full background freshed, only switch area changed.

    switch.mp4

    And when config animate to background, display get even weird.

import { VerticalBox, Switch } from "std-widgets.slint";
export component Demo inherits Window{
 width: 128px;
 height: 128px;
 in-out property<bool> check: false;
 background: sw.checked ? #db073d:#07dba5;
 animate background {
      duration: 300ms;
 }
 VerticalBox {
     alignment: center;
     Text {
         text: "Bg color test";
         font-size: 15px;
         horizontal-alignment: center;
     }
     sw := Switch {
         checked: check;
         text: "Switch";
     }
 }
}
switch_animate.mp4
@hunger
Copy link
Member

hunger commented May 13, 2024

Can't use Slider widget, when add Slider in my .slint, compiler will error out with:

Did you import the Slider? Adding it into the import {...} should work.

When toggled switch, not full background freshed, only switch area changed.

That sounds like a bug to me...

@KortanZ
Copy link
Author

KortanZ commented May 13, 2024

Did you import the Slider? Adding it into the import {...} should work.

Just realize that i've made a really dumb question. Sorry for that.

That sounds like a bug to me...

The slint code works well on slintpad. So there may be something wrong inside draw_if_needed.

@KortanZ
Copy link
Author

KortanZ commented May 14, 2024

After update to slint 1.6.0, things are not getting better much.

switch_animate_1.6.0.mp4

@tronical
Copy link
Member

How are you rendering to the screen? We made a change in 1.6 regarding the dirty regions. Render now returns the region that has multiple rectangles, all of which need to be flushed to the screen.
Do you use the return value of render() somewhere?

@KortanZ
Copy link
Author

KortanZ commented May 14, 2024

@tronical

How are you rendering to the screen?

My whole project code is here, everything about slint is in ui.rs, the render loop looks like this:

    loop {
        slint::platform::update_timers_and_animations();
        window.draw_if_needed(|renderer| {
            renderer.render_by_line(DisplayWrapper{
                display: &mut display,
                line_buffer: &mut line_buffer
            });
        });

        if !window.has_active_animations() {
            if let Some(duration) = slint::platform::duration_until_next_timer_update() {
                Timer::after(Duration::from_millis(duration.as_millis() as u64)).await;
                continue;
            }
        }
        Timer::after(Duration::from_millis(10)).await;
    }

and the LineBufferProvider implemention is like:

struct DisplayWrapper<'a, T>{
    display: &'a mut T,
    line_buffer: &'a mut [slint::platform::software_renderer::Rgb565Pixel],
}

impl<T: DrawTarget<Color = Rgb565>>
    slint::platform::software_renderer::LineBufferProvider for DisplayWrapper<'_, T>
{
    type TargetPixel = slint::platform::software_renderer::Rgb565Pixel;
    fn process_line(
        &mut self,
        line: usize,
        range: core::ops::Range<usize>,
        render_fn: impl FnOnce(&mut [Self::TargetPixel]),
    ) {
        // Render into the line
        render_fn(&mut self.line_buffer[range.clone()]);

        self.display.fill_contiguous(
            &Rectangle::new(Point::new(range.start as _, line as _), Size::new(range.len() as _, 1)),
            self.line_buffer[range.clone()].iter().map(|p| RawU16::new(p.0).into())
        ).map_err(drop).unwrap();
    }
}

Do you use the return value of render() somewhere?

No, I'm using render_by_line() instead and not using return value at all.

@tronical
Copy link
Member

Thanks for confirming. So it can’t be that. Does the background change work if you remove the animation on the background property? (Not a solution of course, but helps narrow down a theory I have)

@KortanZ
Copy link
Author

KortanZ commented May 15, 2024

@tronical

Does the background change work if you remove the animation on the background property?

switch_1.6.0.mp4

Just like when using slint 1.5.1 as i shown on top of this issue, the only difference between animated version and no animation version is that no animation version could change the color correctly rather than a unexpected deeper or lighter color.

@tronical
Copy link
Member

Ouch, ok, so my theory of it being related to the time is not true either :(. Since you're calling render_by_line, could you try to see via debug output what the values are for the line: usize parameter? When toggling the switch, you should get the function invoked also with line values that start at the top of the screen (so zero and onwards).

@KortanZ
Copy link
Author

KortanZ commented May 15, 2024

@tronical I've added debug output in process_line, and line: usize was start from 70 and end at 82 when toggling the switch. So it seems that only color changed area have been re-rendered.

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

No branches or pull requests

3 participants