Description
New DRM driver code does not fulfill my expectation.
- performance is very low - lv_example/benchmark is 6 FPS with DRM but 187 FPS / 84% with FBDEV
- many compiler of warnings (see below)
What MCU/Processor/Board and compiler are you using?
Allwinner V3s + display 800x480 (RGB)
gcc (Debian 8.3.0-6) 8.3.0
What do you experience?
compiler warnings:
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:71:10: warning: no previous prototype for ‘get_plane_property_id’ [-Wmissing-prototypes]
uint32_t get_plane_property_id(const char *name)
^~~~~~~~~~~~~~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:86:10: warning: no previous prototype for ‘get_crtc_property_id’ [-Wmissing-prototypes]
uint32_t get_crtc_property_id(const char *name)
^~~~~~~~~~~~~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:101:10: warning: no previous prototype for ‘get_conn_property_id’ [-Wmissing-prototypes]
uint32_t get_conn_property_id(const char *name)
^~~~~~~~~~~~~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c: In function ‘drm_add_plane_property’:
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:34:30: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘uint64_t’ {aka ‘long long unsigned int’} [-Wformat=]
#define err(msg, ...) print("error: " msg "\n", ##__VA_ARGS__)
^~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:197:61:
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:33:41: note: in definition of macro ‘print’
#define print(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__);
^~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:197:3: note: in expansion of macro ‘err’
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
^~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:197:39: note: format string is defined here
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
~~^
%llu
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c: In function ‘drm_add_crtc_property’:
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:34:30: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘uint64_t’ {aka ‘long long unsigned int’} [-Wformat=]
#define err(msg, ...) print("error: " msg "\n", ##__VA_ARGS__)
^~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:216:61:
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:33:41: note: in definition of macro ‘print’
#define print(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__);
^~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:216:3: note: in expansion of macro ‘err’
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
^~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:216:39: note: format string is defined here
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
~~^
%llu
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c: In function ‘drm_add_conn_property’:
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:34:30: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘uint64_t’ {aka ‘long long unsigned int’} [-Wformat=]
#define err(msg, ...) print("error: " msg "\n", ##__VA_ARGS__)
^~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:235:61:
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:33:41: note: in definition of macro ‘print’
#define print(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__);
^~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:235:3: note: in expansion of macro ‘err’
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
^~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:235:39: note: format string is defined here
err("drmModeAtomicAddProperty (%s:%lu) failed: %d", name, value, ret);
~~^
%llu
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c: In function ‘drm_find_connector’:
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:343:9: warning: unused variable ‘j’ [-Wunused-variable]
int i, j;
^
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c: In function ‘drm_allocate_dumb’:
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:653:8: warning: pointer targets in passing argument 5 of ‘drmModeAddFB2’ differ in signedness [-Wpointer-sign]
handles, pitches, offsets, &buf->fb_handle, 0);
^~~~~~~
In file included from /root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:26:
/usr/include/xf86drmMode.h:371:12: note: expected ‘const uint32_t *’ {aka ‘const unsigned int *’} but argument is of type ‘int *’
extern int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
^~~~~~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:653:17: warning: pointer targets in passing argument 6 of ‘drmModeAddFB2’ differ in signedness [-Wpointer-sign]
handles, pitches, offsets, &buf->fb_handle, 0);
^~~~~~~
In file included from /root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:26:
/usr/include/xf86drmMode.h:371:12: note: expected ‘const uint32_t *’ {aka ‘const unsigned int *’} but argument is of type ‘int *’
extern int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
^~~~~~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:653:26: warning: pointer targets in passing argument 7 of ‘drmModeAddFB2’ differ in signedness [-Wpointer-sign]
handles, pitches, offsets, &buf->fb_handle, 0);
^~~~~~~
In file included from /root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:26:
/usr/include/xf86drmMode.h:371:12: note: expected ‘const uint32_t *’ {aka ‘const unsigned int *’} but argument is of type ‘int *’
extern int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
^~~~~~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c: In function ‘drm_flush’:
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:717:48: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
if (w != drm_dev.width || h != drm_dev.height && drm_dev.cur_bufs[0])
~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:721:34: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
memcpy(fbuf->map + (area->x1 * (LV_COLOR_SIZE/8)) + (fbuf->pitch * i),
^
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:721:67: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
memcpy(fbuf->map + (area->x1 * (LV_COLOR_SIZE/8)) + (fbuf->pitch * i),
^
/root/lv_port_linux_frame_buffer/lv_drivers/display/drm.c:722:40: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
(void *)color_p + (w * (LV_COLOR_SIZE/8) * y),
^
What do you expect?
Better and tested code.
Is it possible to hook DRM double buffer to LVGL double buffer lv_disp_buf_init()
?
I tested small patch to disable double buffer in DRM code then performance equals to FBDEV (185 FPS/85 %):
diff --git a/display/drm.c b/display/drm.c
index bda938e..0c7311d 100644
--- a/display/drm.c
+++ b/display/drm.c
@@ -713,31 +713,22 @@ void drm_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color
dbg("x %d:%d y %d:%d w %d h %d", area->x1, area->x2, area->y1, area->y2, w, h);
- /* Partial update */
- if (w != drm_dev.width || h != drm_dev.height && drm_dev.cur_bufs[0])
- memcpy(fbuf->map, drm_dev.cur_bufs[0]->map, fbuf->size);
-
for (y = 0, i = area->y1 ; i <= area->y2 ; ++i, ++y) {
memcpy(fbuf->map + (area->x1 * (LV_COLOR_SIZE/8)) + (fbuf->pitch * i),
(void *)color_p + (w * (LV_COLOR_SIZE/8) * y),
w * (LV_COLOR_SIZE/8));
}
- if (drm_dev.req)
+ if (!drm_dev.cur_bufs[0]) {
+ /* show fbuf plane */
+ if (drm_dmabuf_set_plane(fbuf)) {
+ err("Flush fail");
+ return;
+ }
+ else
+ dbg("Flush done");
drm_wait_vsync(disp_drv);
-
- /* show fbuf plane */
- if (drm_dmabuf_set_plane(fbuf)) {
- err("Flush fail");
- return;
}
- else
- dbg("Flush done");
-
- if (!drm_dev.cur_bufs[0])
- drm_dev.cur_bufs[1] = &drm_dev.drm_bufs[1];
- else
- drm_dev.cur_bufs[1] = drm_dev.cur_bufs[0];
drm_dev.cur_bufs[0] = fbuf;