-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
SDL display driver doesn't support API calls from a thread other than main #71410
Comments
@kartben can you provide a minimal repro case? |
@aescolar Tweaking the display driver sample like the below is the minimal repro. After applying the change, sample still works fine on e.g. M5Stack Core 2 (ILI9342C display controller), but SDL/native_sim_64 gives a black screen. diff --git a/samples/drivers/display/src/main.c b/samples/drivers/display/src/main.c
index a9267b51c7..af14abc3b0 100644
--- a/samples/drivers/display/src/main.c
+++ b/samples/drivers/display/src/main.c
@@ -170,8 +170,24 @@ static inline void fill_buffer_mono10(enum corner corner, uint8_t grey,
fill_buffer_mono(corner, grey, 0xFFu, 0x00u, buf, buf_size);
}
-int main(void)
+int gui_entry_point(void *arg1, void *arg2, void *arg3);
+
+K_THREAD_STACK_DEFINE(thread_stack, 4096);
+static struct k_thread thread;
+
+int main(void) {
+ k_thread_create(&thread, thread_stack, K_THREAD_STACK_SIZEOF(thread_stack),
+ (k_thread_entry_t)gui_entry_point, NULL, NULL, NULL,
+ K_PRIO_PREEMPT(5), 0, K_NO_WAIT);
+ return 0;
+}
+
+int gui_entry_point(void *arg1, void *arg2, void *arg3)
{
+ ARG_UNUSED(arg1);
+ ARG_UNUSED(arg2);
+ ARG_UNUSED(arg3);
+
size_t x;
size_t y;
size_t rect_w; SDL documentation is pretty clear on the fact that e.g. |
@kartben I can reproduce it with that example.
diff --git a/drivers/display/display_sdl.c b/drivers/display/display_sdl.c
index f21288d1b0f..44013c5adfe 100644
--- a/drivers/display/display_sdl.c
+++ b/drivers/display/display_sdl.c
@@ -48,7 +48,10 @@ static inline uint32_t mono_pixel_order(uint32_t order)
}
}
-static int sdl_display_init(const struct device *dev)
+static int sdl_display_init(const struct device *dev) {
+ return 0;
+}
+int _sdl_display_init(const struct device *dev)
{
const struct sdl_display_config *config = dev->config;
struct sdl_display_data *disp_data = dev->data;
diff --git a/samples/drivers/display/src/main.c b/samples/drivers/display/src/main.c
index a9267b51c74..1142d36ed30 100644
--- a/samples/drivers/display/src/main.c
+++ b/samples/drivers/display/src/main.c
@@ -189,6 +204,9 @@ int main(void)
fill_buffer fill_buffer_fnc = NULL;
display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
+ _sdl_display_init(display_dev);
if (!device_is_ready(display_dev)) {
LOG_ERR("Device %s not found. Aborting sample.",
display_dev->name);
Anyhow, SDL is a bit far from my expertise. Maybe you or one of the display maintainers has the bandwith? |
See issue for more details zephyrproject-rtos/zephyr#71410 Workaround is to run lv_task_handler from main thread and disable CONFIG_LV_Z_FLUSH_THREAD.
See issue for more details zephyrproject-rtos/zephyr#71410 Workaround is to run lv_task_handler from main thread and disable CONFIG_LV_Z_FLUSH_THREAD.
See issue for more details zephyrproject-rtos/zephyr#71410 Workaround is to run lv_task_handler from main thread and disable CONFIG_LV_Z_FLUSH_THREAD.
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time. |
See issue for more details zephyrproject-rtos/zephyr#71410 Workaround is to run lv_task_handler from main thread and disable CONFIG_LV_Z_FLUSH_THREAD.
See issue for more details zephyrproject-rtos/zephyr#71410 Workaround is to run lv_task_handler from main thread and disable CONFIG_LV_Z_FLUSH_THREAD.
This "workaround" wont work if you also add lvgl into your application. lvgl_init() is called too early and will miss a display to work at. |
@KimBP just to be clear: That (#71410 (comment)) was not a workaround, and I would very much discourage anybody from doing that. That comment was only meant to provide information about the possible cause of the issue. |
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time. |
@Finomnis just in case you feel like spending more time on the SDL driver :-) |
@kartben Might take a look at it. Although the only solution that comes to my mind is spawning a dedicated SDL thread. |
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time. |
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time. |
Related to #87519, setting |
I would intercept this and weaken it a little; we did not confirm that it actually fully breaks SDL input. It could be just in your project, where the priority of the render thread starves the input thread. |
Also, be careful with the word "fixes", both are undefined behavior in the current implementation, it just happens to work better. |
Good point could it be that this is a problem in general? EDIT: my apologies for closing and re-opening. Pressed the wrong button. |
Those priorities should be configurable. Maybe they should be reversed in your project? |
I took some time yesterday and did some testing. An easy way to break rendering is to have an additional flush thread:
What I found is that rendering breaks the second writes are done from a different thread:
What I find strange is that currently even without the Anyways I feel like all operations need to be happening in one thread:
The input_sdl_touch binding should be ok since it only adds a callback within the Don't know what is the best solution for this - let the display driver have an own thread where |
Something like that makes sense to me. |
I would probably implement it very similar to how the LVGL flush thread is implemented. About priorities: does this thread need a high priority or will it automatically inherit the priority of the calling thread if they synchronize via semaphore? |
Did a very dirty quick sketch for this: I find that this indeed fixes the rendering, would be intersting if this also fixes @PetervdPerk-NXP and @JarmouniA issues. Keeping the message buffer in memory really will not be needed if we make sure that there is only write message at a time, so thats something I will cleanup before submitting.
I think this will be a matter of priorities. |
@faxe1008 gotta be careful about recursion, the case where the input handlers get called from this thread which in turn causes a new write message. Might need to check if the calling thread is the SDL thread and then bypass the synchronization primitives. |
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Add a thread to the SDL display driver to ensure that init and renderer calls are performed from the same thread. Fixes zephyrproject-rtos#71410. Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
Describe the bug
Trying to call display functions (ex
display_write
) from a thread other thanmain
does not seem to work.To Reproduce
Steps to reproduce the behavior:
samples/drivers/display/src/main.c
so that the contents of main() is effectively executed in a different threadExpected behavior
SDL driver should work in a multithreaded environment, just like other display drivers.
Impact
can't run custom GUI code that requires a dedicated thread using native sim
Environment (please complete the following information):
Linux x86_64, 3.6.99 f419ea7
The text was updated successfully, but these errors were encountered: