mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 11:21:23 +00:00
nyx: utilize VIC for hw rotation
It completely removes the waterfall-like slow rendering on T210B01 and speeds up even more rendering on T210.
This commit is contained in:
parent
9d889e2c3e
commit
833f060c7b
3 changed files with 72 additions and 27 deletions
|
@ -86,9 +86,30 @@ gui_status_bar_ctx status_bar;
|
||||||
|
|
||||||
static void _nyx_disp_init()
|
static void _nyx_disp_init()
|
||||||
{
|
{
|
||||||
|
vic_surface_t vic_sfc;
|
||||||
|
vic_sfc.src_buf = NYX_FB2_ADDRESS;
|
||||||
|
vic_sfc.dst_buf = NYX_FB_ADDRESS;
|
||||||
|
vic_sfc.width = 1280;
|
||||||
|
vic_sfc.height = 720;
|
||||||
|
vic_sfc.pix_fmt = VIC_PIX_FORMAT_X8R8G8B8;
|
||||||
|
vic_sfc.rotation = VIC_ROTATION_270;
|
||||||
|
|
||||||
|
// Set hardware rotation via VIC.
|
||||||
|
vic_init();
|
||||||
|
vic_set_surface(&vic_sfc);
|
||||||
|
|
||||||
|
// Turn off backlight to hide the transition.
|
||||||
display_backlight_brightness(0, 1000);
|
display_backlight_brightness(0, 1000);
|
||||||
display_init_framebuffer_pitch_inv();
|
|
||||||
|
// Rotate and copy the first frame.
|
||||||
|
vic_compose();
|
||||||
|
|
||||||
|
// Switch to new window configuration.
|
||||||
|
display_init_framebuffer_pitch_vic();
|
||||||
|
|
||||||
|
// Enable logging on window D.
|
||||||
display_init_framebuffer_log();
|
display_init_framebuffer_log();
|
||||||
|
// Switch back the backlight.
|
||||||
display_backlight_brightness(h_cfg.backlight - 20, 1000);
|
display_backlight_brightness(h_cfg.backlight - 20, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,11 +131,11 @@ static void _save_log_to_bmp(char *fname)
|
||||||
if (!log_changed)
|
if (!log_changed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const u32 file_size = 0x334000 + 0x36;
|
const u32 file_size = LOG_FB_SZ + 0x36;
|
||||||
u8 *bitmap = malloc(file_size);
|
u8 *bitmap = malloc(file_size);
|
||||||
|
|
||||||
// Reconstruct FB for bottom-top, landscape bmp.
|
// Reconstruct FB for bottom-top, landscape bmp. Rotation: 656x1280 -> 1280x656.
|
||||||
u32 *fb = malloc(0x334000);
|
u32 *fb = malloc(LOG_FB_SZ);
|
||||||
for (int x = 1279; x > - 1; x--)
|
for (int x = 1279; x > - 1; x--)
|
||||||
{
|
{
|
||||||
for (int y = 655; y > -1; y--)
|
for (int y = 655; y > -1; y--)
|
||||||
|
@ -123,7 +144,7 @@ static void _save_log_to_bmp(char *fname)
|
||||||
|
|
||||||
manual_system_maintenance(true);
|
manual_system_maintenance(true);
|
||||||
|
|
||||||
memcpy(bitmap + 0x36, fb, 0x334000);
|
memcpy(bitmap + 0x36, fb, LOG_FB_SZ);
|
||||||
|
|
||||||
typedef struct _bmp_t
|
typedef struct _bmp_t
|
||||||
{
|
{
|
||||||
|
@ -155,7 +176,7 @@ static void _save_log_to_bmp(char *fname)
|
||||||
bmp->planes = 1;
|
bmp->planes = 1;
|
||||||
bmp->pxl_bits = 32;
|
bmp->pxl_bits = 32;
|
||||||
bmp->comp = 0;
|
bmp->comp = 0;
|
||||||
bmp->img_size = 0x334000;
|
bmp->img_size = LOG_FB_SZ;
|
||||||
bmp->res_h = 2834;
|
bmp->res_h = 2834;
|
||||||
bmp->res_v = 2834;
|
bmp->res_v = 2834;
|
||||||
bmp->rsvd2 = 0;
|
bmp->rsvd2 = 0;
|
||||||
|
@ -179,16 +200,20 @@ static void _save_fb_to_bmp()
|
||||||
if (do_reload)
|
if (do_reload)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const u32 file_size = 0x384000 + 0x36;
|
// Invalidate data.
|
||||||
u8 *bitmap = malloc(file_size);
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||||
u32 *fb = malloc(0x384000);
|
|
||||||
u32 *fb_ptr = (u32 *)NYX_FB_ADDRESS;
|
|
||||||
|
|
||||||
// Reconstruct FB for bottom-top, landscape bmp.
|
const u32 file_size = NYX_FB_SZ + 0x36;
|
||||||
for (u32 x = 0; x < 1280; x++)
|
u8 *bitmap = malloc(file_size);
|
||||||
{
|
u32 *fb = malloc(NYX_FB_SZ);
|
||||||
|
u32 *fb_ptr = (u32 *)NYX_FB2_ADDRESS;
|
||||||
|
u32 line_bytes = 1280 * sizeof(u32);
|
||||||
|
|
||||||
|
// Reconstruct FB for bottom-top, landscape bmp. No rotation.
|
||||||
for (int y = 719; y > -1; y--)
|
for (int y = 719; y > -1; y--)
|
||||||
fb[y * 1280 + x] = *fb_ptr++;
|
{
|
||||||
|
memcpy(&fb[y * 1280], fb_ptr, line_bytes);
|
||||||
|
fb_ptr += line_bytes / sizeof(u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create notification box.
|
// Create notification box.
|
||||||
|
@ -206,7 +231,7 @@ static void _save_fb_to_bmp()
|
||||||
|
|
||||||
manual_system_maintenance(true);
|
manual_system_maintenance(true);
|
||||||
|
|
||||||
memcpy(bitmap + 0x36, fb, 0x384000);
|
memcpy(bitmap + 0x36, fb, NYX_FB_SZ);
|
||||||
|
|
||||||
typedef struct _bmp_t
|
typedef struct _bmp_t
|
||||||
{
|
{
|
||||||
|
@ -238,7 +263,7 @@ static void _save_fb_to_bmp()
|
||||||
bmp->planes = 1;
|
bmp->planes = 1;
|
||||||
bmp->pxl_bits = 32;
|
bmp->pxl_bits = 32;
|
||||||
bmp->comp = 0;
|
bmp->comp = 0;
|
||||||
bmp->img_size = 0x384000;
|
bmp->img_size = NYX_FB_SZ;
|
||||||
bmp->res_h = 2834;
|
bmp->res_h = 2834;
|
||||||
bmp->res_v = 2834;
|
bmp->res_v = 2834;
|
||||||
bmp->rsvd2 = 0;
|
bmp->rsvd2 = 0;
|
||||||
|
@ -287,8 +312,12 @@ static void _save_fb_to_bmp()
|
||||||
|
|
||||||
static void _disp_fb_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t *color_p)
|
static void _disp_fb_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t *color_p)
|
||||||
{
|
{
|
||||||
// Draw to framebuffer.
|
// Draw to intermediate non-rotated framebuffer.
|
||||||
gfx_set_rect_land_pitch((u32 *)NYX_FB_ADDRESS, (u32 *)color_p, 720, x1, y1, x2, y2); //pitch
|
gfx_set_rect_pitch((u32 *)NYX_FB2_ADDRESS, (u32 *)color_p, 1280, x1, y1, x2, y2);
|
||||||
|
|
||||||
|
// Rotate and copy to visible framebuffer.
|
||||||
|
if (disp_init_done)
|
||||||
|
vic_compose();
|
||||||
|
|
||||||
// Check if display init was done. If it's the first big draw, init.
|
// Check if display init was done. If it's the first big draw, init.
|
||||||
if (!disp_init_done && ((x2 - x1 + 1) > 600))
|
if (!disp_init_done && ((x2 - x1 + 1) > 600))
|
||||||
|
|
|
@ -173,13 +173,16 @@ void gfx_con_getpos(u32 *x, u32 *y)
|
||||||
*y = gfx_con.y;
|
*y = gfx_con.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gfx_column = 0;
|
||||||
void gfx_con_setpos(u32 x, u32 y)
|
void gfx_con_setpos(u32 x, u32 y)
|
||||||
{
|
{
|
||||||
gfx_con.x = x;
|
gfx_con.x = x;
|
||||||
gfx_con.y = y;
|
gfx_con.y = y;
|
||||||
|
|
||||||
|
if (!x)
|
||||||
|
gfx_column = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gfx_column = 0;
|
|
||||||
void gfx_putc(char c)
|
void gfx_putc(char c)
|
||||||
{
|
{
|
||||||
// Duplicate code for performance reasons.
|
// Duplicate code for performance reasons.
|
||||||
|
@ -497,7 +500,19 @@ void gfx_set_pixel(u32 x, u32 y, u32 color)
|
||||||
gfx_ctxt.fb[y + (gfx_ctxt.width - x) * gfx_ctxt.stride] = color;
|
gfx_ctxt.fb[y + (gfx_ctxt.width - x) * gfx_ctxt.stride] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((optimize("unroll-loops"))) gfx_set_rect_land_pitch(u32 *fb, const u32 *buf, u32 stride, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2)
|
void gfx_set_rect_pitch(u32 *fb, const u32 *buf, u32 stride, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2)
|
||||||
|
{
|
||||||
|
u32 *ptr = (u32 *)buf;
|
||||||
|
u32 line_size = pos_x2 - pos_x + 1;
|
||||||
|
//ptr = gfx_debug_rect(buf, pos_x, pos_y, pos_x2, pos_y2);
|
||||||
|
for (u32 y = pos_y; y <= pos_y2; y++)
|
||||||
|
{
|
||||||
|
memcpy(&fb[pos_x + y * stride], ptr, line_size * sizeof(u32));
|
||||||
|
ptr += line_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx_set_rect_land_pitch(u32 *fb, const u32 *buf, u32 stride, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2)
|
||||||
{
|
{
|
||||||
u32 *ptr = (u32 *)buf;
|
u32 *ptr = (u32 *)buf;
|
||||||
|
|
||||||
|
@ -505,8 +520,8 @@ void __attribute__((optimize("unroll-loops"))) gfx_set_rect_land_pitch(u32 *fb,
|
||||||
|
|
||||||
if (!(pixels_w % 8))
|
if (!(pixels_w % 8))
|
||||||
{
|
{
|
||||||
for (u32 y = pos_y; y < (pos_y2 + 1); y++)
|
for (u32 y = pos_y; y <= pos_y2; y++)
|
||||||
for (u32 x = pos_x; x < (pos_x2 + 1); x+=8)
|
for (u32 x = pos_x; x <= pos_x2; x += 8)
|
||||||
{
|
{
|
||||||
u32 *fbx = &fb[x * stride + y];
|
u32 *fbx = &fb[x * stride + y];
|
||||||
|
|
||||||
|
@ -528,7 +543,7 @@ void __attribute__((optimize("unroll-loops"))) gfx_set_rect_land_pitch(u32 *fb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((optimize("unroll-loops"))) gfx_set_rect_land_block(u32 *fb, const u32 *buf, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2)
|
void gfx_set_rect_land_block(u32 *fb, const u32 *buf, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2)
|
||||||
{
|
{
|
||||||
u32 *ptr = (u32 *)buf;
|
u32 *ptr = (u32 *)buf;
|
||||||
u32 GOB_address = 0;
|
u32 GOB_address = 0;
|
||||||
|
@ -537,9 +552,9 @@ void __attribute__((optimize("unroll-loops"))) gfx_set_rect_land_block(u32 *fb,
|
||||||
|
|
||||||
// Optimized
|
// Optimized
|
||||||
u32 image_width_in_gobs = 655360; //1280
|
u32 image_width_in_gobs = 655360; //1280
|
||||||
for (u32 y = pos_y; y < (pos_y2 + 1); y++)
|
for (u32 y = pos_y; y <= pos_y2; y++)
|
||||||
{
|
{
|
||||||
for (u32 x = pos_x; x < (pos_x2 + 1); x++)
|
for (u32 x = pos_x; x <= pos_x2; x++)
|
||||||
{
|
{
|
||||||
GOB_address = (y >> 7) * image_width_in_gobs + ((x >> 4) << 13) + (((y % 128) >> 3) << 9);
|
GOB_address = (y >> 7) * image_width_in_gobs + ((x >> 4) << 13) + (((y % 128) >> 3) << 9);
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ void gfx_hexdump(u32 base, const void *buf, u32 len);
|
||||||
|
|
||||||
void gfx_set_pixel(u32 x, u32 y, u32 color);
|
void gfx_set_pixel(u32 x, u32 y, u32 color);
|
||||||
|
|
||||||
|
void gfx_set_rect_pitch(u32 *fb, const u32 *buf, u32 stride, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2);
|
||||||
void gfx_set_rect_land_pitch(u32 *fb, const u32 *buf, u32 stride, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2);
|
void gfx_set_rect_land_pitch(u32 *fb, const u32 *buf, u32 stride, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2);
|
||||||
void gfx_set_rect_land_block(u32 *fb, const u32 *buf, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2);
|
void gfx_set_rect_land_block(u32 *fb, const u32 *buf, u32 pos_x, u32 pos_y, u32 pos_x2, u32 pos_y2);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue