Skip to content

Commit

Permalink
Merge pull request #131 from benlumley/framebuffer-alt
Browse files Browse the repository at this point in the history
Change framebuffer handling to avoid the reboot
  • Loading branch information
j005u authored Aug 15, 2023
2 parents 03c1faf + ca06aca commit 03a3e80
Show file tree
Hide file tree
Showing 21 changed files with 163 additions and 167 deletions.
2 changes: 1 addition & 1 deletion ipk/goggle/control/control
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 2 additions & 0 deletions jni/fakehd/fakehd.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

void load_fakehd_config();
void fakehd_disable();
void fakehd_enable();
Expand Down
140 changes: 118 additions & 22 deletions jni/hw/dji_display.c
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
#include <stdlib.h>
#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) {
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));
display_state->fb_0 = (duss_frame_buffer_t *)calloc(1,sizeof(duss_frame_buffer_t));
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_drawn = 0;
return display_state;
}

Expand All @@ -27,7 +25,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);
Expand Down Expand Up @@ -60,15 +57,15 @@ 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},
{0,0,0,0}
};

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");
Expand All @@ -79,13 +76,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;

Expand All @@ -94,19 +91,14 @@ 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);
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");
exit(0);
}

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);
Expand Down Expand Up @@ -155,7 +147,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;
Expand All @@ -171,13 +163,117 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_
}
}

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);

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_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) {
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_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");
}
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, uint8_t which_fb) {
return which_fb ? display_state->fb1_virtual_addr : display_state->fb0_virtual_addr;
void *dji_display_get_fb_address(dji_display_state_t *display_state) {
return display_state->fb1_virtual_addr;
}

10 changes: 5 additions & 5 deletions jni/hw/dji_display.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef DJI_DISPLAY_H
#define DJI_DISPLAY_H
#pragma once
#include "duml_hal.h"

typedef struct dji_display_state_s {
Expand All @@ -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_drawn;
} dji_display_state_t;

void 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);
#endif
void *dji_display_get_fb_address(dji_display_state_t *display_state);
2 changes: 2 additions & 0 deletions jni/hw/dji_radio_shm.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

#pragma once
#include <stdint.h>

#define RTOS_SHM_ADDRESS 0xfffc1000
Expand Down
2 changes: 2 additions & 0 deletions jni/hw/dji_services.h
Original file line number Diff line number Diff line change
@@ -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();
4 changes: 1 addition & 3 deletions jni/hw/duml_hal.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef DUML_HAL_H
#define DUML_HAL_H
#pragma once
#include <stdint.h>

typedef int32_t duss_result_t;
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions jni/msp/msp.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include <stdint.h>

#define MSP_CMD_API_VERSION 1
Expand Down
2 changes: 2 additions & 0 deletions jni/msp/msp_displayport.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#pragma once
#include <stdint.h>
#include "msp.h"

typedef enum {
MSP_DISPLAYPORT_KEEPALIVE,
Expand Down
7 changes: 1 addition & 6 deletions jni/msp_displayport_mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions jni/net/network.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
#pragma once

int connect_to_server(char *address, int port);
int bind_socket(int port);
2 changes: 2 additions & 0 deletions jni/net/serial.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

#include <termios.h>

int open_serial_port(const char *device, speed_t baudrate);
Expand Down
2 changes: 2 additions & 0 deletions jni/osd.h
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
Loading

0 comments on commit 03a3e80

Please sign in to comment.