Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
flow3r firmware
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
dos
flow3r firmware
Commits
3162b477
Commit
3162b477
authored
Oct 3, 2023
by
pippin
Browse files
Options
Downloads
Patches
Plain Diff
st3m_gfx: add virtual framebuffer support
parent
82f3d0c6
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
components/ctx/ctx_config.h
+1
-1
1 addition, 1 deletion
components/ctx/ctx_config.h
components/st3m/st3m_gfx.c
+132
-14
132 additions, 14 deletions
components/st3m/st3m_gfx.c
components/st3m/st3m_gfx.h
+16
-4
16 additions, 4 deletions
components/st3m/st3m_gfx.h
with
149 additions
and
19 deletions
components/ctx/ctx_config.h
+
1
−
1
View file @
3162b477
...
@@ -45,7 +45,7 @@
...
@@ -45,7 +45,7 @@
#define CTX_BAREMETAL 1
#define CTX_BAREMETAL 1
#define CTX_ONE_FONT_ENGINE 1
#define CTX_ONE_FONT_ENGINE 1
#define CTX_MAX_SCANLINE_LENGTH
256
#define CTX_MAX_SCANLINE_LENGTH
960
#define CTX_MAX_JOURNAL_SIZE (1024*512)
#define CTX_MAX_JOURNAL_SIZE (1024*512)
// is also max and limits complexity
// is also max and limits complexity
// of paths that can be filled
// of paths that can be filled
...
...
This diff is collapsed.
Click to expand it.
components/st3m/st3m_gfx.c
+
132
−
14
View file @
3162b477
...
@@ -90,6 +90,9 @@ typedef struct {
...
@@ -90,6 +90,9 @@ typedef struct {
int
osd_y1
;
int
osd_y1
;
int
osd_x1
;
int
osd_x1
;
int
blit_x
;
// upper left pixel in framebuffer coordinates
int
blit_y
;
//
st3m_gfx_mode
mode
;
st3m_gfx_mode
mode
;
uint8_t
*
blit_src
;
uint8_t
*
blit_src
;
}
st3m_gfx_drawlist
;
}
st3m_gfx_drawlist
;
...
@@ -117,6 +120,12 @@ static TaskHandle_t graphics_blit_task;
...
@@ -117,6 +120,12 @@ static TaskHandle_t graphics_blit_task;
static
int
_st3m_gfx_low_latency
=
0
;
static
int
_st3m_gfx_low_latency
=
0
;
static
int
st3m_gfx_fb_width
=
0
;
static
int
st3m_gfx_fb_height
=
0
;
static
int
st3m_gfx_blit_x
=
0
;
static
int
st3m_gfx_blit_y
=
0
;
static
int
st3m_gfx_geom_dirty
=
0
;
static
inline
int
st3m_gfx_scale
(
void
)
{
static
inline
int
st3m_gfx_scale
(
void
)
{
st3m_gfx_mode
set_mode
=
_st3m_gfx_mode
?
_st3m_gfx_mode
:
default_mode
;
st3m_gfx_mode
set_mode
=
_st3m_gfx_mode
?
_st3m_gfx_mode
:
default_mode
;
switch
((
int
)(
set_mode
&
st3m_gfx_4x
))
{
switch
((
int
)(
set_mode
&
st3m_gfx_4x
))
{
...
@@ -351,6 +360,8 @@ st3m_gfx_mode st3m_gfx_set_mode(st3m_gfx_mode mode) {
...
@@ -351,6 +360,8 @@ st3m_gfx_mode st3m_gfx_set_mode(st3m_gfx_mode mode) {
((
mode
&
st3m_gfx_direct_ctx
)
!=
0
))
((
mode
&
st3m_gfx_direct_ctx
)
!=
0
))
_st3m_gfx_low_latency
=
(
N_DRAWLISTS
-
1
);
_st3m_gfx_low_latency
=
(
N_DRAWLISTS
-
1
);
st3m_gfx_fbconfig
(
240
,
240
,
0
,
0
);
return
mode
;
return
mode
;
}
}
...
@@ -367,7 +378,7 @@ uint8_t *st3m_gfx_fb(st3m_gfx_mode mode, int *width, int *height, int *stride) {
...
@@ -367,7 +378,7 @@ uint8_t *st3m_gfx_fb(st3m_gfx_mode mode, int *width, int *height, int *stride) {
if
(
height
)
*
height
=
256
;
if
(
height
)
*
height
=
256
;
return
st3m_pal
;
return
st3m_pal
;
}
else
if
(
mode
==
st3m_gfx_default
)
{
}
else
if
(
mode
==
st3m_gfx_default
)
{
if
(
stride
)
*
stride
=
FLOW3R_BSP_DISPLAY_WIDTH
*
bpp
/
8
;
if
(
stride
)
*
stride
=
st3m_gfx_fb_width
*
bpp
/
8
;
if
(
width
)
*
width
=
FLOW3R_BSP_DISPLAY_WIDTH
;
if
(
width
)
*
width
=
FLOW3R_BSP_DISPLAY_WIDTH
;
if
(
height
)
*
height
=
FLOW3R_BSP_DISPLAY_HEIGHT
;
if
(
height
)
*
height
=
FLOW3R_BSP_DISPLAY_HEIGHT
;
return
((
uint8_t
*
)
st3m_fb
);
return
((
uint8_t
*
)
st3m_fb
);
...
@@ -465,9 +476,11 @@ static void st3m_gfx_rast_task(void *_arg) {
...
@@ -465,9 +476,11 @@ static void st3m_gfx_rast_task(void *_arg) {
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
ctx_set_textureclock
(
osd_ctx
,
ctx_textureclock
(
fb_ctx
));
ctx_set_textureclock
(
osd_ctx
,
ctx_textureclock
(
fb_ctx
));
#endif
#endif
if
(
prev_set_mode
!=
set_mode
)
{
if
(
st3m_gfx_geom_dirty
||
(
prev_set_mode
!=
set_mode
))
{
int
was_geom_dirty
=
(
prev_set_mode
==
set_mode
);
bits
=
_st3m_gfx_bpp
(
set_mode
);
bits
=
_st3m_gfx_bpp
(
set_mode
);
prev_set_mode
=
set_mode
;
prev_set_mode
=
set_mode
;
st3m_gfx_geom_dirty
=
0
;
#if ST3M_GFX_BLIT_TASK
#if ST3M_GFX_BLIT_TASK
if
((
bits
>
16
))
if
((
bits
>
16
))
...
@@ -475,33 +488,40 @@ static void st3m_gfx_rast_task(void *_arg) {
...
@@ -475,33 +488,40 @@ static void st3m_gfx_rast_task(void *_arg) {
else
else
direct_blit
=
0
;
direct_blit
=
0
;
#endif
#endif
int
stride
=
(
bits
*
240
)
/
8
;
int
stride
=
(
bits
*
st3m_gfx_fb_width
)
/
8
;
switch
(
bits
)
{
switch
(
bits
)
{
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
case
1
:
case
1
:
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
240
,
240
,
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
st3m_gfx_fb_width
,
st3m_gfx_fb_height
,
stride
,
CTX_FORMAT_GRAY1
);
stride
,
CTX_FORMAT_GRAY1
);
break
;
break
;
case
2
:
case
2
:
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
240
,
240
,
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
st3m_gfx_fb_width
,
st3m_gfx_fb_height
,
stride
,
CTX_FORMAT_GRAY2
);
stride
,
CTX_FORMAT_GRAY2
);
break
;
break
;
case
4
:
case
4
:
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
240
,
240
,
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
st3m_gfx_fb_width
,
st3m_gfx_fb_height
,
stride
,
CTX_FORMAT_GRAY4
);
stride
,
CTX_FORMAT_GRAY4
);
break
;
break
;
case
8
:
case
8
:
case
9
:
case
9
:
if
((
set_mode
&
0xf
)
==
9
)
if
((
set_mode
&
0xf
)
==
9
)
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
240
,
240
,
ctx_rasterizer_reinit
(
stride
,
CTX_FORMAT_RGB332
);
fb_ctx
,
st3m_fb
,
0
,
0
,
st3m_gfx_fb_width
,
st3m_gfx_fb_height
,
stride
,
CTX_FORMAT_RGB332
);
else
else
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
240
,
240
,
ctx_rasterizer_reinit
(
stride
,
CTX_FORMAT_GRAY8
);
fb_ctx
,
st3m_fb
,
0
,
0
,
st3m_gfx_fb_width
,
st3m_gfx_fb_height
,
stride
,
CTX_FORMAT_GRAY8
);
break
;
break
;
#endif
#endif
case
16
:
case
16
:
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
240
,
240
,
ctx_rasterizer_reinit
(
fb_ctx
,
st3m_fb
,
0
,
0
,
st3m_gfx_fb_width
,
st3m_gfx_fb_height
,
stride
,
stride
,
CTX_FORMAT_RGB565_BYTESWAPPED
);
CTX_FORMAT_RGB565_BYTESWAPPED
);
break
;
break
;
...
@@ -518,10 +538,10 @@ static void st3m_gfx_rast_task(void *_arg) {
...
@@ -518,10 +538,10 @@ static void st3m_gfx_rast_task(void *_arg) {
#endif
#endif
}
}
st3m_gfx_viewport_transform
(
fb_ctx
);
st3m_gfx_viewport_transform
(
fb_ctx
);
memset
(
st3m_fb
,
0
,
sizeof
(
st3m_fb
));
if
(
!
was_geom_dirty
)
memset
(
st3m_fb
,
0
,
sizeof
(
st3m_fb
));
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
#if CONFIG_FLOW3R_CTX_FLAVOUR_FULL
st3m_gfx_viewport_transform
(
osd_ctx
);
st3m_gfx_viewport_transform
(
osd_ctx
);
memset
(
st3m_fb2
,
0
,
sizeof
(
st3m_fb2
));
if
(
!
was_geom_dirty
)
memset
(
st3m_fb2
,
0
,
sizeof
(
st3m_fb2
));
#endif
#endif
}
}
...
@@ -541,7 +561,76 @@ static void st3m_gfx_rast_task(void *_arg) {
...
@@ -541,7 +561,76 @@ static void st3m_gfx_rast_task(void *_arg) {
}
else
{
}
else
{
drawlist
->
blit_src
=
st3m_fb_copy
;
drawlist
->
blit_src
=
st3m_fb_copy
;
xSemaphoreTake
(
st3m_fb_copy_lock
,
portMAX_DELAY
);
xSemaphoreTake
(
st3m_fb_copy_lock
,
portMAX_DELAY
);
memcpy
(
st3m_fb_copy
,
st3m_fb
,
240
*
(
240
*
bits
/
8
));
int
disp_stride
=
240
*
bits
/
8
;
if
((
st3m_gfx_fb_width
==
240
)
&&
(
drawlist
->
blit_x
==
0
))
{
int
blit_offset
=
st3m_gfx_blit_y
*
240
*
bits
/
8
;
int
overlap
=
(
st3m_gfx_blit_y
+
240
)
-
st3m_gfx_fb_height
;
if
(
overlap
>
0
)
{
// vertical overlap, 2 memcpys
int
start_scans
=
240
-
overlap
;
memcpy
(
st3m_fb_copy
,
st3m_fb
+
blit_offset
,
start_scans
*
disp_stride
);
memcpy
(
st3m_fb_copy
+
start_scans
*
disp_stride
,
st3m_fb
,
overlap
*
disp_stride
);
}
else
{
// best case
memcpy
(
st3m_fb_copy
,
st3m_fb
+
blit_offset
,
240
*
disp_stride
);
}
}
else
{
int
fb_stride
=
st3m_gfx_fb_width
*
bits
/
8
;
int
scan_offset
=
drawlist
->
blit_x
*
bits
/
8
;
int
scan_overlap
=
(
drawlist
->
blit_x
+
240
)
-
st3m_gfx_fb_width
;
if
(
scan_overlap
<=
0
)
{
// only vertical wrap-around
int
blit_offset
=
(
st3m_gfx_blit_y
*
240
+
drawlist
->
blit_x
)
*
bits
/
8
;
int
overlap
=
(
st3m_gfx_blit_y
+
240
)
-
st3m_gfx_fb_height
;
if
(
overlap
<=
0
)
overlap
=
0
;
int
start_scans
=
240
-
overlap
;
for
(
int
i
=
0
;
i
<
start_scans
;
i
++
)
memcpy
(
st3m_fb_copy
+
i
*
disp_stride
,
st3m_fb
+
blit_offset
+
i
*
fb_stride
,
disp_stride
);
for
(
int
i
=
0
;
i
<
overlap
;
i
++
)
memcpy
(
st3m_fb_copy
+
(
i
+
start_scans
)
*
disp_stride
,
st3m_fb
+
(
drawlist
->
blit_x
*
bits
/
8
)
+
i
*
fb_stride
,
disp_stride
);
}
else
{
// generic case, handles both horizontal and vertical
// wrap-around
int
start_bit
=
240
-
scan_overlap
;
int
blit_offset
=
(
st3m_gfx_blit_y
)
*
fb_stride
;
int
overlap
=
(
st3m_gfx_blit_y
+
240
)
-
st3m_gfx_fb_height
;
if
(
overlap
<=
0
)
overlap
=
0
;
int
start_scans
=
240
-
overlap
;
int
start_bytes
=
start_bit
*
bits
/
8
;
int
scan_overlap_bytes
=
scan_overlap
*
bits
/
8
;
for
(
int
i
=
0
;
i
<
start_scans
;
i
++
)
memcpy
(
st3m_fb_copy
+
i
*
disp_stride
,
st3m_fb
+
blit_offset
+
i
*
fb_stride
+
scan_offset
,
start_bytes
);
for
(
int
i
=
0
;
i
<
overlap
;
i
++
)
memcpy
(
st3m_fb_copy
+
(
i
+
start_scans
)
*
disp_stride
,
st3m_fb
+
scan_offset
+
i
*
fb_stride
,
start_bytes
);
// second pass over scanlines, filling in second half (which
// is wrapped to start of fb-scans)
for
(
int
i
=
0
;
i
<
start_scans
;
i
++
)
memcpy
(
st3m_fb_copy
+
i
*
disp_stride
+
start_bytes
,
st3m_fb
+
blit_offset
+
i
*
fb_stride
,
scan_overlap_bytes
);
for
(
int
i
=
0
;
i
<
overlap
;
i
++
)
memcpy
(
st3m_fb_copy
+
(
i
+
start_scans
)
*
disp_stride
+
start_bytes
,
st3m_fb
+
i
*
fb_stride
,
scan_overlap_bytes
);
}
}
xSemaphoreGive
(
st3m_fb_copy_lock
);
xSemaphoreGive
(
st3m_fb_copy_lock
);
xSemaphoreGive
(
st3m_fb_lock
);
xSemaphoreGive
(
st3m_fb_lock
);
xQueueSend
(
user_ctx_blitq
,
&
desc_no
,
portMAX_DELAY
);
xQueueSend
(
user_ctx_blitq
,
&
desc_no
,
portMAX_DELAY
);
...
@@ -882,6 +971,8 @@ static void st3m_gfx_pipe_put(void) {
...
@@ -882,6 +971,8 @@ static void st3m_gfx_pipe_put(void) {
drawlist
->
osd_y0
=
_st3m_osd_y0
;
drawlist
->
osd_y0
=
_st3m_osd_y0
;
drawlist
->
osd_x1
=
_st3m_osd_x1
;
drawlist
->
osd_x1
=
_st3m_osd_x1
;
drawlist
->
osd_y1
=
_st3m_osd_y1
;
drawlist
->
osd_y1
=
_st3m_osd_y1
;
drawlist
->
blit_x
=
st3m_gfx_blit_x
;
drawlist
->
blit_y
=
st3m_gfx_blit_y
;
#endif
#endif
xQueueSend
(
user_ctx_rastq
,
&
last_descno
,
portMAX_DELAY
);
xQueueSend
(
user_ctx_rastq
,
&
last_descno
,
portMAX_DELAY
);
}
}
...
@@ -966,3 +1057,30 @@ void st3m_gfx_overlay_clip(int x0, int y0, int x1, int y1) {
...
@@ -966,3 +1057,30 @@ void st3m_gfx_overlay_clip(int x0, int y0, int x1, int y1) {
}
}
}
}
#endif
#endif
void
st3m_gfx_fbconfig
(
int
width
,
int
height
,
int
blit_x
,
int
blit_y
)
{
if
(
width
<=
0
)
width
=
st3m_gfx_fb_width
;
if
(
height
<=
0
)
height
=
st3m_gfx_fb_height
;
st3m_gfx_mode
set_mode
=
_st3m_gfx_mode
?
_st3m_gfx_mode
:
default_mode
;
int
bits
=
st3m_gfx_bpp
(
set_mode
);
if
(
width
>
CTX_MAX_SCANLINE_LENGTH
)
width
=
CTX_MAX_SCANLINE_LENGTH
;
if
((
width
*
height
*
bits
)
/
8
>
(
240
*
240
*
4
))
height
=
240
*
240
*
4
*
8
/
(
width
*
bits
);
blit_x
%=
width
;
blit_y
%=
height
;
if
((
st3m_gfx_fb_width
!=
width
)
||
(
st3m_gfx_fb_height
!=
height
))
{
st3m_gfx_fb_width
=
width
;
st3m_gfx_fb_height
=
height
;
st3m_gfx_geom_dirty
++
;
}
st3m_gfx_blit_x
=
blit_x
;
st3m_gfx_blit_y
=
blit_y
;
}
void
st3m_gfx_get_fbconfig
(
int
*
width
,
int
*
height
,
int
*
blit_x
,
int
*
blit_y
)
{
if
(
width
)
*
width
=
st3m_gfx_fb_width
;
if
(
height
)
*
height
=
st3m_gfx_fb_height
;
if
(
blit_x
)
*
blit_x
=
st3m_gfx_blit_x
;
if
(
blit_y
)
*
blit_y
=
st3m_gfx_blit_y
;
}
This diff is collapsed.
Click to expand it.
components/st3m/st3m_gfx.h
+
16
−
4
View file @
3162b477
...
@@ -43,10 +43,10 @@ typedef enum {
...
@@ -43,10 +43,10 @@ typedef enum {
st3m_gfx_1bpp
=
1
,
st3m_gfx_1bpp
=
1
,
st3m_gfx_2bpp
=
2
,
st3m_gfx_2bpp
=
2
,
st3m_gfx_4bpp
=
4
,
st3m_gfx_4bpp
=
4
,
st3m_gfx_8bpp
=
8
,
st3m_gfx_8bpp
=
8
,
// bare 8bpp mode is grayscale
st3m_gfx_rgb332
=
9
,
st3m_gfx_rgb332
=
9
,
// variant of 8bpp mode using RGB
st3m_gfx_sepia
=
10
,
st3m_gfx_sepia
=
10
,
// grayscale rendering with sepia palette
st3m_gfx_cool
=
11
,
st3m_gfx_cool
=
11
,
// grayscale rendering with cool palette
st3m_gfx_palette
=
15
,
st3m_gfx_palette
=
15
,
// 16bpp modes have the lowest blit overhead - no osd for now
// 16bpp modes have the lowest blit overhead - no osd for now
st3m_gfx_16bpp
=
16
,
st3m_gfx_16bpp
=
16
,
...
@@ -136,3 +136,15 @@ void st3m_gfx_splash(const char *text);
...
@@ -136,3 +136,15 @@ void st3m_gfx_splash(const char *text);
// Draw the flow3r multi-coloured logo at coordinates x,y and with given
// Draw the flow3r multi-coloured logo at coordinates x,y and with given
// dimension (approx. bounding box size).
// dimension (approx. bounding box size).
void
st3m_gfx_flow3r_logo
(
Ctx
*
ctx
,
float
x
,
float
y
,
float
dim
);
void
st3m_gfx_flow3r_logo
(
Ctx
*
ctx
,
float
x
,
float
y
,
float
dim
);
// configure virtual viewport, the default values are 0, 0, 240, 240 which
// also gives room for a copy of the fb for separate rasterize/blit in 16bpp
//
// with, height: width and height of virtual framebuffer
//
// changing the viewport should be done after setting the graphics mode - upon
// graphics mode setting viewport is reset to 240, 240, 0,0,0,0
void
st3m_gfx_fbconfig
(
int
width
,
int
height
,
int
blit_x
,
int
blit_y
);
// get fbconfig values, arguments passed NULL ptrs are ignored.
void
st3m_gfx_get_fbconfig
(
int
*
width
,
int
*
height
,
int
*
blit_x
,
int
*
blit_y
);
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment