From 59866c43cd64172dee698b44269bd34fa9972a0f Mon Sep 17 00:00:00 2001 From: bri3d Date: Sun, 23 Jul 2023 21:59:32 -0600 Subject: [PATCH 1/7] wait for push to finish before trying another push --- jni/fakehd/fakehd.h | 2 + jni/hw/dji_display.c | 116 +++++++++++++++++++++++++++++++++++++- jni/hw/dji_display.h | 6 +- jni/hw/dji_radio_shm.h | 2 + jni/hw/dji_services.h | 2 + jni/hw/duml_hal.h | 4 +- jni/msp/msp.h | 1 + jni/msp/msp_displayport.h | 2 + jni/msp_displayport_mux.c | 7 +-- jni/net/network.h | 2 + jni/net/serial.h | 2 + jni/osd.h | 2 + jni/osd_dji_overlay_udp.c | 116 +------------------------------------- jni/osd_dji_udp.c | 7 +-- jni/osd_sfml_udp.c | 7 +-- jni/toast/toast.h | 2 + jni/util/fs_util.c | 1 + jni/util/fs_util.h | 2 + jni/util/time_util.h | 2 + 19 files changed, 145 insertions(+), 140 deletions(-) diff --git a/jni/fakehd/fakehd.h b/jni/fakehd/fakehd.h index c82490a..d58398c 100644 --- a/jni/fakehd/fakehd.h +++ b/jni/fakehd/fakehd.h @@ -1,3 +1,5 @@ +#pragma once + void load_fakehd_config(); void fakehd_disable(); void fakehd_enable(); diff --git a/jni/hw/dji_display.c b/jni/hw/dji_display.c index 303c43c..92b4d64 100644 --- a/jni/hw/dji_display.c +++ b/jni/hw/dji_display.c @@ -1,10 +1,13 @@ #include #include "dji_display.h" +#include "util/debug.h" #define GOGGLES_V1_VOFFSET 575 #define GOGGLES_V2_VOFFSET 215 static duss_result_t pop_func(duss_disp_instance_handle_t *disp_handle,duss_disp_plane_id_t plane_id, duss_frame_buffer_t *frame_buffer,void *user_ctx) { + dji_display_state_t *display_state = (dji_display_state_t *)user_ctx; + display_state->frame_waiting = 0; return 0; } @@ -15,6 +18,7 @@ dji_display_state_t *dji_display_state_alloc(uint8_t is_v2_goggles) { display_state->fb_1 = (duss_frame_buffer_t *)calloc(1,sizeof(duss_frame_buffer_t)); display_state->pb_0 = (duss_disp_plane_blending_t *)calloc(1, sizeof(duss_disp_plane_blending_t)); display_state->is_v2_goggles = is_v2_goggles; + display_state->frame_waiting = 0; return display_state; } @@ -27,7 +31,6 @@ void dji_display_state_free(dji_display_state_t *display_state) { } void dji_display_close_framebuffer(dji_display_state_t *display_state) { - duss_hal_display_port_enable(display_state->disp_instance_handle, 3, 0); duss_hal_display_release_plane(display_state->disp_instance_handle, display_state->plane_id); duss_hal_display_close(display_state->disp_handle, &display_state->disp_instance_handle); @@ -94,7 +97,7 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_ printf("failed to acquire plane"); exit(0); } - res = duss_hal_display_register_frame_cycle_callback(display_state->disp_instance_handle, plane_id, &pop_func, 0); + res = duss_hal_display_register_frame_cycle_callback(display_state->disp_instance_handle, plane_id, &pop_func, display_state); if (res != 0) { printf("failed to register callback"); exit(0); @@ -171,10 +174,117 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_ } } + +void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, duss_disp_instance_handle_t *disp, duss_hal_obj_handle_t ion_handle, duss_disp_plane_id_t plane_id) { + uint32_t hal_device_open_unk = 0; + duss_result_t res = 0; + display_state->disp_instance_handle = disp; + display_state->ion_handle = ion_handle; + display_state->plane_id = plane_id; + + // PLANE BLENDING + + display_state->pb_0->is_enable = 1; + + // TODO just check hwid to figure this out. Not actually V1/V2 related but an HW version ID. + + display_state->pb_0->voffset = GOGGLES_V1_VOFFSET; + display_state->pb_0->hoffset = 0; + + // On Goggles V1, the UI and video are in Z-Order 1. On Goggles V2, they're in Z-Order 4. + // Unfortunately, this means we cannot draw below the DJI UI on Goggles V1. But, on Goggles V2 we get what we want. + + display_state->pb_0->order = 2; + + // Global alpha - disable as we want per pixel alpha. + + display_state->pb_0->glb_alpha_en = 0; + display_state->pb_0->glb_alpha_val = 0; + + // These aren't documented. Blending algorithm 0 is employed for menus and 1 for screensaver. + + display_state->pb_0->blending_alg = 1; + + // No idea what this "plane mode" actually does but it's different on V2 + uint8_t acquire_plane_mode = display_state->is_v2_goggles ? 6 : 0; + + DEBUG_PRINT("acquire plane\n"); + res = duss_hal_display_aquire_plane(display_state->disp_instance_handle,acquire_plane_mode,&plane_id); + if (res != 0) { + DEBUG_PRINT("failed to acquire plane"); + exit(0); + } + res = duss_hal_display_register_frame_cycle_callback(display_state->disp_instance_handle, plane_id, &pop_func, 0); + if (res != 0) { + DEBUG_PRINT("failed to register callback"); + exit(0); + } + + res = duss_hal_display_plane_blending_set(display_state->disp_instance_handle, plane_id, display_state->pb_0); + + if (res != 0) { + DEBUG_PRINT("failed to set blending"); + exit(0); + } + DEBUG_PRINT("alloc ion buf\n"); + res = duss_hal_mem_alloc(display_state->ion_handle,&display_state->ion_buf_0,0x473100,0x400,0,0x17); + if (res != 0) { + DEBUG_PRINT("failed to allocate VRAM"); + exit(0); + } + res = duss_hal_mem_map(display_state->ion_buf_0, &display_state->fb0_virtual_addr); + if (res != 0) { + DEBUG_PRINT("failed to map VRAM"); + exit(0); + } + res = duss_hal_mem_get_phys_addr(display_state->ion_buf_0, &display_state->fb0_physical_addr); + if (res != 0) { + DEBUG_PRINT("failed to get FB0 phys addr"); + exit(0); + } + DEBUG_PRINT("first buffer VRAM mapped virtual memory is at %p : %p\n", display_state->fb0_virtual_addr, display_state->fb0_physical_addr); + + res = duss_hal_mem_alloc(display_state->ion_handle,&display_state->ion_buf_1,0x473100,0x400,0,0x17); + if (res != 0) { + DEBUG_PRINT("failed to allocate FB1 VRAM"); + exit(0); + } + res = duss_hal_mem_map(display_state->ion_buf_1,&display_state->fb1_virtual_addr); + if (res != 0) { + DEBUG_PRINT("failed to map FB1 VRAM"); + exit(0); + } + res = duss_hal_mem_get_phys_addr(display_state->ion_buf_1, &display_state->fb1_physical_addr); + if (res != 0) { + DEBUG_PRINT("failed to get FB1 phys addr"); + exit(0); + } + DEBUG_PRINT("second buffer VRAM mapped virtual memory is at %p : %p\n", display_state->fb1_virtual_addr, display_state->fb1_physical_addr); + + for(int i = 0; i < 2; i++) { + duss_frame_buffer_t *fb = i ? display_state->fb_1 : display_state->fb_0; + fb->buffer = i ? display_state->ion_buf_1 : display_state->ion_buf_0; + fb->pixel_format = display_state->is_v2_goggles ? DUSS_PIXFMT_RGBA8888_GOGGLES_V2 : DUSS_PIXFMT_RGBA8888; // 20012 instead on V2 + fb->frame_id = i; + fb->planes[0].bytes_per_line = 0x1680; + fb->planes[0].offset = 0; + fb->planes[0].plane_height = 810; + fb->planes[0].bytes_written = 0x473100; + fb->width = 1440; + fb->height = 810; + fb->plane_count = 1; + } +} + void dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb) { duss_frame_buffer_t *fb = which_fb ? display_state->fb_1 : display_state->fb_0; duss_hal_mem_sync(fb->buffer, 1); - duss_hal_display_push_frame(display_state->disp_instance_handle, display_state->plane_id, fb); + if (display_state->frame_waiting == 0) { + display_state->frame_waiting = 1; + duss_hal_display_push_frame(display_state->disp_instance_handle, display_state->plane_id, fb); + } else { + DEBUG_PRINT("!!! Dropped frame due to pending frame push!\n"); + } } void *dji_display_get_fb_address(dji_display_state_t *display_state, uint8_t which_fb) { diff --git a/jni/hw/dji_display.h b/jni/hw/dji_display.h index 47200a4..35e7d7d 100644 --- a/jni/hw/dji_display.h +++ b/jni/hw/dji_display.h @@ -1,5 +1,4 @@ -#ifndef DJI_DISPLAY_H -#define DJI_DISPLAY_H +#pragma once #include "duml_hal.h" typedef struct dji_display_state_s { @@ -18,12 +17,13 @@ typedef struct dji_display_state_s { duss_frame_buffer_t *fb_1; duss_disp_plane_blending_t *pb_0; uint8_t is_v2_goggles; + uint8_t frame_waiting; } dji_display_state_t; void dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb); void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_plane_id_t plane_id); +void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, duss_disp_instance_handle_t *disp, duss_hal_obj_handle_t ion_handle, duss_disp_plane_id_t plane_id); void dji_display_close_framebuffer(dji_display_state_t *display_state); dji_display_state_t *dji_display_state_alloc(uint8_t is_v2_goggles); void dji_display_state_free(dji_display_state_t *display_state); void *dji_display_get_fb_address(dji_display_state_t *display_state, uint8_t which_fb); -#endif \ No newline at end of file diff --git a/jni/hw/dji_radio_shm.h b/jni/hw/dji_radio_shm.h index 893d4a9..021507b 100644 --- a/jni/hw/dji_radio_shm.h +++ b/jni/hw/dji_radio_shm.h @@ -1,3 +1,5 @@ + +#pragma once #include #define RTOS_SHM_ADDRESS 0xfffc1000 diff --git a/jni/hw/dji_services.h b/jni/hw/dji_services.h index bae6279..b192cab 100644 --- a/jni/hw/dji_services.h +++ b/jni/hw/dji_services.h @@ -1,3 +1,5 @@ +#pragma once + void dji_stop_goggles(int is_v2); void dji_start_goggles(int is_v2); int dji_goggles_are_v2(); \ No newline at end of file diff --git a/jni/hw/duml_hal.h b/jni/hw/duml_hal.h index 590be37..0e406d9 100644 --- a/jni/hw/duml_hal.h +++ b/jni/hw/duml_hal.h @@ -1,5 +1,4 @@ -#ifndef DUML_HAL_H -#define DUML_HAL_H +#pragma once #include typedef int32_t duss_result_t; @@ -259,4 +258,3 @@ duss_result_t duss_hal_attach_disp(char *param_1,duss_hal_obj **param_2); duss_result_t duss_hal_attach_ion_mem(char *param_1,duss_hal_obj **param_2); duss_result_t duss_hal_detach_ion_mem(); duss_result_t duss_hal_detach_disp(); -#endif \ No newline at end of file diff --git a/jni/msp/msp.h b/jni/msp/msp.h index 23ade1f..e25b35b 100644 --- a/jni/msp/msp.h +++ b/jni/msp/msp.h @@ -1,3 +1,4 @@ +#pragma once #include #define MSP_CMD_API_VERSION 1 diff --git a/jni/msp/msp_displayport.h b/jni/msp/msp_displayport.h index fe5e72f..938c8e6 100644 --- a/jni/msp/msp_displayport.h +++ b/jni/msp/msp_displayport.h @@ -1,4 +1,6 @@ +#pragma once #include +#include "msp.h" typedef enum { MSP_DISPLAYPORT_KEEPALIVE, diff --git a/jni/msp_displayport_mux.c b/jni/msp_displayport_mux.c index 21d09bf..4a71648 100644 --- a/jni/msp_displayport_mux.c +++ b/jni/msp_displayport_mux.c @@ -13,6 +13,7 @@ #include "net/serial.h" #include "msp/msp.h" #include "msp/msp_displayport.h" +#include "util/debug.h" #include "util/time_util.h" #include "util/fs_util.h" @@ -42,12 +43,6 @@ enum { // The Betaflight MSP minor version in which MSP DisplayPort sizing is supported. #define MSP_DISPLAY_SIZE_VERSION 45 -#ifdef DEBUG -#define DEBUG_PRINT(fmt, args...) fprintf(stderr, fmt, ## args) -#else -#define DEBUG_PRINT(fmt, args...) -#endif - typedef struct msp_cache_entry_s { struct timespec time; msp_msg_t message; diff --git a/jni/net/network.h b/jni/net/network.h index 85b2df6..48e1161 100644 --- a/jni/net/network.h +++ b/jni/net/network.h @@ -1,2 +1,4 @@ +#pragma once + int connect_to_server(char *address, int port); int bind_socket(int port); \ No newline at end of file diff --git a/jni/net/serial.h b/jni/net/serial.h index f5ae8ee..1df9810 100644 --- a/jni/net/serial.h +++ b/jni/net/serial.h @@ -1,3 +1,5 @@ +#pragma once + #include int open_serial_port(const char *device, speed_t baudrate); diff --git a/jni/osd.h b/jni/osd.h index 621698b..0b2ba64 100644 --- a/jni/osd.h +++ b/jni/osd.h @@ -1,3 +1,5 @@ +#pragma once + #include "hw/dji_display.h" void osd_directfb(duss_disp_instance_handle_t *disp, duss_hal_obj_handle_t ion_handle); diff --git a/jni/osd_dji_overlay_udp.c b/jni/osd_dji_overlay_udp.c index d40d466..2a98012 100644 --- a/jni/osd_dji_overlay_udp.c +++ b/jni/osd_dji_overlay_udp.c @@ -28,6 +28,7 @@ #include "msp/msp.h" #include "msp/msp_displayport.h" +#include "util/debug.h" #include "util/fs_util.h" #include "util/time_util.h" #include "rec/rec.h" @@ -76,12 +77,6 @@ typedef enum #define BACK_BUTTON_DELAY 4 -#ifdef DEBUG -#define DEBUG_PRINT(fmt, args...) fprintf(stderr, fmt, ## args) -#else -#define DEBUG_PRINT(fmt, args...) -#endif - #define SWAP32(data) \ ( (((data) >> 24) & 0x000000FF) | (((data) >> 8) & 0x0000FF00) | \ (((data) << 8) & 0x00FF0000) | (((data) << 24) & 0xFF000000) ) @@ -114,6 +109,8 @@ struct timespec last_render; static char current_fc_variant[5]; +static uint8_t frame_waiting = 0; + static display_info_t sd_display_info = { .char_width = 30, .char_height = 15, @@ -450,113 +447,6 @@ static void display_print_string(uint8_t init_x, uint8_t y, const char *string, } } -/* DJI framebuffer configuration */ - -static duss_result_t pop_func(duss_disp_instance_handle_t *disp_handle,duss_disp_plane_id_t plane_id, duss_frame_buffer_t *frame_buffer,void *user_ctx) { - return 0; -} - -void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, duss_disp_instance_handle_t *disp, duss_hal_obj_handle_t ion_handle, duss_disp_plane_id_t plane_id) { - uint32_t hal_device_open_unk = 0; - duss_result_t res = 0; - display_state->disp_instance_handle = disp; - display_state->ion_handle = ion_handle; - display_state->plane_id = plane_id; - - // PLANE BLENDING - - display_state->pb_0->is_enable = 1; - - // TODO just check hwid to figure this out. Not actually V1/V2 related but an HW version ID. - - display_state->pb_0->voffset = GOGGLES_V1_VOFFSET; - display_state->pb_0->hoffset = 0; - - // On Goggles V1, the UI and video are in Z-Order 1. On Goggles V2, they're in Z-Order 4. - // Unfortunately, this means we cannot draw below the DJI UI on Goggles V1. But, on Goggles V2 we get what we want. - - display_state->pb_0->order = 2; - - // Global alpha - disable as we want per pixel alpha. - - display_state->pb_0->glb_alpha_en = 0; - display_state->pb_0->glb_alpha_val = 0; - - // These aren't documented. Blending algorithm 0 is employed for menus and 1 for screensaver. - - display_state->pb_0->blending_alg = 1; - - // No idea what this "plane mode" actually does but it's different on V2 - uint8_t acquire_plane_mode = display_state->is_v2_goggles ? 6 : 0; - - DEBUG_PRINT("acquire plane\n"); - res = duss_hal_display_aquire_plane(display_state->disp_instance_handle,acquire_plane_mode,&plane_id); - if (res != 0) { - DEBUG_PRINT("failed to acquire plane"); - exit(0); - } - res = duss_hal_display_register_frame_cycle_callback(display_state->disp_instance_handle, plane_id, &pop_func, 0); - if (res != 0) { - DEBUG_PRINT("failed to register callback"); - exit(0); - } - - res = duss_hal_display_plane_blending_set(display_state->disp_instance_handle, plane_id, display_state->pb_0); - - if (res != 0) { - DEBUG_PRINT("failed to set blending"); - exit(0); - } - DEBUG_PRINT("alloc ion buf\n"); - res = duss_hal_mem_alloc(display_state->ion_handle,&display_state->ion_buf_0,0x473100,0x400,0,0x17); - if (res != 0) { - DEBUG_PRINT("failed to allocate VRAM"); - exit(0); - } - res = duss_hal_mem_map(display_state->ion_buf_0, &display_state->fb0_virtual_addr); - if (res != 0) { - DEBUG_PRINT("failed to map VRAM"); - exit(0); - } - res = duss_hal_mem_get_phys_addr(display_state->ion_buf_0, &display_state->fb0_physical_addr); - if (res != 0) { - DEBUG_PRINT("failed to get FB0 phys addr"); - exit(0); - } - DEBUG_PRINT("first buffer VRAM mapped virtual memory is at %p : %p\n", display_state->fb0_virtual_addr, display_state->fb0_physical_addr); - - res = duss_hal_mem_alloc(display_state->ion_handle,&display_state->ion_buf_1,0x473100,0x400,0,0x17); - if (res != 0) { - DEBUG_PRINT("failed to allocate FB1 VRAM"); - exit(0); - } - res = duss_hal_mem_map(display_state->ion_buf_1,&display_state->fb1_virtual_addr); - if (res != 0) { - DEBUG_PRINT("failed to map FB1 VRAM"); - exit(0); - } - res = duss_hal_mem_get_phys_addr(display_state->ion_buf_1, &display_state->fb1_physical_addr); - if (res != 0) { - DEBUG_PRINT("failed to get FB1 phys addr"); - exit(0); - } - DEBUG_PRINT("second buffer VRAM mapped virtual memory is at %p : %p\n", display_state->fb1_virtual_addr, display_state->fb1_physical_addr); - - for(int i = 0; i < 2; i++) { - duss_frame_buffer_t *fb = i ? display_state->fb_1 : display_state->fb_0; - fb->buffer = i ? display_state->ion_buf_1 : display_state->ion_buf_0; - fb->pixel_format = display_state->is_v2_goggles ? DUSS_PIXFMT_RGBA8888_GOGGLES_V2 : DUSS_PIXFMT_RGBA8888; // 20012 instead on V2 - fb->frame_id = i; - fb->planes[0].bytes_per_line = 0x1680; - fb->planes[0].offset = 0; - fb->planes[0].plane_height = 810; - fb->planes[0].bytes_written = 0x473100; - fb->width = 1440; - fb->height = 810; - fb->plane_count = 1; - } -} - /* Display initialization and deinitialization */ static void start_display(uint8_t is_v2_goggles,duss_disp_instance_handle_t *disp, duss_hal_obj_handle_t ion_handle) { diff --git a/jni/osd_dji_udp.c b/jni/osd_dji_udp.c index 1cb0c88..1be25ca 100644 --- a/jni/osd_dji_udp.c +++ b/jni/osd_dji_udp.c @@ -22,6 +22,7 @@ #include "net/data_protocol.h" #include "msp/msp.h" #include "msp/msp_displayport.h" +#include "util/debug.h" #include "util/fs_util.h" #define MSP_PORT 7654 @@ -48,12 +49,6 @@ #define BACK_BUTTON_DELAY 4 -#ifdef DEBUG -#define DEBUG_PRINT(fmt, args...) fprintf(stderr, fmt, ## args) -#else -#define DEBUG_PRINT(fmt, args...) -#endif - #define SWAP32(data) \ ( (((data) >> 24) & 0x000000FF) | (((data) >> 8) & 0x0000FF00) | \ (((data) << 8) & 0x00FF0000) | (((data) << 24) & 0xFF000000) ) diff --git a/jni/osd_sfml_udp.c b/jni/osd_sfml_udp.c index 89eac7b..b0b5410 100644 --- a/jni/osd_sfml_udp.c +++ b/jni/osd_sfml_udp.c @@ -16,12 +16,7 @@ #include "msp/msp_displayport.h" #include "net/serial.h" #include "net/network.h" - -#ifdef DEBUG -#define DEBUG_PRINT(fmt, args...) fprintf(stderr, fmt, ## args) -#else -#define DEBUG_PRINT(fmt, args...) -#endif +#include "util/debug.h" #define X_OFFSET 120 diff --git a/jni/toast/toast.h b/jni/toast/toast.h index f29cbe3..a26d1fa 100644 --- a/jni/toast/toast.h +++ b/jni/toast/toast.h @@ -1,3 +1,5 @@ +#pragma once + int toast(char*, ...); void toast_load_config(); void do_toast(void (*display_print_string)(uint8_t init_x, uint8_t y, const char *string, uint8_t len)); \ No newline at end of file diff --git a/jni/util/fs_util.c b/jni/util/fs_util.c index c7f6896..f1769e0 100644 --- a/jni/util/fs_util.c +++ b/jni/util/fs_util.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include diff --git a/jni/util/fs_util.h b/jni/util/fs_util.h index 7991450..fcfa82a 100644 --- a/jni/util/fs_util.h +++ b/jni/util/fs_util.h @@ -1,3 +1,5 @@ +#pragma once + #include int32_t get_int_from_fs(char* path); diff --git a/jni/util/time_util.h b/jni/util/time_util.h index e4d98f6..10da606 100644 --- a/jni/util/time_util.h +++ b/jni/util/time_util.h @@ -1,3 +1,5 @@ +#pragma once + #include #include From cff01af7e28c325025f064a1e95a3c94946417d6 Mon Sep 17 00:00:00 2001 From: bri3d Date: Tue, 8 Aug 2023 15:38:40 -0600 Subject: [PATCH 2/7] add debug.h --- jni/util/debug.h | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 jni/util/debug.h diff --git a/jni/util/debug.h b/jni/util/debug.h new file mode 100644 index 0000000..bbdd4c4 --- /dev/null +++ b/jni/util/debug.h @@ -0,0 +1,7 @@ +#pragma once + +#ifdef DEBUG +#define DEBUG_PRINT(fmt, args...) fprintf(stderr, fmt, ## args) +#else +#define DEBUG_PRINT(fmt, args...) +#endif \ No newline at end of file From 71b8811994958d9492bd699c913da1f55d8bb58c Mon Sep 17 00:00:00 2001 From: Joonas Trussmann Date: Thu, 10 Aug 2023 18:21:01 +0300 Subject: [PATCH 3/7] Corrected which_fb behavior when frames are dropped --- jni/hw/dji_display.c | 4 +++- jni/hw/dji_display.h | 2 +- jni/osd_dji_overlay_udp.c | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/jni/hw/dji_display.c b/jni/hw/dji_display.c index 92b4d64..9ce3f84 100644 --- a/jni/hw/dji_display.c +++ b/jni/hw/dji_display.c @@ -276,14 +276,16 @@ void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, d } } -void dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb) { +uint8_t dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb) { duss_frame_buffer_t *fb = which_fb ? display_state->fb_1 : display_state->fb_0; duss_hal_mem_sync(fb->buffer, 1); if (display_state->frame_waiting == 0) { display_state->frame_waiting = 1; duss_hal_display_push_frame(display_state->disp_instance_handle, display_state->plane_id, fb); + return !which_fb; } else { DEBUG_PRINT("!!! Dropped frame due to pending frame push!\n"); + return which_fb; } } diff --git a/jni/hw/dji_display.h b/jni/hw/dji_display.h index 35e7d7d..dfd85bb 100644 --- a/jni/hw/dji_display.h +++ b/jni/hw/dji_display.h @@ -20,7 +20,7 @@ typedef struct dji_display_state_s { uint8_t frame_waiting; } dji_display_state_t; -void dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb); +uint8_t dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb); void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_plane_id_t plane_id); void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, duss_disp_instance_handle_t *disp, duss_hal_obj_handle_t ion_handle, duss_disp_plane_id_t plane_id); void dji_display_close_framebuffer(dji_display_state_t *display_state); diff --git a/jni/osd_dji_overlay_udp.c b/jni/osd_dji_overlay_udp.c index 2a98012..3c9a7a6 100644 --- a/jni/osd_dji_overlay_udp.c +++ b/jni/osd_dji_overlay_udp.c @@ -252,8 +252,7 @@ static void render_screen() { if (display_mode == DISPLAY_DISABLED) { clear_framebuffer(); } - dji_display_push_frame(dji_display, which_fb); - which_fb = !which_fb; + which_fb = dji_display_push_frame(dji_display, which_fb); DEBUG_PRINT("drew a frame\n"); clock_gettime(CLOCK_MONOTONIC, &last_render); } From ebae1247fe282af139ccebe7ef904b942796c07c Mon Sep 17 00:00:00 2001 From: Ben Lumley Date: Thu, 10 Aug 2023 23:17:14 +0100 Subject: [PATCH 4/7] Debug / disable clear + draw the blanks in the main loop --- jni/hw/dji_display.c | 30 ++++++++++++++++++------------ jni/hw/dji_display.h | 4 ++-- jni/osd_dji_overlay_udp.c | 13 ++++++------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/jni/hw/dji_display.c b/jni/hw/dji_display.c index 9ce3f84..48a4798 100644 --- a/jni/hw/dji_display.c +++ b/jni/hw/dji_display.c @@ -5,9 +5,12 @@ #define GOGGLES_V1_VOFFSET 575 #define GOGGLES_V2_VOFFSET 215 +static uint8_t which_fb = 0; + static duss_result_t pop_func(duss_disp_instance_handle_t *disp_handle,duss_disp_plane_id_t plane_id, duss_frame_buffer_t *frame_buffer,void *user_ctx) { dji_display_state_t *display_state = (dji_display_state_t *)user_ctx; display_state->frame_waiting = 0; + printf("fbdebug pop_func\n"); return 0; } @@ -63,7 +66,7 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_ // Blending algorithm 1 seems to work. display_state->pb_0->blending_alg = 1; - + duss_hal_device_desc_t device_descs[3] = { {"/dev/dji_display", &duss_hal_attach_disp, &duss_hal_detach_disp, 0x0}, {"/dev/ion", &duss_hal_attach_ion_mem, &duss_hal_detach_ion_mem, 0x0}, @@ -71,7 +74,7 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_ }; duss_hal_initialize(device_descs); - + res = duss_hal_device_open("/dev/dji_display",&hal_device_open_unk,&display_state->disp_handle); if (res != 0) { printf("failed to open dji_display device"); @@ -82,13 +85,13 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_ printf("failed to open display hal"); exit(0); } - + res = duss_hal_display_reset(display_state->disp_instance_handle); if (res != 0) { printf("failed to reset display"); exit(0); } - + // No idea what this "plane mode" actually does but it's different on V2 uint8_t acquire_plane_mode = display_state->is_v2_goggles ? 6 : 0; @@ -109,7 +112,7 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_ } res = duss_hal_display_plane_blending_set(display_state->disp_instance_handle, plane_id, display_state->pb_0); - + if (res != 0) { printf("failed to set blending"); exit(0); @@ -158,7 +161,7 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_ exit(0); } printf("second buffer VRAM mapped virtual memory is at %p : %p\n", display_state->fb1_virtual_addr, display_state->fb1_physical_addr); - + for(int i = 0; i < 2; i++) { duss_frame_buffer_t *fb = i ? display_state->fb_1 : display_state->fb_0; fb->buffer = i ? display_state->ion_buf_1 : display_state->ion_buf_0; @@ -276,20 +279,23 @@ void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, d } } -uint8_t dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb) { - duss_frame_buffer_t *fb = which_fb ? display_state->fb_1 : display_state->fb_0; - duss_hal_mem_sync(fb->buffer, 1); +void dji_display_push_frame(dji_display_state_t *display_state) { + // print which_fb + printf("fbdebug which_fb: %d\n", which_fb); if (display_state->frame_waiting == 0) { + which_fb = !which_fb; + duss_frame_buffer_t *fb = which_fb ? display_state->fb_1 : display_state->fb_0; + duss_hal_mem_sync(fb->buffer, 1); display_state->frame_waiting = 1; + printf("fbdebug pushing frame\n"); duss_hal_display_push_frame(display_state->disp_instance_handle, display_state->plane_id, fb); - return !which_fb; } else { DEBUG_PRINT("!!! Dropped frame due to pending frame push!\n"); - return which_fb; + printf("fbdebug dropping frame\n"); } } -void *dji_display_get_fb_address(dji_display_state_t *display_state, uint8_t which_fb) { +void *dji_display_get_fb_address(dji_display_state_t *display_state) { return which_fb ? display_state->fb1_virtual_addr : display_state->fb0_virtual_addr; } diff --git a/jni/hw/dji_display.h b/jni/hw/dji_display.h index dfd85bb..5389d25 100644 --- a/jni/hw/dji_display.h +++ b/jni/hw/dji_display.h @@ -20,10 +20,10 @@ typedef struct dji_display_state_s { uint8_t frame_waiting; } dji_display_state_t; -uint8_t dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb); +void dji_display_push_frame(dji_display_state_t *display_state); void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_plane_id_t plane_id); void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, duss_disp_instance_handle_t *disp, duss_hal_obj_handle_t ion_handle, duss_disp_plane_id_t plane_id); void dji_display_close_framebuffer(dji_display_state_t *display_state); dji_display_state_t *dji_display_state_alloc(uint8_t is_v2_goggles); void dji_display_state_free(dji_display_state_t *display_state); -void *dji_display_get_fb_address(dji_display_state_t *display_state, uint8_t which_fb); +void *dji_display_get_fb_address(dji_display_state_t *display_state); diff --git a/jni/osd_dji_overlay_udp.c b/jni/osd_dji_overlay_udp.c index 3c9a7a6..cf030b9 100644 --- a/jni/osd_dji_overlay_udp.c +++ b/jni/osd_dji_overlay_udp.c @@ -104,7 +104,6 @@ static uint16_t msp_character_map[MAX_DISPLAY_X][MAX_DISPLAY_Y]; static uint16_t msp_render_character_map[MAX_DISPLAY_X][MAX_DISPLAY_Y]; static uint16_t overlay_character_map[MAX_DISPLAY_X][MAX_DISPLAY_Y]; static displayport_vtable_t *display_driver; -static uint8_t which_fb = 0; struct timespec last_render; static char current_fc_variant[5]; @@ -189,7 +188,7 @@ static void draw_character_map(display_info_t *display_info, void* restrict fb_a for(int y = 0; y < display_info->char_height; y++) { for(int x = 0; x < display_info->char_width; x++) { uint16_t c = character_map[x][y]; - if (c != 0) { + // if (c != 0) { font = display_info->font_page_1; if (c > 255) { c = c & 0xFF; @@ -211,7 +210,7 @@ static void draw_character_map(display_info_t *display_info, void* restrict fb_a target_offset += WIDTH * BYTES_PER_PIXEL - (display_info->font_width * BYTES_PER_PIXEL); } // DEBUG_PRINT("%c", c > 31 ? c : 20); - } + // } // DEBUG_PRINT(" "); } // DEBUG_PRINT("\n"); @@ -219,15 +218,15 @@ static void draw_character_map(display_info_t *display_info, void* restrict fb_a } static void clear_framebuffer() { - void *fb_addr = dji_display_get_fb_address(dji_display, which_fb); + void *fb_addr = dji_display_get_fb_address(dji_display); // DJI has a backwards alpha channel - FF is transparent, 00 is opaque. memset(fb_addr, 0x000000FF, WIDTH * HEIGHT * BYTES_PER_PIXEL); } static void draw_screen() { - void *fb_addr = dji_display_get_fb_address(dji_display, which_fb); + void *fb_addr = dji_display_get_fb_address(dji_display); // DJI has a backwards alpha channel - FF is transparent, 00 is opaque. - memset(fb_addr, 0x000000FF, WIDTH * HEIGHT * BYTES_PER_PIXEL); + // memset(fb_addr, 0x000000FF, WIDTH * HEIGHT * BYTES_PER_PIXEL); if (fakehd_is_enabled()) { fakehd_map_sd_character_map_to_hd(msp_character_map, msp_render_character_map); @@ -252,7 +251,7 @@ static void render_screen() { if (display_mode == DISPLAY_DISABLED) { clear_framebuffer(); } - which_fb = dji_display_push_frame(dji_display, which_fb); + dji_display_push_frame(dji_display); DEBUG_PRINT("drew a frame\n"); clock_gettime(CLOCK_MONOTONIC, &last_render); } From 5390d16c46565b3fd2e3225f02cf05e226c88714 Mon Sep 17 00:00:00 2001 From: Ben Lumley Date: Fri, 11 Aug 2023 17:22:33 +0100 Subject: [PATCH 5/7] Hackier way to double buffer; but works --- jni/hw/dji_display.c | 19 +++++++------------ jni/hw/dji_display.h | 2 +- jni/osd_dji_overlay_udp.c | 6 +++--- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/jni/hw/dji_display.c b/jni/hw/dji_display.c index 48a4798..4ac8ace 100644 --- a/jni/hw/dji_display.c +++ b/jni/hw/dji_display.c @@ -5,11 +5,9 @@ #define GOGGLES_V1_VOFFSET 575 #define GOGGLES_V2_VOFFSET 215 -static uint8_t which_fb = 0; - static duss_result_t pop_func(duss_disp_instance_handle_t *disp_handle,duss_disp_plane_id_t plane_id, duss_frame_buffer_t *frame_buffer,void *user_ctx) { dji_display_state_t *display_state = (dji_display_state_t *)user_ctx; - display_state->frame_waiting = 0; + display_state->frame_drawn = 0; printf("fbdebug pop_func\n"); return 0; } @@ -21,7 +19,7 @@ dji_display_state_t *dji_display_state_alloc(uint8_t is_v2_goggles) { display_state->fb_1 = (duss_frame_buffer_t *)calloc(1,sizeof(duss_frame_buffer_t)); display_state->pb_0 = (duss_disp_plane_blending_t *)calloc(1, sizeof(duss_disp_plane_blending_t)); display_state->is_v2_goggles = is_v2_goggles; - display_state->frame_waiting = 0; + display_state->frame_drawn = 0; return display_state; } @@ -280,22 +278,19 @@ void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, d } void dji_display_push_frame(dji_display_state_t *display_state) { - // print which_fb - printf("fbdebug which_fb: %d\n", which_fb); - if (display_state->frame_waiting == 0) { - which_fb = !which_fb; - duss_frame_buffer_t *fb = which_fb ? display_state->fb_1 : display_state->fb_0; + if (display_state->frame_drawn == 0) { + duss_frame_buffer_t *fb = display_state->fb_0; duss_hal_mem_sync(fb->buffer, 1); - display_state->frame_waiting = 1; + display_state->frame_drawn = 1; printf("fbdebug pushing frame\n"); duss_hal_display_push_frame(display_state->disp_instance_handle, display_state->plane_id, fb); } else { DEBUG_PRINT("!!! Dropped frame due to pending frame push!\n"); - printf("fbdebug dropping frame\n"); } + memcpy(display_state->fb0_virtual_addr, display_state->fb1_virtual_addr, sizeof(uint32_t) * 1440 * 810); } void *dji_display_get_fb_address(dji_display_state_t *display_state) { - return which_fb ? display_state->fb1_virtual_addr : display_state->fb0_virtual_addr; + return display_state->fb1_virtual_addr; } diff --git a/jni/hw/dji_display.h b/jni/hw/dji_display.h index 5389d25..49fb768 100644 --- a/jni/hw/dji_display.h +++ b/jni/hw/dji_display.h @@ -17,7 +17,7 @@ typedef struct dji_display_state_s { duss_frame_buffer_t *fb_1; duss_disp_plane_blending_t *pb_0; uint8_t is_v2_goggles; - uint8_t frame_waiting; + uint8_t frame_drawn; } dji_display_state_t; void dji_display_push_frame(dji_display_state_t *display_state); diff --git a/jni/osd_dji_overlay_udp.c b/jni/osd_dji_overlay_udp.c index cf030b9..e9ef091 100644 --- a/jni/osd_dji_overlay_udp.c +++ b/jni/osd_dji_overlay_udp.c @@ -188,7 +188,7 @@ static void draw_character_map(display_info_t *display_info, void* restrict fb_a for(int y = 0; y < display_info->char_height; y++) { for(int x = 0; x < display_info->char_width; x++) { uint16_t c = character_map[x][y]; - // if (c != 0) { + if (c != 0) { font = display_info->font_page_1; if (c > 255) { c = c & 0xFF; @@ -210,7 +210,7 @@ static void draw_character_map(display_info_t *display_info, void* restrict fb_a target_offset += WIDTH * BYTES_PER_PIXEL - (display_info->font_width * BYTES_PER_PIXEL); } // DEBUG_PRINT("%c", c > 31 ? c : 20); - // } + } // DEBUG_PRINT(" "); } // DEBUG_PRINT("\n"); @@ -226,7 +226,7 @@ static void clear_framebuffer() { static void draw_screen() { void *fb_addr = dji_display_get_fb_address(dji_display); // DJI has a backwards alpha channel - FF is transparent, 00 is opaque. - // memset(fb_addr, 0x000000FF, WIDTH * HEIGHT * BYTES_PER_PIXEL); + memset(fb_addr, 0x000000FF, WIDTH * HEIGHT * BYTES_PER_PIXEL); if (fakehd_is_enabled()) { fakehd_map_sd_character_map_to_hd(msp_character_map, msp_render_character_map); From ac52105385107216da7adb1b3981447f20684a1a Mon Sep 17 00:00:00 2001 From: Ben Lumley Date: Mon, 14 Aug 2023 09:31:27 +0100 Subject: [PATCH 6/7] Remove not working function --- jni/hw/dji_display.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/jni/hw/dji_display.c b/jni/hw/dji_display.c index 4ac8ace..9f40d6c 100644 --- a/jni/hw/dji_display.c +++ b/jni/hw/dji_display.c @@ -5,13 +5,6 @@ #define GOGGLES_V1_VOFFSET 575 #define GOGGLES_V2_VOFFSET 215 -static duss_result_t pop_func(duss_disp_instance_handle_t *disp_handle,duss_disp_plane_id_t plane_id, duss_frame_buffer_t *frame_buffer,void *user_ctx) { - dji_display_state_t *display_state = (dji_display_state_t *)user_ctx; - display_state->frame_drawn = 0; - printf("fbdebug pop_func\n"); - return 0; -} - dji_display_state_t *dji_display_state_alloc(uint8_t is_v2_goggles) { dji_display_state_t *display_state = calloc(1, sizeof(dji_display_state_t)); display_state->disp_instance_handle = (duss_disp_instance_handle_t *)calloc(1, sizeof(duss_disp_instance_handle_t)); @@ -98,11 +91,6 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_ printf("failed to acquire plane"); exit(0); } - res = duss_hal_display_register_frame_cycle_callback(display_state->disp_instance_handle, plane_id, &pop_func, display_state); - if (res != 0) { - printf("failed to register callback"); - exit(0); - } res = duss_hal_display_port_enable(display_state->disp_instance_handle, 3, 1); if (res != 0) { printf("failed to enable display port"); @@ -215,11 +203,6 @@ void dji_display_open_framebuffer_injected(dji_display_state_t *display_state, d DEBUG_PRINT("failed to acquire plane"); exit(0); } - res = duss_hal_display_register_frame_cycle_callback(display_state->disp_instance_handle, plane_id, &pop_func, 0); - if (res != 0) { - DEBUG_PRINT("failed to register callback"); - exit(0); - } res = duss_hal_display_plane_blending_set(display_state->disp_instance_handle, plane_id, display_state->pb_0); From ca06acaafd444263293b8b0d769ba9318c53b967 Mon Sep 17 00:00:00 2001 From: Ben Lumley Date: Mon, 14 Aug 2023 09:32:45 +0100 Subject: [PATCH 7/7] Version bump --- ipk/goggle/control/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipk/goggle/control/control b/ipk/goggle/control/control index c45d780..f8b5cfe 100644 --- a/ipk/goggle/control/control +++ b/ipk/goggle/control/control @@ -1,5 +1,5 @@ Package: msp-osd -Version: 0.10.1 +Version: 0.11.0 Maintainer: bri3d Description: MSP OSD service for the DJI HD FPV goggles. Architecture: pigeon-glasses