Display and UI
Prefer the Host-provided LVGL table for ordinary UI. Write directly to the framebuffer only when you need per-pixel control.
Drawing text and controls#
- Include gm_plugin_lvgl_api.h and obtain the API table from host->graphics.lvgl.
- Check the table version, struct_size, and the functions you use.
- Call root_get() in on_start and create controls such as label and obj under the returned root.
- Update the UI with Host functions such as label_set_text, obj_set_pos and obj_set_size.
- Drive interaction with on_event and on_loop. On stop, release the objects you created without deleting the Host root.
Direct framebuffer drawing#
display_get_info reports the actual geometry. lock(y, &surface) returns the Host tile containing that row. Follow the returned y, height, stride, and pixel format, then unlock after drawing. GRAY_4 uses 4 bits per pixel, with two pixels in each byte.
- Drawing the full frame may require iterating over multiple tiles. Do not assume a fixed half-screen tile size.
- Submit intermediate tiles with present=false and only the last tile with present=true.
- Do not call LVGL while holding the framebuffer lock. Later LVGL refreshes may overwrite overlapping regions.
- Start by reusing the drawing flow in GlassSDK/examples/framebuffer, then change its content.
Images and animation#
Images and frame animation require LVGL API 1.1. First check GM_PLUGIN_VERSION_COMPATIBLE(ui->api_version, GM_PLUGIN_VERSION(1U, 1U)), ui->struct_size >= GM_PLUGIN_LVGL_API_1_1_SIZE, and the function pointers you use. Passing only the LVGL 1.0 minimum table-size check is insufficient for these new members.
| Contents | Layout and processing |
|---|---|
| Image format | GM_PLUGIN_LVGL_IMAGE_INDEXED_4BIT: a 64-byte palette (16 BGRA8888 entries) followed by row-by-row 4-bit pixel indices. Do not pass PNG/JPEG file bytes directly. |
| Pixel Position | Each row uses ceil(width / 2) bytes, without extra row padding. Even x uses the high 4 bits; odd x uses the low 4 bits. Palette alpha participates in compositing, but the final display remains GRAY_4. |
| Resource life cycle | The Host copies descriptors and animation frame lists but borrows pixel data. Keep that data valid and unchanged until you replace the source or delete the object. |
| Start Animation | anim_image_create does not start playback. Configure the frames and timing, then call anim_image_start. A repeat count of 0 plays once; use GM_PLUGIN_LVGL_ANIM_REPEAT_INFINITE to loop. |
Calculate memory use before increasing image size#
Each frame's pixel resource uses 64 + ceil(width / 2) × height bytes; multiply by the number of frames. One 75 × 65 frame uses 2534 bytes, and 4 frames use 10136 bytes. Application state, stack, messages, and temporary working memory require additional space.
- Reducing dimensions and frame count reduces resident memory. Increasing frame duration only lowers the update rate; it does not reduce stored frame data.
- Compressed ZIP size does not represent GMP runtime memory use. Add assets gradually and check outputs and physical-device behavior after each build.
Reference files in the toolkit#
- GlassSDK/include/gm_plugin_lvgl_api.h
- GlassSDK/docs/GRAPHICS.md
- GlassSDK/examples/image_animation