Skip to content
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

OLED burnin and static image protection #342

Merged
merged 2 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/core/osd.c
Original file line number Diff line number Diff line change
Expand Up @@ -686,9 +686,9 @@ static void create_osd_scr(void) {
lv_obj_clear_flag(scr_main, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_clear_flag(scr_osd[i], LV_OBJ_FLAG_SCROLLABLE);
if (i)
lv_obj_set_size(scr_osd[i], 1920, 1080);
lv_obj_set_size(scr_osd[i], DRAW_HOR_RES_FHD, DRAW_VER_RES_FHD);
else
lv_obj_set_size(scr_osd[i], 1280, 720);
lv_obj_set_size(scr_osd[i], DRAW_HOR_RES_HD, DRAW_VER_RES_HD);
lv_obj_add_flag(scr_osd[i], LV_OBJ_FLAG_HIDDEN);
lv_obj_add_style(scr_osd[i], &style_osd, 0);
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const setting_t g_setting_defaults = {
.no_dial = 0,
},
.osd = {
.orbit = 2,
.embedded_mode = EMBEDDED_4x3,
.startup_visibility = SETTING_OSD_SHOW_AT_STARTUP_SHOW,
.is_visible = true,
Expand Down Expand Up @@ -310,6 +311,7 @@ void settings_load(void) {
g_setting.autoscan.last_source = ini_getl("autoscan", "last_source", g_setting_defaults.autoscan.last_source, SETTING_INI);

// osd
g_setting.osd.orbit = ini_getl("osd", "orbit", g_setting_defaults.osd.orbit, SETTING_INI);
g_setting.osd.embedded_mode = ini_getl("osd", "embedded_mode", g_setting_defaults.osd.embedded_mode, SETTING_INI);
g_setting.osd.startup_visibility = ini_getl("osd", "startup_visibility", g_setting_defaults.osd.startup_visibility, SETTING_INI);

Expand Down
5 changes: 3 additions & 2 deletions src/core/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ typedef struct {
typedef enum {
EMBEDDED_4x3,
EMBEDDED_16x9
} setting_embedded_mode_t;
} setting_osd_embedded_mode_t;

typedef enum {
SETTING_OSD_SHOW_AT_STARTUP_SHOW,
Expand Down Expand Up @@ -144,7 +144,8 @@ typedef enum {
} osd_goggle_element_e;

typedef struct {
setting_embedded_mode_t embedded_mode;
int orbit;
setting_osd_embedded_mode_t embedded_mode;
setting_osd_show_at_startup_t startup_visibility;
bool is_visible;
setting_osd_goggle_element_t element[OSD_GOGGLE_NUM];
Expand Down
6 changes: 5 additions & 1 deletion src/ui/page_focus_chart.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <stdio.h>

#include "core/osd.h"
#include "core/settings.h"
#include "ui/ui_porting.h"

static lv_obj_t *focus_chart_img;

Expand Down Expand Up @@ -32,7 +34,7 @@ lv_obj_t *page_focus_chart_create(lv_obj_t *parent, panel_arr_t *arr) {
lv_obj_add_flag(focus_chart_img, LV_OBJ_FLAG_FLOATING);
lv_obj_clear_flag(focus_chart_img, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_pos(focus_chart_img, 0, 0);
lv_obj_set_size(focus_chart_img, 1920, 1080);
lv_obj_set_size(focus_chart_img, DRAW_HOR_RES_FHD, DRAW_VER_RES_FHD);

char filename[128];
osd_resource_path(filename, "%s", OSD_RESOURCE_720, FOCUS_CHART_IMG);
Expand All @@ -48,10 +50,12 @@ static void page_focus_chart_exit() {
static void page_focus_chart_enter() {
lv_obj_move_foreground(focus_chart_img);
lv_obj_clear_flag(focus_chart_img, LV_OBJ_FLAG_HIDDEN);
lvgl_screen_orbit(false);
}

static void page_focus_chart_on_click(uint8_t key, int sel) {
lv_obj_add_flag(focus_chart_img, LV_OBJ_FLAG_HIDDEN);
lvgl_screen_orbit(g_setting.osd.orbit > 0);
submenu_exit();
}

Expand Down
17 changes: 16 additions & 1 deletion src/ui/page_osd.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
#include "driver/hardware.h"
#include "page_common.h"
#include "ui/ui_osd_element_pos.h"
#include "ui/ui_porting.h"
#include "ui/ui_style.h"
#include "util/math.h"

enum {
ROW_OSD_MODE = 0,
ROW_OSD_ORBIT = 0,
ROW_OSD_MODE,
ROW_OSD_STARTUP_VISIBILITY,
ROW_ADJUST_OSD_ELEMENTS,
ROW_BACK,
Expand All @@ -28,6 +30,7 @@ enum {
static lv_coord_t col_dsc[] = {160, 180, 160, 160, 120, 160, LV_GRID_TEMPLATE_LAST};
static lv_coord_t row_dsc[] = {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, LV_GRID_TEMPLATE_LAST};

static btn_group_t btn_group_osd_orbit;
static btn_group_t btn_group_osd_mode;
static btn_group_t btn_group_osd_startup_visibility;

Expand Down Expand Up @@ -58,6 +61,7 @@ static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) {

// create menu entries
create_label_item(cont, "Adjust OSD Elements", 1, ROW_ADJUST_OSD_ELEMENTS, 1);
create_btn_group_item(&btn_group_osd_orbit, cont, 3, "OSD Orbit", "Off", "Min", "Max", "", ROW_OSD_ORBIT);
create_btn_group_item(&btn_group_osd_mode, cont, 2, "OSD Mode", "4x3", "16x9", "", "", ROW_OSD_MODE);
create_btn_group_item(&btn_group_osd_startup_visibility, cont, 3, "At Startup", "Show", "Hide", "Last", "", ROW_OSD_STARTUP_VISIBILITY);
create_label_item(cont, "< Back", 1, ROW_BACK, 1);
Expand All @@ -73,9 +77,13 @@ static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) {
LV_GRID_ALIGN_START, ROW_USER_HINT, 2);

// set ui values from settings
btn_group_set_sel(&btn_group_osd_orbit, g_setting.osd.orbit);
btn_group_set_sel(&btn_group_osd_mode, g_setting.osd.embedded_mode);
btn_group_set_sel(&btn_group_osd_startup_visibility, g_setting.osd.startup_visibility);

// Set OSD orbit
lvgl_screen_orbit(g_setting.osd.orbit > 0);

return page;
}

Expand Down Expand Up @@ -131,6 +139,13 @@ static void on_click(uint8_t key, int sel) {
osd_update_element_positions();
break;

case ROW_OSD_ORBIT:
btn_group_toggle_sel(&btn_group_osd_orbit);
g_setting.osd.orbit = btn_group_get_sel(&btn_group_osd_orbit);
ini_putl("osd", "orbit", g_setting.osd.orbit, SETTING_INI);
lvgl_screen_orbit(g_setting.osd.orbit > 0);
break;

default:
break;
}
Expand Down
146 changes: 107 additions & 39 deletions src/ui/ui_porting.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <log/log.h>

#include "../core/common.hh"
#include "../core/settings.h"
#include "fbtools.h"
#include "lvgl/lvgl.h"

Expand All @@ -19,42 +20,100 @@ SDL_Texture *texture = NULL;
#endif
#endif

#define DISP_HOR_RES (1920)
#define DISP_VER_RES (1080)
typedef enum {
ORBIT_NONE = 0x00,
ORBIT_D = 0x01,
ORBIT_R = 0x02,
ORBIT_U = 0x04,
ORBIT_L = 0x08,
ORBIT_FLUSH = 0x10,
} orbit_state_t;

FBDEV fbdev;

static int h_resolution = DISP_HOR_RES;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t disp_buf[DISP_HOR_RES * DISP_VER_RES * 4];
static lv_color_t disp_buf[DRAW_HOR_RES_FHD * DRAW_VER_RES_FHD * 4];
static lv_disp_drv_t disp_drv;
static orbit_state_t disp_orbit_state = ORBIT_NONE;
static int disp_orbit_x, disp_orbit_y;
static lv_disp_t *disp;

static void hdz_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
static int orbit_flush = 0;

// Manipulates the orbiting speed
if (++orbit_flush % 500 == 0) {
disp_orbit_state |= ORBIT_FLUSH;
}

#ifndef EMULATOR_BUILD
for (lv_coord_t y = area->y1; y <= area->y2; y++) {
fbdev.fb_mem_offset = (y * h_resolution + area->x1) * 4;
fbdev.fb_fix.smem_len = 4 * (area->x2 - area->x1 + 1);
for (lv_coord_t y = area->y1 + disp_orbit_y; y <= area->y2; y++) {
fbdev.fb_mem_offset = (y * (disp_drv.hor_res - DISP_OVERSCAN) + disp_orbit_x) * 4;
fbdev.fb_fix.smem_len = 4 * (area->x2 - area->x1 + 1 - DISP_OVERSCAN);
memcpy(fbdev.fb_mem + fbdev.fb_mem_offset, ((char *)color_p), fbdev.fb_fix.smem_len);
color_p += (area->x2 - area->x1 + 1);
}

fb_sync(&fbdev);
#else
SDL_Rect r;
r.x = area->x1;
r.y = area->y1;
r.w = area->x2 - area->x1 + 1;
r.h = area->y2 - area->y1 + 1;
SDL_UpdateTexture(texture, &r, color_p, r.w * ((LV_COLOR_DEPTH + 7) / 8));
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_Rect
src = {
.x = 0,
.y = 0,
.w = disp_drv.hor_res,
.h = disp_drv.ver_res,
},
dst = {
.x = 0,
.y = 0,
.w = disp_drv.hor_res - DISP_OVERSCAN,
.h = disp_drv.ver_res - DISP_OVERSCAN,
};

SDL_UpdateTexture(texture, &src, color_p, disp_drv.hor_res * ((LV_COLOR_DEPTH + 7) / 8));
src.x = disp_orbit_x;
src.w = dst.w;
src.y = disp_orbit_y;
src.h = dst.h;
SDL_RenderCopy(renderer, texture, &src, &dst);
SDL_RenderPresent(renderer);
#endif

if (disp_orbit_state & ORBIT_FLUSH) {
disp_orbit_state &= ~ORBIT_FLUSH;

int pixels = 1 << g_setting.osd.orbit;

if (disp_orbit_state & ORBIT_D && disp_orbit_y < pixels) {
disp_orbit_y += 1;
if (disp_orbit_y == pixels) {
disp_orbit_state &= ~ORBIT_D;
disp_orbit_state |= ORBIT_R;
}
} else if (disp_orbit_state & ORBIT_R && disp_orbit_x < pixels) {
disp_orbit_x += 1;
if (disp_orbit_x == pixels) {
disp_orbit_state &= ~ORBIT_R;
disp_orbit_state |= ORBIT_U;
}
} else if (disp_orbit_state & ORBIT_U && disp_orbit_y > 0) {
disp_orbit_y -= 1;
if (disp_orbit_y == 0) {
disp_orbit_state &= !ORBIT_U;
disp_orbit_state |= ORBIT_L;
}
} else if (disp_orbit_state & ORBIT_L && disp_orbit_x > 0) {
disp_orbit_x -= 1;
if (disp_orbit_x == 0) {
disp_orbit_state &= ~ORBIT_L;
disp_orbit_state |= ORBIT_D;
}
}
}

lv_disp_flush_ready(disp);
}

int lvgl_init_porting(void) {
int lvgl_init_porting() {
#ifndef EMULATOR_BUILD
memset(&fbdev, 0x0, sizeof(FBDEV));
strncpy(fbdev.dev, "/dev/fb0", sizeof(fbdev.dev));
Expand All @@ -64,60 +123,69 @@ int lvgl_init_porting(void) {
}
LOGI("register disp drv");

lv_disp_draw_buf_init(&draw_buf, disp_buf, NULL, DISP_HOR_RES * DISP_VER_RES * 4);
lv_disp_draw_buf_init(&draw_buf, disp_buf, NULL, DRAW_HOR_RES_FHD * DRAW_VER_RES_FHD * 4);

lv_disp_drv_init(&disp_drv);
#else
SDL_InitSubSystem(SDL_INIT_VIDEO);

window = SDL_CreateWindow(WINDOW_NAME,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
DISP_HOR_RES, DISP_VER_RES, 0);
DISP_HOR_RES_FHD, DISP_VER_RES_FHD, 0);

renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);

texture = SDL_CreateTexture(renderer,
(LV_COLOR_DEPTH == 32) ? (SDL_PIXELFORMAT_ARGB8888) : (SDL_PIXELFORMAT_RGB565),
SDL_TEXTUREACCESS_STREAMING,
DISP_HOR_RES,
DISP_VER_RES);
DRAW_HOR_RES_FHD,
DRAW_VER_RES_FHD);

fb1 = malloc(DISP_HOR_RES * DISP_VER_RES * ((LV_COLOR_DEPTH + 7) / 8));
fb2 = malloc(DISP_HOR_RES * DISP_VER_RES * ((LV_COLOR_DEPTH + 7) / 8));
fb1 = malloc(DRAW_HOR_RES_FHD * DRAW_VER_RES_FHD * ((LV_COLOR_DEPTH + 7) / 8));
fb2 = malloc(DRAW_HOR_RES_FHD * DRAW_VER_RES_FHD * ((LV_COLOR_DEPTH + 7) / 8));

lv_disp_draw_buf_init(&draw_buf, fb1, fb2, DISP_HOR_RES * DISP_VER_RES);
lv_disp_draw_buf_init(&draw_buf, fb1, fb2, DRAW_HOR_RES_FHD * DRAW_VER_RES_FHD);
lv_disp_drv_init(&disp_drv);

disp_drv.full_refresh = 1;
#endif

disp_drv.full_refresh = 1;
disp_drv.flush_cb = hdz_disp_flush;
disp_drv.draw_buf = &draw_buf;
disp_drv.hor_res = DISP_HOR_RES;
disp_drv.ver_res = DISP_VER_RES;
disp_drv.hor_res = DRAW_HOR_RES_FHD;
disp_drv.ver_res = DRAW_VER_RES_FHD;
disp = lv_disp_drv_register(&disp_drv);

return 0;
}

int lvgl_switch_to_720p(void) {
lv_disp_draw_buf_init(&draw_buf, disp_buf, NULL, 1280 * 720 * 4);
int lvgl_switch_to_720p() {
lvgl_screen_orbit(false);
lv_disp_draw_buf_init(&draw_buf, disp_buf, NULL, DRAW_HOR_RES_HD * DRAW_VER_RES_HD * 4);
disp_drv.draw_buf = &draw_buf;
disp_drv.hor_res = 1280;
disp_drv.ver_res = 720;
disp_drv.hor_res = DRAW_HOR_RES_HD;
disp_drv.ver_res = DRAW_VER_RES_HD;
lv_disp_drv_update(disp, &disp_drv);

h_resolution = 1280;
lvgl_screen_orbit(g_setting.osd.orbit > 0);
return 0;
}

int lvgl_switch_to_1080p(void) {
lv_disp_draw_buf_init(&draw_buf, disp_buf, NULL, 1920 * 1080 * 4);
int lvgl_switch_to_1080p() {
lvgl_screen_orbit(false);
lv_disp_draw_buf_init(&draw_buf, disp_buf, NULL, DRAW_HOR_RES_FHD * DRAW_VER_RES_FHD * 4);
disp_drv.draw_buf = &draw_buf;
disp_drv.hor_res = 1920;
disp_drv.ver_res = 1080;
disp_drv.hor_res = DRAW_HOR_RES_FHD;
disp_drv.ver_res = DRAW_VER_RES_FHD;
lv_disp_drv_update(disp, &disp_drv);

h_resolution = 1920;
lvgl_screen_orbit(g_setting.osd.orbit > 0);
return 0;
}

void lvgl_screen_orbit(bool enable) {
if (enable) {
disp_orbit_state = ORBIT_D;
} else {
disp_orbit_state = ORBIT_NONE;
disp_orbit_x = 0;
disp_orbit_y = 0;
}
}
17 changes: 14 additions & 3 deletions src/ui/ui_porting.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,19 @@

#include <stdbool.h>

int lvgl_init_porting(void);
int lvgl_switch_to_720p(void);
int lvgl_switch_to_1080p(void);
#define DISP_OVERSCAN 8
#define DISP_HOR_RES_HD 1280
#define DISP_VER_RES_HD 720
#define DRAW_HOR_RES_HD (DISP_HOR_RES_HD + DISP_OVERSCAN)
#define DRAW_VER_RES_HD (DISP_VER_RES_HD + DISP_OVERSCAN)
#define DISP_HOR_RES_FHD 1920
#define DISP_VER_RES_FHD 1080
#define DRAW_HOR_RES_FHD (DISP_HOR_RES_FHD + DISP_OVERSCAN)
#define DRAW_VER_RES_FHD (DISP_VER_RES_FHD + DISP_OVERSCAN)

int lvgl_init_porting();
int lvgl_switch_to_720p();
int lvgl_switch_to_1080p();
void lvgl_screen_orbit(bool enable);

#endif
3 changes: 2 additions & 1 deletion src/ui/ui_statusbar.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "ui/page_playback.h"
#include "ui/page_storage.h"
#include "ui/page_wifi.h"
#include "ui/ui_porting.h"
#include "ui/ui_style.h"

///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -45,7 +46,7 @@ int statusbar_init(void) {

/*Create a container with grid*/
lv_obj_t *cont = lv_obj_create(lv_scr_act());
lv_obj_set_size(cont, 1920, 96);
lv_obj_set_size(cont, DRAW_HOR_RES_FHD, 96);
lv_obj_set_pos(cont, 0, 0);
lv_obj_set_layout(cont, LV_LAYOUT_GRID);
lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
Expand Down