Skip to content

Commit 8609a61

Browse files
committed
CB24FW-162: Implement display partial updates
* add cfb_framebuffer_set_updated_window API function for specifying update region Signed-off-by: Dmitry Konyshev <[email protected]>
1 parent 755d21f commit 8609a61

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

include/zephyr/display/cfb.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,19 @@ int cfb_invert_area(const struct device *dev, uint16_t x, uint16_t y,
179179
*/
180180
int cfb_framebuffer_finalize(const struct device *dev);
181181

182+
/**
183+
* @brief Set updated framebuffer area for partial updates.
184+
*
185+
* @param dev Pointer to device structure for driver instance
186+
* @param x Position in X direction of the beginning of area
187+
* @param y Position in Y direction of the beginning of area
188+
* @param ex Position in X direction of the end of area
189+
* @param ey Position in Y direction of the end of area
190+
*
191+
* @return 0 on success, negative value otherwise
192+
*/
193+
int cfb_framebuffer_set_updated_window(const struct device *dev, int x, int y, int ex, int ey);
194+
182195
/**
183196
* @brief Get display parameter.
184197
*

subsys/fb/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ config CHARACTER_FRAMEBUFFER_SHELL_DRIVER_NAME
3131
help
3232
Character Framebuffer Display Driver Name
3333

34+
config CBF_PARTIAL_UPDATES
35+
bool "Character Framebuffer Partial Update Support"
36+
default n
37+
help
38+
Set if hardware supports windowed display updates
39+
3440
module = CFB
3541
module-str = cfb
3642
source "subsys/logging/Kconfig.template.log_config"

subsys/fb/cfb.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ STRUCT_SECTION_END_EXTERN(cfb_font);
1919
#define LSB_BIT_MASK(x) BIT_MASK(x)
2020
#define MSB_BIT_MASK(x) (BIT_MASK(x) << (8 - x))
2121

22+
#ifndef CONFIG_CBF_PARTIAL_UPDATES
2223
#define DISP_NUM_PARTS (4)
24+
#endif
2325
#define DISP_BUF_SIZE (960 * 640 / 8)
2426

2527
static uint8_t fb_buf[DISP_BUF_SIZE];
28+
static int upd_win_x = -1, upd_win_y = -1, upd_win_ex = -1, upd_win_ey = -1;
2629

2730
static inline uint8_t byte_reverse(uint8_t b)
2831
{
@@ -458,6 +461,26 @@ int cfb_framebuffer_invert(const struct device *dev)
458461
return 0;
459462
}
460463

464+
int cfb_framebuffer_set_updated_window(const struct device *dev, int x, int y, int ex, int ey)
465+
{
466+
const struct display_driver_api *api = dev->api;
467+
struct display_capabilities cfg;
468+
469+
api->get_capabilities(dev, &cfg);
470+
471+
if (x < 0 || x > cfg.x_resolution || x > ex || ex > cfg.x_resolution || y < 0 ||
472+
y > cfg.y_resolution || y > ey || ey > cfg.y_resolution) {
473+
return -1;
474+
}
475+
476+
upd_win_x = (x < upd_win_x || upd_win_x < 0) ? (x & ~7) : upd_win_x;
477+
upd_win_ex = ex > upd_win_ex ? ((ex + 7) & ~7) : upd_win_ex;
478+
upd_win_y = (y < upd_win_y || upd_win_y < 0) ? (y & ~7) : upd_win_y;
479+
upd_win_ey = ey > upd_win_ey ? ((ey + 7) & ~7) : upd_win_ey;
480+
481+
return 0;
482+
}
483+
461484
int cfb_framebuffer_finalize(const struct device *dev)
462485
{
463486
const struct display_driver_api *api = dev->api;
@@ -470,27 +493,44 @@ int cfb_framebuffer_finalize(const struct device *dev)
470493
return -ENODEV;
471494
}
472495

496+
#ifndef CONFIG_CBF_PARTIAL_UPDATES
473497
desc.buf_size = fb->size / DISP_NUM_PARTS;
474498
desc.width = fb->x_res;
475499
desc.height = fb->y_res / DISP_NUM_PARTS;
476500
desc.pitch = fb->x_res;
501+
#else
502+
/* partial updates are implemented for full lines of frame buffer */
503+
desc.width = fb->x_res;
504+
desc.height = (upd_win_y < 0 || upd_win_ey < 0) ? fb->y_res : upd_win_ey - upd_win_y;
505+
desc.pitch = fb->x_res;
506+
desc.buf_size = desc.width * desc.height / fb->ppt;
507+
#endif
477508

478509
if (invert) {
479510
cfb_invert(fb);
480511
}
481512

482513
api->blanking_on(dev);
483514

515+
#ifndef CONFIG_CBF_PARTIAL_UPDATES
484516
for (int i = 0; i < fb->y_res; i += fb->y_res / DISP_NUM_PARTS) {
485517
err = api->write(dev, 0, i, &desc, &fb->buf[i * (fb->x_res / 8U)]);
486518
}
519+
#else
520+
err = api->write(dev, 0, upd_win_y, &desc, &fb->buf[upd_win_y * (fb->x_res / 8U)]);
521+
#endif
487522

488523
api->blanking_off(dev);
489524

490525
if (invert) {
491526
cfb_invert(fb);
492527
}
493528

529+
upd_win_x = -1;
530+
upd_win_ex = -1;
531+
upd_win_y = -1;
532+
upd_win_ey = -1;
533+
494534
return err;
495535
}
496536

0 commit comments

Comments
 (0)