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

feat(disp): Enable rendering to display subsection #2583

Merged
merged 5 commits into from Oct 11, 2021

Conversation

Johennes
Copy link
Contributor

@Johennes Johennes commented Sep 22, 2021

Description of the feature or fix

This change introduces new fields on lv_disp_drv_t that allow to specify the size of the full display and the offset of the display
subsection that is being rendered to. The values are used to transform the drawing area before calling flush_cb so that only the desired part of the full display is being rendered to.

Relates to: lvgl/lv_drivers#166

Checkpoints

This is a draft for evaluating the proposal made in lvgl/lv_drivers#166 (comment). I tried using this in my framebuffer application to only draw my UI in the lower third of the screen and leave the upper two thirds untouched:

    /* Query display size */
    uint32_t hor_res;
    uint32_t ver_res_full;
    fbdev_get_sizes(&hor_res, &ver_res_full);

    /* Position display at the bottom of the screen */
    uint32_t ver_res = ver_res_full / 3;
    uint32_t ver_off = 2 * ver_res;

    /* Prepare display buffer */
    const size_t buf_size = hor_res * ver_res / 10; /* At least 1/10 of the display size is recommended */
    lv_disp_draw_buf_t disp_buf;
    lv_color_t *buf = (lv_color_t *)malloc(buf_size * sizeof(lv_color_t));
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, buf_size);    

    /* Initialise display driver */
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = fbdev_flush;
    disp_drv.hor_res = hor_res;
    disp_drv.ver_res = ver_res;
    disp_drv.physical_hor_res = hor_res;
    disp_drv.physical_ver_res = 3 * ver_res;
    disp_drv.offset_x = 0;
    disp_drv.offset_y = 2 * ver_res;
    lv_disp_drv_register(&disp_drv);

This does seem to work really well in my testing so far.

src/hal/lv_hal_disp.h Outdated Show resolved Hide resolved
src/core/lv_refr.c Outdated Show resolved Hide resolved
src/hal/lv_hal_disp.h Outdated Show resolved Hide resolved
@Johennes Johennes marked this pull request as ready for review September 24, 2021 07:32
Copy link
Member

@kisvegabor kisvegabor left a comment

Choose a reason for hiding this comment

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

Just a minor thing in the comment.

docs/porting/display.md Outdated Show resolved Hide resolved
This change introduces new fields on `lv_disp_drv_t` that allow to
specify the size of the full display and the offset of the display
subsection that is being rendered to. The values are used to transform
the drawing area before calling `flush_cb` so that only the desired part
of the full display is being rendered to.

Relates to: lvgl/lv_drivers#166
Copy link
Member

@embeddedt embeddedt left a comment

Choose a reason for hiding this comment

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

Hmm... correct me if I'm wrong, but physical_hor_res and physical_ver_res are ignored by LVGL, and all drivers have to have references to hor_res and ver_res replaced with the physical equivalents for this feature to work properly, right?

If so, do we also need physical versions of these functions to be added for MicroPython-based drivers?

@Johennes
Copy link
Contributor Author

Hmm... correct me if I'm wrong, but physical_hor_res and physical_ver_res are ignored by LVGL, and all drivers have to have references to hor_res and ver_res replaced with the physical equivalents for this feature to work properly, right?

Yes, that's correct but I'm not sure if the physical resolution will be needed in all drivers. The original problem that led to this PR is specified in lvgl/lv_drivers#166. In a non-full-screen app, touchscreens don't work correctly with the libinput driver because the driver maps absolute screen coordinates to absolute display coordinates. Pointer devices, in turn, still work correctly in this case because they only rely on relative coordinate changes.

If so, do we also need physical versions of these functions to be added for MicroPython-based drivers?

I can do that if you want me to. I'm not using MicroPython currently though so I can't judge if this will be needed or not.

@Johennes
Copy link
Contributor Author

Johennes commented Oct 1, 2021

Ok, I added physical versions of the functions in question now. Let me know if anything else is needed.

@Johennes
Copy link
Contributor Author

Johennes commented Oct 9, 2021

Merged master in (only had a conflict in the changelog).

@kisvegabor
Copy link
Member

Looks good to me. @embeddedt ?

@embeddedt embeddedt merged commit d09f6bd into lvgl:master Oct 11, 2021
@embeddedt
Copy link
Member

Looks good to me as well. Merged, thank you!

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.

None yet

4 participants