AWTK 中 LCD 接口的四種實現方式

LCD 接口的四種實現方式

LCD 是對顯示設備的抽象,提供了基本的繪圖函數。本身去實現 LCD 接口雖然不難,可是須要花費很多功夫,AWTK 提供了幾種缺省的實現,利用這些缺省的實現,在移植到新的平臺時,通常只須要不多的代碼就好了。canvas

下面咱們介紹一下幾種常見的 LCD 實現方式:函數

1、基於寄存器實現的 LCD

在低端的嵌入式平臺上,內存只有幾十 KB,沒有足夠的內存使用 framebuffer,一般直接向寄存器中寫入座標和顏色數據。lcd_reg.inc 提供了基於寄存器實現的 LCD,用它實現不一樣平臺的 LCD 時,只須要提供兩個宏便可:性能

  • set_window_func 設置要寫入顏色數據的區域,相對於每次設置座標而言,能夠極大提升工做效率。
  • write_data_func 寫入顏色數據。

下面是 STMF103ze 上 LCD 的實現,這裏把 set_window_func 定義爲 TFT_SetWindow,把 write_data_func 定義爲 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"

基於寄存器實現的實現有幾個限制:ui

  • 因爲內存和 CPU 性能的問題,不提供任何類型的動畫。
  • 因爲讀取 LCD 當前內容速度很慢,因此須要與底色進行混合時,由 GUI 本身處理 (APP 無需關心)。
  • 屏幕大時會出現閃爍。

在 AWTK 中,再也不推薦此方法,基於片斷幀緩衝實現的 LCD 是更好的選擇。code

2、基於片斷幀緩衝實現的 LCD

在低端的嵌入式平臺上,內存只有幾十 KB,沒有足夠的內存建立一屏的幀緩衝,而使用基於寄存器的方式屏幕容易閃爍。orm

比較好的辦法是,建立一小塊幀緩衝,把屏幕分紅不少小塊,一次只繪製一小塊。因爲有髒矩形機制,除了打開新窗口時,在正常狀況下,繪製速度仍然很快,能夠有效的解決閃速問題。接口

lcd_mem_fragment.inc 提供了基於片斷幀緩衝實現的 LCD,用它實現不一樣平臺的 LCD 時,只須要提供兩個宏便可:內存

  • set_window_func 設置要寫入顏色數據的區域,相對於每次設置座標而言,能夠極大提升工做效率。
  • write_data_func 寫入顏色數據。

下面是 STMF103ze 上 LCD 的實現,這裏把 set_window_func 定義爲 TFT_SetWindow,把 write_data_func 定義爲 TFT_WriteData:it

#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、基於 framebuffer 實現的 LCD

這是在嵌入式平臺上最多見的方式。通常有兩個 framebuffer,一個稱爲 online framebuffer,一個稱爲 offline framebuffer。online framebuffer 是當前現實的內容,offline framebuffer 是 GUI 當前正在繪製的內容。lcd_mem_rgb565 提供了 rgb565 格式的 LCD 實現,lcd_mem_rgba8888 提供了 rgba8888 格式的 LCD 實現,它們都是在 lcd_mem.inc 基礎上實現的,要增長新的格式也是很方便的。

下面是 STMF429 上 LCD 的實現:

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、基於 vgcanvas 實現的 LCD

在支持 OpenGL 3D 硬件加速的平臺上(如 PC 和手機),咱們使用 nanovg 把 OpenGL 封裝成 vgcanvas 的接口,在 vgcanvas 基礎之上實現 LCD。lcd_vgcanvas.inc 將 vgcanvas 封裝成 LCD 的接口,這裏出於可移植性考慮,並無直接基於 nanovg 的函數,而是基於 vgcanvas 的接口,因此在沒有 GPU 時,若是 CPU 夠強大,也是能夠基於 agg/picasso 去實現的 LCD。

這種方式實現,通常不會在嵌入平臺上使用,讀者不須要關注它。

總結

以上幾種實現方式,基本上涵蓋了最經常使用的場景,因此在移植 AWTK 到新的平臺時,並不須要在實現 LCD 接口上費多少功夫。

相關文章
相關標籤/搜索