Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions thorvg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(TVG_INC_DIR thorvg/src/bindings/capi)
set(TVG_SUBDIR "${CMAKE_CURRENT_SOURCE_DIR}/thorvg")
set(TVG_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/thorvg_build")
set(TVG_CROSS_CFG "${CMAKE_CURRENT_BINARY_DIR}/thorvg_build/cross_file.txt")
set(TVG_STATIC_LIB "${TVG_BUILD_DIR}/src/libthorvg-1.a")

set(TVG_LOADERS_OPTION "")

Expand All @@ -15,10 +16,6 @@ if(CONFIG_THORVG_SVG_LOADER_SUPPORT)
list(APPEND TVG_LOADERS_OPTION "svg")
endif()

if(CONFIG_THORVG_TVG_LOADER_SUPPORT)
list(APPEND TVG_LOADERS_OPTION "tvg")
endif()

if(CONFIG_THORVG_PNG_LOADER_SUPPORT)
list(APPEND TVG_LOADERS_OPTION "png")
endif()
Expand Down Expand Up @@ -50,6 +47,10 @@ idf_component_register(
INCLUDE_DIRS "${TVG_INC_DIR}"
PRIV_REQUIRES pthread)

target_compile_options(${COMPONENT_LIB} INTERFACE
$<$<COMPILE_LANGUAGE:C>:-Wno-ignored-qualifiers>
)


# Expands CMake flags that may contain response files (@"file" syntax) into a list.
# ESP-IDF v6 uses @"file" syntax for response files, but Meson doesn't support this.
Expand Down Expand Up @@ -122,10 +123,10 @@ ExternalProject_Add(${TVG_LIB}_target
-Dloaders=${TVG_LOADERS_OPTION} # Pass the loaders option to Meson
BUILD_COMMAND ninja -C ${TVG_BUILD_DIR}
INSTALL_COMMAND ""
BUILD_BYPRODUCTS ${TVG_BUILD_DIR}/src/${TVG_LIB}.a
BUILD_BYPRODUCTS ${TVG_STATIC_LIB}
)

add_prebuilt_library(${TVG_LIB} ${TVG_BUILD_DIR}/src/${TVG_LIB}.a PRIV_REQUIRES ${TVG_REQUIRES})
add_prebuilt_library(${TVG_LIB} ${TVG_STATIC_LIB} PRIV_REQUIRES ${TVG_REQUIRES})
add_dependencies(${TVG_LIB} ${TVG_LIB}_target)

if(TVG_THREADS STREQUAL "true")
Expand Down
4 changes: 0 additions & 4 deletions thorvg/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ menu "ThorVG Support Options"
bool "Enable Lottie loader support"
default y

config THORVG_TVG_LOADER_SUPPORT
bool "Enable tvg loader support"
default y

config THORVG_SVG_LOADER_SUPPORT
bool "Enable svg loader support"
default y
Expand Down
2 changes: 1 addition & 1 deletion thorvg/cross_file.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ld = '${CMAKE_LINKER}'
strip = '${CMAKE_STRIP}'

[built-in options]
cpp_args = ['-D_GNU_SOURCE','-D__linux__','-Wno-format','-fno-if-conversion','-Wno-deprecated-declarations','-Wno-stringop-truncation',${MESON_CXX_FLAGS}]
cpp_args = ['-D_GNU_SOURCE','-D__linux__','-Wno-format','-Wno-stringop-truncation',${MESON_CXX_FLAGS}]
cpp_link_args = [${MESON_LINKER_FLAGS}]

[host_machine]
Expand Down
2 changes: 1 addition & 1 deletion thorvg/examples/thorvg_lottie/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
idf_component_register(
SRCS "thorvg_example_main.c"
INCLUDE_DIRS "."
PRIV_REQUIRES esp_lcd)
PRIV_REQUIRES esp_lcd pthread)

littlefs_create_partition_image(storage ../lottie_files FLASH_IN_PROJECT)
111 changes: 77 additions & 34 deletions thorvg/examples/thorvg_lottie/main/thorvg_example_main.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/

#include <stdlib.h>
#include <dirent.h>
#include <pthread.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_check.h"
#include "esp_pthread.h"
#include "esp_heap_caps.h"
#include "esp_littlefs.h"
#include "esp_lcd_panel_ops.h"
Expand Down Expand Up @@ -69,25 +72,26 @@ static void argb888_to_rgb565(const uint32_t *in, uint16_t *out, size_t num_pixe
}
}

static void play_lottie(esp_lcd_panel_handle_t lcd_panel, uint32_t *canvas_buf_argb888, uint16_t *canvas_buf_rgb565)
static void play_lottie(esp_lcd_panel_handle_t lcd_panel, uint32_t *canvas_buf_argb888, uint16_t *canvas_buf_rgb565, SemaphoreHandle_t flush_done_sem)
{
// Initialize ThorVG engine
if (tvg_engine_init(TVG_ENGINE_SW, 0) != TVG_RESULT_SUCCESS) {
if (tvg_engine_init(0) != TVG_RESULT_SUCCESS) {
printf("Failed to initialize ThorVG engine\n");
abort();
}

// Create a canvas. Here, using SW engine and ARGB8888 buffer format
Tvg_Canvas *canvas = tvg_swcanvas_create();
// Create a software canvas backed by an ARGB8888 buffer.
// ThorVG renders into this buffer first, then we convert it to panel RGB565.
Tvg_Canvas canvas = tvg_swcanvas_create(TVG_ENGINE_OPTION_DEFAULT);
assert(canvas);
tvg_swcanvas_set_target(canvas, canvas_buf_argb888, EXAMPLE_LOTTIE_SIZE_HOR, EXAMPLE_LOTTIE_SIZE_HOR, EXAMPLE_LOTTIE_SIZE_VER, TVG_COLORSPACE_ARGB8888);
// flush the background with black
// Flush the background with black.
esp_lcd_panel_draw_bitmap(lcd_panel, 0, 0, EXAMPLE_LOTTIE_SIZE_HOR, EXAMPLE_LOTTIE_SIZE_VER, canvas_buf_rgb565);

// Create an animation object
Tvg_Animation *animation = tvg_animation_new();
Tvg_Animation animation = tvg_lottie_animation_new();
// Get the picture object from animation
Tvg_Paint *picture = tvg_animation_get_picture(animation);
Tvg_Paint picture = tvg_animation_get_picture(animation);

// Load the Lottie file (JSON)
if (tvg_picture_load(picture, EXAMPLE_LOTTIE_FILENAME) != TVG_RESULT_SUCCESS) {
Expand All @@ -96,34 +100,55 @@ static void play_lottie(esp_lcd_panel_handle_t lcd_panel, uint32_t *canvas_buf_a
}
// Resize the picture
tvg_picture_set_size(picture, EXAMPLE_LOTTIE_SIZE_HOR, EXAMPLE_LOTTIE_SIZE_VER);
// Push the animation to the canvas
tvg_canvas_push(canvas, picture);

// Play the animation frame by frame
float f_total;
float f = 0;
tvg_animation_get_total_frame(animation, &f_total);
while (f < f_total) {
tvg_animation_get_frame(animation, &f);
f++;
tvg_animation_set_frame(animation, f);
// add the picture to the canvas
tvg_canvas_add(canvas, picture);

// Play the animation frame by frame.
float total_frames;
tvg_animation_get_total_frame(animation, &total_frames);

for (float frame = 0.0f; frame < total_frames; frame += 1.0f) {
tvg_animation_set_frame(animation, frame);
tvg_canvas_update(canvas);
// Draw the canvas (renders to the buffer)
tvg_canvas_draw(canvas);
tvg_canvas_draw(canvas, false);
// Sync to ensure drawing is completed
tvg_canvas_sync(canvas);

// wait for the last flush is finished before reusing the canvas buffer
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// Convert the buffer from ARGB8888 to RGB565 and flush to the display
// Wait until the previous panel transfer is completed before reusing buffers.
xSemaphoreTake(flush_done_sem, portMAX_DELAY);
// Convert ARGB8888 to RGB565 and flush one full frame to the panel.
argb888_to_rgb565(canvas_buf_argb888, canvas_buf_rgb565, EXAMPLE_LOTTIE_SIZE_HOR * EXAMPLE_LOTTIE_SIZE_VER);
esp_lcd_panel_draw_bitmap(lcd_panel, 0, 0, EXAMPLE_LOTTIE_SIZE_HOR, EXAMPLE_LOTTIE_SIZE_VER, canvas_buf_rgb565);
}

// Cleanup
tvg_animation_del(animation);
tvg_canvas_destroy(canvas);
tvg_engine_term(TVG_ENGINE_SW);
tvg_engine_term();
}

typedef struct {
esp_lcd_panel_handle_t lcd_panel;
uint32_t *canvas_buf_argb888;
uint16_t *canvas_buf_rgb565;
SemaphoreHandle_t flush_done_sem;
} lottie_render_ctx_t;

static void *lottie_render_thread(void *arg)
{
lottie_render_ctx_t *ctx = (lottie_render_ctx_t *)arg;
uint32_t *canvas_buf_argb888 = ctx->canvas_buf_argb888;
uint16_t *canvas_buf_rgb565 = ctx->canvas_buf_rgb565;
esp_lcd_panel_handle_t lcd_panel = ctx->lcd_panel;
SemaphoreHandle_t flush_done_sem = ctx->flush_done_sem;

while (1) {
play_lottie(lcd_panel, canvas_buf_argb888, canvas_buf_rgb565, flush_done_sem);
vTaskDelay(pdMS_TO_TICKS(100));
}

return NULL;
}

static esp_err_t example_init_fs(void)
Expand Down Expand Up @@ -159,9 +184,9 @@ static esp_err_t example_init_fs(void)

static bool example_on_color_trans_done(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx)
{
TaskHandle_t task_handle = (TaskHandle_t)user_ctx;
SemaphoreHandle_t flush_done_sem = (SemaphoreHandle_t)user_ctx;
BaseType_t high_task_wakeup = pdFALSE;
vTaskNotifyGiveFromISR(task_handle, &high_task_wakeup);
xSemaphoreGiveFromISR(flush_done_sem, &high_task_wakeup);
return high_task_wakeup == pdTRUE;
}

Expand Down Expand Up @@ -200,11 +225,6 @@ void app_main(void)
};
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(EXAMPLE_LCD_SPI_HOST, &io_config, &io_handle));

esp_lcd_panel_io_callbacks_t cbs = {
.on_color_trans_done = example_on_color_trans_done,
};
esp_lcd_panel_io_register_event_callbacks(io_handle, &cbs, xTaskGetCurrentTaskHandle());

esp_lcd_panel_handle_t lcd_panel = NULL;
sh8601_vendor_config_t vendor_config = {
.init_cmds = lcd_init_cmds,
Expand All @@ -225,8 +245,31 @@ void app_main(void)
esp_lcd_panel_init(lcd_panel);
esp_lcd_panel_disp_on_off(lcd_panel, true);

while (1) {
play_lottie(lcd_panel, canvas_buf_argb888, canvas_buf_rgb565);
vTaskDelay(pdMS_TO_TICKS(100));
lottie_render_ctx_t render_ctx = {
.lcd_panel = lcd_panel,
.canvas_buf_argb888 = canvas_buf_argb888,
.canvas_buf_rgb565 = canvas_buf_rgb565,
.flush_done_sem = xSemaphoreCreateBinary(),
};
assert(render_ctx.flush_done_sem);

esp_lcd_panel_io_callbacks_t cbs = {
.on_color_trans_done = example_on_color_trans_done,
};
// Pass the semaphore as callback user data for frame-complete notification.
esp_lcd_panel_io_register_event_callbacks(io_handle, &cbs, render_ctx.flush_done_sem);

esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
cfg.thread_name = "lottie_render";
cfg.inherit_cfg = false;
cfg.stack_size = 30 * 1024;
ESP_ERROR_CHECK(esp_pthread_set_cfg(&cfg));

pthread_t thread;
int ret = pthread_create(&thread, NULL, lottie_render_thread, &render_ctx);
if (ret != 0) {
ESP_LOGE(TAG, "Failed to create render thread: %d", ret);
abort();
}
pthread_detach(thread);
}
2 changes: 0 additions & 2 deletions thorvg/examples/thorvg_lottie/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,3 @@
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_COMPILER_OPTIMIZATION_PERF=y

CONFIG_ESP_MAIN_TASK_STACK_SIZE=60000
2 changes: 1 addition & 1 deletion thorvg/examples/thorvg_lottie/sdkconfig.defaults.esp32s3
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_SPEED_80M=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y

CONFIG_ESP_TASK_WDT_TIMEOUT_S=10
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
11 changes: 2 additions & 9 deletions thorvg/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
version: "0.15.16"
version: "1.0.1"
description: "ThorVG is an open-source graphics library designed for creating vector-based scenes and animations"
url: https://github.com/espressif/idf-extra-components/tree/master/thorvg
repository: "https://github.com/espressif/idf-extra-components.git"
documentation: "https://github.com/thorvg/thorvg/blob/main/README.md"
documentation: "https://www.thorvg.org/native-apis"
issues: "https://github.com/espressif/idf-extra-components/issues"
dependencies:
idf: ">=5.1"
sbom:
manifests:
- path: sbom_thorvg.yml
dest: thorvg
files:
exclude:
- "thorvg/docs/**/*"
- "thorvg/examples/**/*"
- "thorvg/res/**/*"
- "thorvg/test/**/*"
- "thorvg/web/**/*"
4 changes: 2 additions & 2 deletions thorvg/sbom_thorvg.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: thorvg
version: 0.15.16
version: 1.0.1
cpe: cpe:2.3:a:thorvg:thorvg:{}:*:*:*:*:*:*:*
supplier: 'Organization: thorvg <https://github.com/thorvg/thorvg>'
description: ThorVG is an open-source graphics library designed for creating vector-based scenes and animations.
url: https://github.com/thorvg/thorvg
hash: e15069de7afcc5e853edf1561e69d9b8383e2c6c
hash: 6648d791972169d9cd22168f5bd11089bbec56c9
2 changes: 1 addition & 1 deletion thorvg/thorvg
Submodule thorvg updated 1120 files
Loading