Hardware Agnostic Graphics Library for Embedded

Thu, Apr 16, 2020

What started as a project to learn C, I have now been using in all my hobby projects. HAGL is a hardware agnostic graphics library for embedded projects. It supports basic geometric primitives, bitmaps, blitting, fixed width fonts and an optional framebuffer.

Yet another graphics library?

Most embedded hobbyist projects do not seem to care about code reuse. Instead there is a graphics library for everydifferentdisplaydriver for every different architecture. They all implement the same functions for drawing the graphical primitives This feels wrong. Graphics library should not know anything about the underlying hardware, responsibilities should be separated.

HAGL takes a different approach. It contains code only for drawing the primitives. It can be used with any microcontroller and display driver. It can also be used with normal computers. This is useful for testing your graphics code without need to flash it to the microcontroller.

Hardware abstraction layer

To use Copepod with your microcontroller and display driver you must provide a HAL. The only mandatory function for HAL to provide is for putting a single pixel on the display. Copepod will use the putpixel funtion to draw all the other graphical primitives. For examples of this see libgd HAL and libsdl2 HAL.

For improved speed the HAL can also provide accelerated functions for bitmap blitting and horizontal and vertical lines. See ESP MIPI DCS HAL for an example of a hardware accelerated HAL. This is also the one I use with my ESP32 projects. It supports most of the displays hobbyists currently use.

How fast is it?

Speed mostly depends on two things. Everything is much faster when double buffering is enabled. Also the HAL implementation dictates a lot. I have been testing with the TTGO T-Display, TTGO T4, M5StickC and M5Stack.

NOTE! Links above are affiliate links. If you buy something I will be a happy puppy.

In the below table numbers are operations per second with double buffering. ESP32 is clocked at the default 160MHz. Bigger number is better. T-Display and M5StickC have higher numbers because they have smaller resolution. Smaller resolution means less bytes to push to the display.

T4

T-Display

M5Stack

M5StickC

hagl_put_pixel()

304400

304585

340850

317094

hagl_draw_line()

10485

14942

12145

31293

hagl_draw_circle()

15784

16430

17730

18928

hagl_fill_circle()

8712

9344

9982

13910

hagl_draw_ellipse()

8187

8642

9168

10019

hagl_fill_ellipse()

3132

3457

3605

5590

hagl_draw_triangle()

3581

5137

4160

11186

hagl_fill_triangle()

1246

1993

1654

6119

hagl_draw_rectangle()

22759

30174

26910

64259

hagl_fill_rectangle()

2191

4849

2487

16146

hagl_draw_rounded_rectangle()

17660

21993

20736

39102

hagl_fill_rounded_rectangle()

2059

4446

2313

13270

hagl_draw_polygon()

2155

3096

2494

6763

hagl_fill_polygon()

692

1081

938

3295

hagl_put_char()

29457

29131

32429

27569

hagl_flush()

32

76

32

96

When double buffering is disabled everything is much slower. On the positive side you save lots of memory.