BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lvgl
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
lvgl
Commits
d9147ae2
Commit
d9147ae2
authored
Aug 04, 2017
by
Kiss-Vamosi Gabor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
LV_VDB_DOUBLE: Add double virtual display buffer. Needs test on real hardware
parent
d1837d26
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
101 additions
and
40 deletions
+101
-40
lv_conf_templ.h
lv_conf_templ.h
+10
-9
lv_refr.c
lv_obj/lv_refr.c
+15
-15
lv_vdb.c
lv_obj/lv_vdb.c
+67
-12
lv_vdb.h
lv_obj/lv_vdb.h
+9
-4
No files found.
lv_conf_templ.h
View file @
d9147ae2
...
...
@@ -17,18 +17,19 @@
#define LV_HOR_RES (320 * LV_DOWNSCALE)
#define LV_VER_RES (240 * LV_DOWNSCALE)
#define LV_DPI (80 * LV_DOWNSCALE)
/* Buffered rendering: >= LV_DOWNSCALE * LV_HOR_RES or 0 to disable buffering*/
#define LV_VDB_SIZE (LV_HOR_RES * 30)
/* Enable antialaiassing
/* Enable anti-aliasing
* If enabled everything will half-sized
* Use LV_DOWNSCALE to compensate
* the down scaling effect of antialiassing*/
* Use LV_DOWNSCALE to compensate he down scaling effect of anti-aliasing*/
#define LV_ANTIALIAS 1
#define LV_DOWNSCALE (1 << LV_ANTIALIAS) /*Set the downscaling value*/
/*Set the downscaling value*/
#define LV_DOWNSCALE (1 << LV_ANTIALIAS)
/* Buffered rendering: >= LV_DOWNSCALE * LV_HOR_RES or 0 to disable buffering*/
#define LV_VDB_SIZE (LV_HOR_RES * LV_VER_RES / 20)
#if LV_VDB_SIZE
/* Double virtual buffering
* One for rendering another to transfer former rendered image to frame buffer in the background*/
#define LV_VDB_DOUBLE 1
#endif
#define LV_REFR_PERIOD 40 /*Screen refresh period in milliseconds*/
#define LV_INV_FIFO_SIZE 32 /*The average number of objects on a screen */
...
...
lv_obj/lv_refr.c
View file @
d9147ae2
...
...
@@ -70,7 +70,6 @@ void lv_refr_init(void)
ptask_t
*
task
;
task
=
ptask_create
(
lv_refr_task
,
LV_REFR_PERIOD
,
PTASK_PRIO_MID
,
NULL
);
dm_assert
(
task
);
}
/**
...
...
@@ -130,7 +129,7 @@ void lv_inv_area(const area_t * area_p)
* @param cb pointer to a callback function (void my_refr_cb(uint32_t time_ms, uint32_t px_num))
* time_ms: refresh time in [ms]
* px_num: not the drawn pixels but the number of affected pixels of the screen
* (more pixels are drawn
with opacity area
s)
* (more pixels are drawn
because of overlapping object
s)
*/
void
lv_refr_set_monitor_cb
(
void
(
*
cb
)(
uint32_t
,
uint32_t
))
{
...
...
@@ -257,15 +256,8 @@ static void lv_refr_area_no_vdb(const area_t * area_p)
*/
static
void
lv_refr_area_with_vdb
(
const
area_t
*
area_p
)
{
lv_vdb_t
*
vdb_p
=
lv_vdb_get
();
/*Always use the full row*/
vdb_p
->
area
.
x1
=
area_p
->
x1
;
vdb_p
->
area
.
y1
=
area_p
->
y1
;
vdb_p
->
area
.
x2
=
area_p
->
x2
;
/*Calculate the max row num*/
uint32_t
max_row
=
(
uint32_t
)
LV_VDB_SIZE
/
(
vdb_p
->
area
.
x2
-
vdb_p
->
area
.
x1
+
1
);
uint32_t
max_row
=
(
uint32_t
)
LV_VDB_SIZE
/
(
area_get_width
(
area_p
)
);
if
(
max_row
>
area_get_height
(
area_p
))
max_row
=
area_get_height
(
area_p
);
/*Round the row number with downscale*/
...
...
@@ -273,20 +265,28 @@ static void lv_refr_area_with_vdb(const area_t * area_p)
max_row
&=
(
~
0x1
);
#endif
/*
Refresh all rows
*/
cord_t
row
=
area_p
->
y1
;
/*
Always use the full row
*/
cord_t
row
;
cord_t
row_last
=
0
;
for
(
row
=
area_p
->
y1
;
row
+
max_row
-
1
<=
area_p
->
y2
;
row
+=
max_row
)
{
lv_vdb_t
*
vdb_p
=
lv_vdb_get
();
/*Calc. the next y coordinates of VDB*/
vdb_p
->
area
.
x1
=
area_p
->
x1
;
vdb_p
->
area
.
x2
=
area_p
->
x2
;
vdb_p
->
area
.
y1
=
row
;
vdb_p
->
area
.
y2
=
row
+
max_row
-
1
;
row_last
=
row
+
max_row
-
1
;
lv_refr_area_part_vdb
(
area_p
);
}
/*If the last y coordinates are not handled yet ...*/
if
(
area_p
->
y2
!=
vdb_p
->
area
.
y2
)
{
if
(
area_p
->
y2
!=
row_last
)
{
lv_vdb_t
*
vdb_p
=
lv_vdb_get
();
/*Calc. the next y coordinates of VDB*/
vdb_p
->
area
.
x1
=
area_p
->
x1
;
vdb_p
->
area
.
x2
=
area_p
->
x2
;
vdb_p
->
area
.
y1
=
row
;
vdb_p
->
area
.
y2
=
area_p
->
y2
;
...
...
lv_obj/lv_vdb.c
View file @
d9147ae2
...
...
@@ -20,7 +20,13 @@
/**********************
* TYPEDEFS
**********************/
#if LV_VDB_DOUBLE != 0
typedef
enum
{
LV_VDB_STATE_FREE
=
0
,
LV_VDB_STATE_ACTIVE
,
LV_VDB_STATE_FLUSH
,
}
lv_vdb_state_t
;
#endif
/**********************
* STATIC PROTOTYPES
**********************/
...
...
@@ -28,7 +34,12 @@
/**********************
* STATIC VARIABLES
**********************/
#if LV_VDB_DOUBLE == 0
static
lv_vdb_t
vdb
;
#else
static
lv_vdb_t
vdb
[
2
];
static
volatile
lv_vdb_state_t
vdb_state
[
2
]
=
{
LV_VDB_STATE_FREE
,
LV_VDB_STATE_FREE
};
#endif
/**********************
* MACROS
...
...
@@ -39,21 +50,53 @@ static lv_vdb_t vdb;
**********************/
/**
* Get the
vdb variabl
e
* @return pointer to the
vdb
variable
* Get the
'vdb' variable or allocate one in LV_VDB_DOUBLE mod
e
* @return pointer to the
'vdb'
variable
*/
lv_vdb_t
*
lv_vdb_get
(
void
)
{
#if LV_VDB_DOUBLE == 0
return
&
vdb
;
#else
/*If already there is an active do nothing*/
if
(
vdb_state
[
0
]
==
LV_VDB_STATE_ACTIVE
)
return
&
vdb
[
0
];
if
(
vdb_state
[
1
]
==
LV_VDB_STATE_ACTIVE
)
return
&
vdb
[
1
];
/*Try to allocate a free VDB*/
if
(
vdb_state
[
0
]
==
LV_VDB_STATE_FREE
)
{
vdb_state
[
0
]
=
LV_VDB_STATE_ACTIVE
;
return
&
vdb
[
0
];
}
if
(
vdb_state
[
1
]
==
LV_VDB_STATE_FREE
)
{
vdb_state
[
1
]
=
LV_VDB_STATE_ACTIVE
;
return
&
vdb
[
1
];
}
return
NULL
;
/*There wasn't free VDB (never happen)*/
#endif
}
/**
* Flush the content of the
vdb
* Flush the content of the
VDB
*/
void
lv_vdb_flush
(
void
)
{
lv_vdb_t
*
vdb_act
=
lv_vdb_get
();
if
(
vdb_act
==
NULL
)
return
;
#if LV_VDB_DOUBLE != 0
/* Wait the pending flush before starting this one
* (Don't forget: 'lv_vdb_flush_ready' has to be called when flushing is ready)*/
while
(
vdb_state
[
0
]
==
LV_VDB_STATE_FLUSH
||
vdb_state
[
1
]
==
LV_VDB_STATE_FLUSH
);
/*Turn the active VDB to flushing*/
if
(
vdb_state
[
0
]
==
LV_VDB_STATE_ACTIVE
)
vdb_state
[
0
]
=
LV_VDB_STATE_FLUSH
;
if
(
vdb_state
[
1
]
==
LV_VDB_STATE_ACTIVE
)
vdb_state
[
1
]
=
LV_VDB_STATE_FLUSH
;
#endif
#if LV_ANTIALIAS == 0
disp_map
(
vdb
.
area
.
x1
,
vdb
.
area
.
y1
,
vdb
.
area
.
x2
,
vdb
.
area
.
y2
,
vdb
.
buf
);
disp_map
(
vdb
_act
->
area
.
x1
,
vdb_act
->
area
.
y1
,
vdb_act
->
area
.
x2
,
vdb_act
->
area
.
y2
,
vdb_act
->
buf
);
#else
/* Get the average of 2x2 pixels and put the result back to the VDB
* The reading goes much faster then the write back
...
...
@@ -68,12 +111,12 @@ void lv_vdb_flush(void)
* */
cord_t
x
;
cord_t
y
;
cord_t
w
=
area_get_width
(
&
vdb
.
area
);
color_t
*
in1_buf
=
vdb
.
buf
;
/*Pointer to the first row*/
color_t
*
in2_buf
=
vdb
.
buf
+
w
;
/*Pointer to the second row*/
color_t
*
out_buf
=
vdb
.
buf
;
/*Store the result here*/
for
(
y
=
vdb
.
area
.
y1
;
y
<
vdb
.
area
.
y2
;
y
+=
2
)
{
for
(
x
=
vdb
.
area
.
x1
;
x
<
vdb
.
area
.
x2
;
x
+=
2
)
{
cord_t
w
=
area_get_width
(
&
vdb
_act
->
area
);
color_t
*
in1_buf
=
vdb
_act
->
buf
;
/*Pointer to the first row*/
color_t
*
in2_buf
=
vdb
_act
->
buf
+
w
;
/*Pointer to the second row*/
color_t
*
out_buf
=
vdb
_act
->
buf
;
/*Store the result here*/
for
(
y
=
vdb
_act
->
area
.
y1
;
y
<
vdb_act
->
area
.
y2
;
y
+=
2
)
{
for
(
x
=
vdb
_act
->
area
.
x1
;
x
<
vdb_act
->
area
.
x2
;
x
+=
2
)
{
/*If the pixels are the same do not calculate the average */
if
(
in1_buf
->
full
==
(
in1_buf
+
1
)
->
full
&&
...
...
@@ -103,7 +146,19 @@ void lv_vdb_flush(void)
/* Now the full the VDB is filtered and the result is stored in the first quarter of it
* Write out the filtered map to the display*/
disp_map
(
vdb
.
area
.
x1
>>
1
,
vdb
.
area
.
y1
>>
1
,
vdb
.
area
.
x2
>>
1
,
vdb
.
area
.
y2
>>
1
,
vdb
.
buf
);
disp_map
(
vdb_act
->
area
.
x1
>>
1
,
vdb_act
->
area
.
y1
>>
1
,
vdb_act
->
area
.
x2
>>
1
,
vdb_act
->
area
.
y2
>>
1
,
vdb_act
->
buf
);
#endif
}
/**
* In 'LV_VDB_DOUBLE' mode has to be called when the 'disp_map'
* is ready with copying the map to a frame buffer.
*/
void
lv_vdb_flush_ready
(
void
)
{
#if LV_VDB_DOUBLE != 0
if
(
vdb_state
[
0
]
==
LV_VDB_STATE_FLUSH
)
vdb_state
[
0
]
=
LV_VDB_STATE_FREE
;
if
(
vdb_state
[
1
]
==
LV_VDB_STATE_FLUSH
)
vdb_state
[
1
]
=
LV_VDB_STATE_FREE
;
#endif
}
...
...
lv_obj/lv_vdb.h
View file @
d9147ae2
...
...
@@ -34,15 +34,13 @@ typedef struct
color_t
buf
[
LV_VDB_SIZE
];
}
lv_vdb_t
;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Get the
vdb variabl
e
* @return pointer to the
vdb
variable
* Get the
'vdb' variable or allocate one in LV_VDB_DOUBLE mod
e
* @return pointer to the
'vdb'
variable
*/
lv_vdb_t
*
lv_vdb_get
(
void
);
...
...
@@ -51,6 +49,13 @@ lv_vdb_t * lv_vdb_get(void);
*/
void
lv_vdb_flush
(
void
);
/**
* In 'LV_VDB_DOUBLE' mode has to be called when 'disp_map()'
* is ready with copying the map to a frame buffer.
*/
void
lv_vdb_flush_ready
(
void
);
/**********************
* MACROS
**********************/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment