Message ID | 20230821135111.3558478-5-alpernebiyasak@gmail.com |
---|---|
State | Under Review |
Delegated to: | Anatolij Gustschin |
Headers | show |
Series | Add video damage tracking | expand |
On Mon, 21 Aug 2023 at 07:51, Alper Nebi Yasak <alpernebiyasak@gmail.com> wrote: > > From: Alexander Graf <agraf@csgraf.de> > > We are going to introduce image damage tracking to fasten up screen > refresh on large displays. This patch adds damage tracking for up to > one rectangle of the screen which is typically enough to hold blt or > text print updates. Callers into this API and a reduced dcache flush > code path will follow in later patches. > > Signed-off-by: Alexander Graf <agraf@csgraf.de> > Reported-by: Da Xue <da@libre.computer> > [Alper: Use xstart/yend, document new fields, return void from > video_damage(), declare priv, drop headers, use IS_ENABLED()] > Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> > Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> > --- > > Changes in v5: > - Use xstart, ystart, xend, yend as names for damage region > - Document damage struct and fields in struct video_priv comment > - Return void from video_damage() > - Fix undeclared priv error in video_sync() > - Drop unused headers from video-uclass.c > - Use IS_ENABLED() instead of CONFIG_IS_ENABLED() > > Changes in v4: > - Move damage clear to patch "dm: video: Add damage tracking API" > - Simplify first damage logic > - Remove VIDEO_DAMAGE default for ARM > > Changes in v3: > - Adapt to always assume DM is used > > Changes in v2: > - Remove ifdefs > > drivers/video/Kconfig | 13 ++++++++++++ > drivers/video/video-uclass.c | 41 +++++++++++++++++++++++++++++++++--- > include/video.h | 32 ++++++++++++++++++++++++++-- > 3 files changed, 81 insertions(+), 5 deletions(-) > Reviewed-by: Simon Glass <sjg@chromium.org> But I suggest an empty static inline in the case where the feature is disabled?
On 2023-08-21 22:11 +03:00, Simon Glass wrote: > On Mon, 21 Aug 2023 at 07:51, Alper Nebi Yasak <alpernebiyasak@gmail.com> wrote: >> >> From: Alexander Graf <agraf@csgraf.de> >> >> We are going to introduce image damage tracking to fasten up screen >> refresh on large displays. This patch adds damage tracking for up to >> one rectangle of the screen which is typically enough to hold blt or >> text print updates. Callers into this API and a reduced dcache flush >> code path will follow in later patches. >> >> Signed-off-by: Alexander Graf <agraf@csgraf.de> >> Reported-by: Da Xue <da@libre.computer> >> [Alper: Use xstart/yend, document new fields, return void from >> video_damage(), declare priv, drop headers, use IS_ENABLED()] >> Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> >> Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> >> --- >> >> Changes in v5: >> - Use xstart, ystart, xend, yend as names for damage region >> - Document damage struct and fields in struct video_priv comment >> - Return void from video_damage() >> - Fix undeclared priv error in video_sync() >> - Drop unused headers from video-uclass.c >> - Use IS_ENABLED() instead of CONFIG_IS_ENABLED() >> >> Changes in v4: >> - Move damage clear to patch "dm: video: Add damage tracking API" >> - Simplify first damage logic >> - Remove VIDEO_DAMAGE default for ARM >> >> Changes in v3: >> - Adapt to always assume DM is used >> >> Changes in v2: >> - Remove ifdefs >> >> drivers/video/Kconfig | 13 ++++++++++++ >> drivers/video/video-uclass.c | 41 +++++++++++++++++++++++++++++++++--- >> include/video.h | 32 ++++++++++++++++++++++++++-- >> 3 files changed, 81 insertions(+), 5 deletions(-) >> > > Reviewed-by: Simon Glass <sjg@chromium.org> > > But I suggest an empty static inline in the case where the feature is disabled? You mean with something like #ifdef CONFIG_VIDEO_DAMAGE, right?
Hi Alper, On Wed, 30 Aug 2023 at 13:15, Alper Nebi Yasak <alpernebiyasak@gmail.com> wrote: > > > > On 2023-08-21 22:11 +03:00, Simon Glass wrote: > > On Mon, 21 Aug 2023 at 07:51, Alper Nebi Yasak <alpernebiyasak@gmail.com> wrote: > >> > >> From: Alexander Graf <agraf@csgraf.de> > >> > >> We are going to introduce image damage tracking to fasten up screen > >> refresh on large displays. This patch adds damage tracking for up to > >> one rectangle of the screen which is typically enough to hold blt or > >> text print updates. Callers into this API and a reduced dcache flush > >> code path will follow in later patches. > >> > >> Signed-off-by: Alexander Graf <agraf@csgraf.de> > >> Reported-by: Da Xue <da@libre.computer> > >> [Alper: Use xstart/yend, document new fields, return void from > >> video_damage(), declare priv, drop headers, use IS_ENABLED()] > >> Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> > >> Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> > >> --- > >> > >> Changes in v5: > >> - Use xstart, ystart, xend, yend as names for damage region > >> - Document damage struct and fields in struct video_priv comment > >> - Return void from video_damage() > >> - Fix undeclared priv error in video_sync() > >> - Drop unused headers from video-uclass.c > >> - Use IS_ENABLED() instead of CONFIG_IS_ENABLED() > >> > >> Changes in v4: > >> - Move damage clear to patch "dm: video: Add damage tracking API" > >> - Simplify first damage logic > >> - Remove VIDEO_DAMAGE default for ARM > >> > >> Changes in v3: > >> - Adapt to always assume DM is used > >> > >> Changes in v2: > >> - Remove ifdefs > >> > >> drivers/video/Kconfig | 13 ++++++++++++ > >> drivers/video/video-uclass.c | 41 +++++++++++++++++++++++++++++++++--- > >> include/video.h | 32 ++++++++++++++++++++++++++-- > >> 3 files changed, 81 insertions(+), 5 deletions(-) > >> > > > > Reviewed-by: Simon Glass <sjg@chromium.org> > > > > But I suggest an empty static inline in the case where the feature is disabled? > > You mean with something like #ifdef CONFIG_VIDEO_DAMAGE, right? Yes Regards, Simon
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index fe43fbd7004a..97f494a1340b 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -92,6 +92,19 @@ config VIDEO_COPY To use this, your video driver must set @copy_base in struct video_uc_plat. +config VIDEO_DAMAGE + bool "Enable damage tracking of frame buffer regions" + help + On some machines (most ARM), the display frame buffer resides in + RAM. To make the display controller pick up screen updates, we + have to flush frame buffer contents from CPU caches into RAM which + can be a slow operation. + + This feature adds damage tracking to collect information about regions + that received updates. When we want to sync, we then only flush + regions of the frame buffer that were modified before, speeding up + screen refreshes significantly. + config BACKLIGHT_PWM bool "Generic PWM based Backlight Driver" depends on BACKLIGHT && DM_PWM diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 8f268fc4063f..447689581668 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -351,9 +351,39 @@ void video_set_default_colors(struct udevice *dev, bool invert) priv->colour_bg = video_index_to_colour(priv, back); } +/* Notify about changes in the frame buffer */ +void video_damage(struct udevice *vid, int x, int y, int width, int height) +{ + struct video_priv *priv = dev_get_uclass_priv(vid); + int xend = x + width; + int yend = y + height; + + if (!IS_ENABLED(CONFIG_VIDEO_DAMAGE)) + return; + + if (x > priv->xsize) + return; + + if (y > priv->ysize) + return; + + if (xend > priv->xsize) + xend = priv->xsize; + + if (yend > priv->ysize) + yend = priv->ysize; + + /* Span a rectangle across all old and new damage */ + priv->damage.xstart = min(x, priv->damage.xstart); + priv->damage.ystart = min(y, priv->damage.ystart); + priv->damage.xend = max(xend, priv->damage.xend); + priv->damage.yend = max(yend, priv->damage.yend); +} + /* Flush video activity to the caches */ int video_sync(struct udevice *vid, bool force) { + struct video_priv *priv = dev_get_uclass_priv(vid); struct video_ops *ops = video_get_ops(vid); int ret; @@ -369,15 +399,12 @@ int video_sync(struct udevice *vid, bool force) * out whether it exists? For now, ARM is safe. */ #if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) - struct video_priv *priv = dev_get_uclass_priv(vid); - if (priv->flush_dcache) { flush_dcache_range((ulong)priv->fb, ALIGN((ulong)priv->fb + priv->fb_size, CONFIG_SYS_CACHELINE_SIZE)); } #elif defined(CONFIG_VIDEO_SANDBOX_SDL) - struct video_priv *priv = dev_get_uclass_priv(vid); static ulong last_sync; if (force || get_timer(last_sync) > 100) { @@ -385,6 +412,14 @@ int video_sync(struct udevice *vid, bool force) last_sync = get_timer(0); } #endif + + if (IS_ENABLED(CONFIG_VIDEO_DAMAGE)) { + priv->damage.xstart = priv->xsize; + priv->damage.ystart = priv->ysize; + priv->damage.xend = 0; + priv->damage.yend = 0; + } + return 0; } diff --git a/include/video.h b/include/video.h index 66d109ca5da6..a522f33949e5 100644 --- a/include/video.h +++ b/include/video.h @@ -85,6 +85,11 @@ enum video_format { * @fb_size: Frame buffer size * @copy_fb: Copy of the frame buffer to keep up to date; see struct * video_uc_plat + * @damage: A bounding box of framebuffer regions updated since last sync + * @damage.xstart: X start position in pixels from the left + * @damage.ystart: Y start position in pixels from the top + * @damage.xend: X end position in pixels from the left + * @damage.xend: Y end position in pixels from the top * @line_length: Length of each frame buffer line, in bytes. This can be * set by the driver, but if not, the uclass will set it after * probing @@ -112,6 +117,12 @@ struct video_priv { void *fb; int fb_size; void *copy_fb; + struct { + int xstart; + int ystart; + int xend; + int yend; + } damage; int line_length; u32 colour_fg; u32 colour_bg; @@ -254,8 +265,9 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, * @return: 0 on success, error code otherwise * * Some frame buffers are cached or have a secondary frame buffer. This - * function syncs these up so that the current contents of the U-Boot frame - * buffer are displayed to the user. + * function syncs the damaged parts of them up so that the current contents + * of the U-Boot frame buffer are displayed to the user. It clears the damage + * buffer. */ int video_sync(struct udevice *vid, bool force); @@ -375,6 +387,22 @@ static inline int video_sync_copy_all(struct udevice *dev) #endif +/** + * video_damage() - Notify the video subsystem about screen updates. + * + * @vid: Device to sync + * @x: Upper left X coordinate of the damaged rectangle + * @y: Upper left Y coordinate of the damaged rectangle + * @width: Width of the damaged rectangle + * @height: Height of the damaged rectangle + * + * Some frame buffers are cached or have a secondary frame buffer. This + * function notifies the video subsystem about rectangles that were updated + * within the frame buffer. They may only get written to the screen on the + * next call to video_sync(). + */ +void video_damage(struct udevice *vid, int x, int y, int width, int height); + /** * video_is_active() - Test if one video device it active *