Four implementations of LCD interface in AWTK

Four Implementations of LCD Interface

LCD is an abstraction of the display device and provides basic drawing functions. It is not difficult to implement the LCD interface by yourself, but it takes a lot of effort. AWTK provides several default implementations. Using these default implementations, when porting to a new platform, generally only a small amount of code is required. .

Below we introduce several common LCD implementation methods:

1. LCD based on register implementation

On low-end embedded platforms, the memory is only a few tens of KB, and there is not enough memory to use the framebuffer, so coordinate and color data are usually written directly to the registers. lcd_reg.inc provides a register-based LCD. When using it to implement LCDs on different platforms, you only need to provide two macros:

  • set_window_func sets the area to write color data, which can greatly improve work efficiency compared to setting coordinates each time.
  • write_data_func Writes color data.

The following is the implementation of LCD on STMF103ze, where set_window_func is defined as TFT_SetWindow, and write_data_func is defined as TFT_WriteData:

#include "tftlcd.h"
#include "tkc/mem.h"
#include "lcd/lcd_reg.h"

typedef uint16_t pixel_t;

#define LCD_FORMAT BITMAP_FMT_BGR565
#define pixel_from_rgb(r, g, b)                                                \
  ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define pixel_to_rgba(p)                                                       \
  { (0xff & ((p >> 11) << 3)), (0xff & ((p >> 5) << 2)), (0xff & (p << 3)) }

#define set_window_func LCD_Set_Window
#define write_data_func LCD_WriteData_Color

#include "base/pixel.h"
#include "blend/pixel_ops.inc"
#include "lcd/lcd_reg.inc"

The register-based implementation has several limitations:

  • Due to memory and CPU performance issues, animations of any kind are not available.
  • Since reading the current content of the LCD is very slow, when it needs to be mixed with the background color, it is handled by the GUI itself (the APP does not need to care).
  • Flickering occurs when the screen is large.

In AWTK, this method is no longer recommended and an LCD based on fragment framebuffer implementation is a better choice.

2. LCD based on fragment frame buffer

On low-end embedded platforms, the memory is only a few tens of KB, and there is not enough memory to create a frame buffer for one screen, and the screen is prone to flicker using the register-based method.

A better approach is to create a small framebuffer, divide the screen into many small pieces, and draw only one small piece at a time. Due to the dirty rectangle mechanism, except when opening a new window, the drawing speed is still very fast under normal circumstances, which can effectively solve the flash problem.

lcd_mem_fragment.inc provides LCD based on fragment frame buffer. When using it to implement LCD on different platforms, you only need to provide two macros:

  • set_window_func sets the area to write color data, which can greatly improve work efficiency compared to setting coordinates each time.
  • write_data_func Writes color data.

The following is the implementation of LCD on STMF103ze, where set_window_func is defined as TFT_SetWindow, and write_data_func is defined as TFT_WriteData:

#include "tftlcd.h"

#include "tkc/mem.h"
#include "lcd/lcd_mem_fragment.h"

typedef uint16_t pixel_t;

#define LCD_FORMAT BITMAP_FMT_BGR565
#define pixel_from_rgb(r, g, b)                                                \
  ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define pixel_to_rgba(p)                                                       \
  { (0xff & ((p >> 11) << 3)), (0xff & ((p >> 5) << 2)), (0xff & (p << 3)) }

#define set_window_func LCD_Set_Window
#define write_data_func LCD_WriteData_Color

#include "base/pixel.h"
#include "blend/pixel_ops.inc"
#include "lcd/lcd_mem_fragment.inc"

3. LCD based on framebuffer

This is the most common way on embedded platforms. Generally, there are two framebuffers, one is called online framebuffer and the other is called offline framebuffer. The online framebuffer is the content of the current reality, and the offline framebuffer is the content that the GUI is currently drawing. lcd_mem_rgb565 provides LCD implementation in rgb565 format, and lcd_mem_rgba8888 provides LCD implementation in rgba8888 format.

The following is the implementation of LCD on STMF429:

extern u32 *ltdc_framebuf[2];
#define online_fb_addr (uint8_t*)ltdc_framebuf[0]
#define offline_fb_addr (uint8_t*)ltdc_framebuf[1]

lcd_t* platform_create_lcd(wh_t w, wh_t h) {
  return lcd_mem_rgb565_create_double_fb(w, h, online_fb_addr, offline_fb_addr);
}

4. LCD based on vgcanvas

On platforms that support OpenGL 3D hardware acceleration (such as PCs and mobile phones), we use nanovg to encapsulate OpenGL into a vgcanvas interface, and implement LCD on the basis of vgcanvas. lcd_vgcanvas.inc encapsulates vgcanvas into an LCD interface. For portability reasons, there is no function directly based on nanovg, but an interface based on vgcanvas, so when there is no GPU, if the CPU is powerful enough, it can also be based on agg/ picasso to achieve LCD.

It is implemented in this way and is generally not used on embedded platforms, and readers do not need to pay attention to it.

Summarize

The above implementation methods basically cover the most commonly used scenarios, so when porting AWTK to a new platform, you don't need to spend much effort on implementing the LCD interface.

{{o.name}}
{{m.name}}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324058673&siteId=291194637