Skip to content

Commit 03a3e80

Browse files
authored
Merge pull request #131 from benlumley/framebuffer-alt
Change framebuffer handling to avoid the reboot
2 parents 03c1faf + ca06aca commit 03a3e80

21 files changed

+163
-167
lines changed

ipk/goggle/control/control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: msp-osd
2-
Version: 0.10.1
2+
Version: 0.11.0
33
Maintainer: bri3d
44
Description: MSP OSD service for the DJI HD FPV goggles.
55
Architecture: pigeon-glasses

jni/fakehd/fakehd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
void load_fakehd_config();
24
void fakehd_disable();
35
void fakehd_enable();

jni/hw/dji_display.c

Lines changed: 118 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
#include <stdlib.h>
22
#include "dji_display.h"
3+
#include "util/debug.h"
34

45
#define GOGGLES_V1_VOFFSET 575
56
#define GOGGLES_V2_VOFFSET 215
67

7-
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) {
8-
return 0;
9-
}
10-
118
dji_display_state_t *dji_display_state_alloc(uint8_t is_v2_goggles) {
129
dji_display_state_t *display_state = calloc(1, sizeof(dji_display_state_t));
1310
display_state->disp_instance_handle = (duss_disp_instance_handle_t *)calloc(1, sizeof(duss_disp_instance_handle_t));
1411
display_state->fb_0 = (duss_frame_buffer_t *)calloc(1,sizeof(duss_frame_buffer_t));
1512
display_state->fb_1 = (duss_frame_buffer_t *)calloc(1,sizeof(duss_frame_buffer_t));
1613
display_state->pb_0 = (duss_disp_plane_blending_t *)calloc(1, sizeof(duss_disp_plane_blending_t));
1714
display_state->is_v2_goggles = is_v2_goggles;
15+
display_state->frame_drawn = 0;
1816
return display_state;
1917
}
2018

@@ -27,7 +25,6 @@ void dji_display_state_free(dji_display_state_t *display_state) {
2725
}
2826

2927
void dji_display_close_framebuffer(dji_display_state_t *display_state) {
30-
3128
duss_hal_display_port_enable(display_state->disp_instance_handle, 3, 0);
3229
duss_hal_display_release_plane(display_state->disp_instance_handle, display_state->plane_id);
3330
duss_hal_display_close(display_state->disp_handle, &display_state->disp_instance_handle);
@@ -60,15 +57,15 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_
6057
// Blending algorithm 1 seems to work.
6158

6259
display_state->pb_0->blending_alg = 1;
63-
60+
6461
duss_hal_device_desc_t device_descs[3] = {
6562
{"/dev/dji_display", &duss_hal_attach_disp, &duss_hal_detach_disp, 0x0},
6663
{"/dev/ion", &duss_hal_attach_ion_mem, &duss_hal_detach_ion_mem, 0x0},
6764
{0,0,0,0}
6865
};
6966

7067
duss_hal_initialize(device_descs);
71-
68+
7269
res = duss_hal_device_open("/dev/dji_display",&hal_device_open_unk,&display_state->disp_handle);
7370
if (res != 0) {
7471
printf("failed to open dji_display device");
@@ -79,13 +76,13 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_
7976
printf("failed to open display hal");
8077
exit(0);
8178
}
82-
79+
8380
res = duss_hal_display_reset(display_state->disp_instance_handle);
8481
if (res != 0) {
8582
printf("failed to reset display");
8683
exit(0);
8784
}
88-
85+
8986
// No idea what this "plane mode" actually does but it's different on V2
9087
uint8_t acquire_plane_mode = display_state->is_v2_goggles ? 6 : 0;
9188

@@ -94,19 +91,14 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_
9491
printf("failed to acquire plane");
9592
exit(0);
9693
}
97-
res = duss_hal_display_register_frame_cycle_callback(display_state->disp_instance_handle, plane_id, &pop_func, 0);
98-
if (res != 0) {
99-
printf("failed to register callback");
100-
exit(0);
101-
}
10294
res = duss_hal_display_port_enable(display_state->disp_instance_handle, 3, 1);
10395
if (res != 0) {
10496
printf("failed to enable display port");
10597
exit(0);
10698
}
10799

108100
res = duss_hal_display_plane_blending_set(display_state->disp_instance_handle, plane_id, display_state->pb_0);
109-
101+
110102
if (res != 0) {
111103
printf("failed to set blending");
112104
exit(0);
@@ -155,7 +147,7 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_
155147
exit(0);
156148
}
157149
printf("second buffer VRAM mapped virtual memory is at %p : %p\n", display_state->fb1_virtual_addr, display_state->fb1_physical_addr);
158-
150+
159151
for(int i = 0; i < 2; i++) {
160152
duss_frame_buffer_t *fb = i ? display_state->fb_1 : display_state->fb_0;
161153
fb->buffer = i ? display_state->ion_buf_1 : display_state->ion_buf_0;
@@ -171,13 +163,117 @@ void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_
171163
}
172164
}
173165

174-
void dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb) {
175-
duss_frame_buffer_t *fb = which_fb ? display_state->fb_1 : display_state->fb_0;
176-
duss_hal_mem_sync(fb->buffer, 1);
177-
duss_hal_display_push_frame(display_state->disp_instance_handle, display_state->plane_id, fb);
166+
167+
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) {
168+
uint32_t hal_device_open_unk = 0;
169+
duss_result_t res = 0;
170+
display_state->disp_instance_handle = disp;
171+
display_state->ion_handle = ion_handle;
172+
display_state->plane_id = plane_id;
173+
174+
// PLANE BLENDING
175+
176+
display_state->pb_0->is_enable = 1;
177+
178+
// TODO just check hwid to figure this out. Not actually V1/V2 related but an HW version ID.
179+
180+
display_state->pb_0->voffset = GOGGLES_V1_VOFFSET;
181+
display_state->pb_0->hoffset = 0;
182+
183+
// On Goggles V1, the UI and video are in Z-Order 1. On Goggles V2, they're in Z-Order 4.
184+
// Unfortunately, this means we cannot draw below the DJI UI on Goggles V1. But, on Goggles V2 we get what we want.
185+
186+
display_state->pb_0->order = 2;
187+
188+
// Global alpha - disable as we want per pixel alpha.
189+
190+
display_state->pb_0->glb_alpha_en = 0;
191+
display_state->pb_0->glb_alpha_val = 0;
192+
193+
// These aren't documented. Blending algorithm 0 is employed for menus and 1 for screensaver.
194+
195+
display_state->pb_0->blending_alg = 1;
196+
197+
// No idea what this "plane mode" actually does but it's different on V2
198+
uint8_t acquire_plane_mode = display_state->is_v2_goggles ? 6 : 0;
199+
200+
DEBUG_PRINT("acquire plane\n");
201+
res = duss_hal_display_aquire_plane(display_state->disp_instance_handle,acquire_plane_mode,&plane_id);
202+
if (res != 0) {
203+
DEBUG_PRINT("failed to acquire plane");
204+
exit(0);
205+
}
206+
207+
res = duss_hal_display_plane_blending_set(display_state->disp_instance_handle, plane_id, display_state->pb_0);
208+
209+
if (res != 0) {
210+
DEBUG_PRINT("failed to set blending");
211+
exit(0);
212+
}
213+
DEBUG_PRINT("alloc ion buf\n");
214+
res = duss_hal_mem_alloc(display_state->ion_handle,&display_state->ion_buf_0,0x473100,0x400,0,0x17);
215+
if (res != 0) {
216+
DEBUG_PRINT("failed to allocate VRAM");
217+
exit(0);
218+
}
219+
res = duss_hal_mem_map(display_state->ion_buf_0, &display_state->fb0_virtual_addr);
220+
if (res != 0) {
221+
DEBUG_PRINT("failed to map VRAM");
222+
exit(0);
223+
}
224+
res = duss_hal_mem_get_phys_addr(display_state->ion_buf_0, &display_state->fb0_physical_addr);
225+
if (res != 0) {
226+
DEBUG_PRINT("failed to get FB0 phys addr");
227+
exit(0);
228+
}
229+
DEBUG_PRINT("first buffer VRAM mapped virtual memory is at %p : %p\n", display_state->fb0_virtual_addr, display_state->fb0_physical_addr);
230+
231+
res = duss_hal_mem_alloc(display_state->ion_handle,&display_state->ion_buf_1,0x473100,0x400,0,0x17);
232+
if (res != 0) {
233+
DEBUG_PRINT("failed to allocate FB1 VRAM");
234+
exit(0);
235+
}
236+
res = duss_hal_mem_map(display_state->ion_buf_1,&display_state->fb1_virtual_addr);
237+
if (res != 0) {
238+
DEBUG_PRINT("failed to map FB1 VRAM");
239+
exit(0);
240+
}
241+
res = duss_hal_mem_get_phys_addr(display_state->ion_buf_1, &display_state->fb1_physical_addr);
242+
if (res != 0) {
243+
DEBUG_PRINT("failed to get FB1 phys addr");
244+
exit(0);
245+
}
246+
DEBUG_PRINT("second buffer VRAM mapped virtual memory is at %p : %p\n", display_state->fb1_virtual_addr, display_state->fb1_physical_addr);
247+
248+
for(int i = 0; i < 2; i++) {
249+
duss_frame_buffer_t *fb = i ? display_state->fb_1 : display_state->fb_0;
250+
fb->buffer = i ? display_state->ion_buf_1 : display_state->ion_buf_0;
251+
fb->pixel_format = display_state->is_v2_goggles ? DUSS_PIXFMT_RGBA8888_GOGGLES_V2 : DUSS_PIXFMT_RGBA8888; // 20012 instead on V2
252+
fb->frame_id = i;
253+
fb->planes[0].bytes_per_line = 0x1680;
254+
fb->planes[0].offset = 0;
255+
fb->planes[0].plane_height = 810;
256+
fb->planes[0].bytes_written = 0x473100;
257+
fb->width = 1440;
258+
fb->height = 810;
259+
fb->plane_count = 1;
260+
}
261+
}
262+
263+
void dji_display_push_frame(dji_display_state_t *display_state) {
264+
if (display_state->frame_drawn == 0) {
265+
duss_frame_buffer_t *fb = display_state->fb_0;
266+
duss_hal_mem_sync(fb->buffer, 1);
267+
display_state->frame_drawn = 1;
268+
printf("fbdebug pushing frame\n");
269+
duss_hal_display_push_frame(display_state->disp_instance_handle, display_state->plane_id, fb);
270+
} else {
271+
DEBUG_PRINT("!!! Dropped frame due to pending frame push!\n");
272+
}
273+
memcpy(display_state->fb0_virtual_addr, display_state->fb1_virtual_addr, sizeof(uint32_t) * 1440 * 810);
178274
}
179275

180-
void *dji_display_get_fb_address(dji_display_state_t *display_state, uint8_t which_fb) {
181-
return which_fb ? display_state->fb1_virtual_addr : display_state->fb0_virtual_addr;
276+
void *dji_display_get_fb_address(dji_display_state_t *display_state) {
277+
return display_state->fb1_virtual_addr;
182278
}
183279

jni/hw/dji_display.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#ifndef DJI_DISPLAY_H
2-
#define DJI_DISPLAY_H
1+
#pragma once
32
#include "duml_hal.h"
43

54
typedef struct dji_display_state_s {
@@ -18,12 +17,13 @@ typedef struct dji_display_state_s {
1817
duss_frame_buffer_t *fb_1;
1918
duss_disp_plane_blending_t *pb_0;
2019
uint8_t is_v2_goggles;
20+
uint8_t frame_drawn;
2121
} dji_display_state_t;
2222

23-
void dji_display_push_frame(dji_display_state_t *display_state, uint8_t which_fb);
23+
void dji_display_push_frame(dji_display_state_t *display_state);
2424
void dji_display_open_framebuffer(dji_display_state_t *display_state, duss_disp_plane_id_t plane_id);
25+
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);
2526
void dji_display_close_framebuffer(dji_display_state_t *display_state);
2627
dji_display_state_t *dji_display_state_alloc(uint8_t is_v2_goggles);
2728
void dji_display_state_free(dji_display_state_t *display_state);
28-
void *dji_display_get_fb_address(dji_display_state_t *display_state, uint8_t which_fb);
29-
#endif
29+
void *dji_display_get_fb_address(dji_display_state_t *display_state);

jni/hw/dji_radio_shm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
2+
#pragma once
13
#include <stdint.h>
24

35
#define RTOS_SHM_ADDRESS 0xfffc1000

jni/hw/dji_services.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#pragma once
2+
13
void dji_stop_goggles(int is_v2);
24
void dji_start_goggles(int is_v2);
35
int dji_goggles_are_v2();

jni/hw/duml_hal.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#ifndef DUML_HAL_H
2-
#define DUML_HAL_H
1+
#pragma once
32
#include <stdint.h>
43

54
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);
259258
duss_result_t duss_hal_attach_ion_mem(char *param_1,duss_hal_obj **param_2);
260259
duss_result_t duss_hal_detach_ion_mem();
261260
duss_result_t duss_hal_detach_disp();
262-
#endif

jni/msp/msp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#pragma once
12
#include <stdint.h>
23

34
#define MSP_CMD_API_VERSION 1

jni/msp/msp_displayport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
#pragma once
12
#include <stdint.h>
3+
#include "msp.h"
24

35
typedef enum {
46
MSP_DISPLAYPORT_KEEPALIVE,

jni/msp_displayport_mux.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "net/serial.h"
1414
#include "msp/msp.h"
1515
#include "msp/msp_displayport.h"
16+
#include "util/debug.h"
1617
#include "util/time_util.h"
1718
#include "util/fs_util.h"
1819

@@ -42,12 +43,6 @@ enum {
4243
// The Betaflight MSP minor version in which MSP DisplayPort sizing is supported.
4344
#define MSP_DISPLAY_SIZE_VERSION 45
4445

45-
#ifdef DEBUG
46-
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, fmt, ## args)
47-
#else
48-
#define DEBUG_PRINT(fmt, args...)
49-
#endif
50-
5146
typedef struct msp_cache_entry_s {
5247
struct timespec time;
5348
msp_msg_t message;

0 commit comments

Comments
 (0)