创建和管理绘制任务相关的函数

本文详细介绍了LVGL图形库中与绘制任务相关的函数,包括初始化、关闭、创建、调度和管理等,涉及lv_draw_init、lv_draw_deinit、lv_draw_create_unit等关键函数。这些函数用于创建和管理绘制任务、分配和释放图层缓冲区、调度绘制单元以及处理图层的创建和内存管理,是实现LVGL图形界面高效绘制和动态更新的基础。
摘要由CSDN通过智能技术生成

主要介绍与绘制任务相关的函数。这些函数负责创建和管理绘制任务、分配和释放图层缓冲区、调度绘制单元以及处理图层的创建和内存管理。

定义的函数和解析

1. lv_draw_init:


   - 初始化绘制模块,如果启用了操作系统支持,则初始化线程同步机制。lv_draw_init 函数是 LVGL 图形库中用于初始化绘制系统的函数。这个函数的作用是设置绘制系统的基本状态,并准备绘制任务的同步机制。这是在使用 LVGL 进行图形绘制之前必须执行的初始化步骤。

void lv_draw_init(void)
{
#if LV_USE_OS
    lv_thread_sync_init(&_draw_info.sync);
#endif
}
  1. 函数参数:

    • 无参数,这个函数用于初始化绘制系统。
  2. 函数逻辑:

    • 函数首先检查是否定义了 LV_USE_OS,这个宏通常表示 LVGL 被配置为在支持操作系统的环境中运行。
    • 如果 LV_USE_OS 被定义,函数调用 lv_thread_sync_init 来初始化一个线程同步对象 _draw_info.sync。这个同步对象用于在多线程环境中同步绘制任务的执行,确保绘制操作的线程安全。
  3. 使用场景:

    • lv_draw_init 函数通常在 LVGL 应用程序的初始化阶段被调用,确保绘制系统准备好处理后续的绘制任务。
  4. 注意事项:

    • lv_draw_init 函数应该在应用程序的其他部分(如创建窗口、添加控件等)之前调用。
    • 如果应用程序不运行在支持操作系统的环境中,LV_USE_OS 宏可能不会被定义,这时线程同步初始化代码将不会被执行。
    • 该函数的调用通常只需要进行一次,以确保绘制系统的初始化。

通过 lv_draw_init 函数,LVGL 应用程序可以确保绘制系统已经正确初始化,准备好处理即将到来的绘制任务。这是实现 LVGL 应用程序图形界面的基础。

2. lv_draw_deinit:


   - 反初始化绘制模块,释放所有绘制单元和任务资源。lv_draw_deinit 函数是 LVGL 图形库中用于关闭和清理绘制系统的函数。这个函数的目的是在应用程序结束时释放绘制模块所分配的所有资源,确保没有任何内存泄漏或其他资源问题。

void lv_draw_deinit(void)
{
#if LV_USE_OS
    lv_thread_sync_delete(&_draw_info.sync);
#endif

    lv_draw_unit_t * u = _draw_info.unit_head;
    while(u) {
        lv_draw_unit_t * cur_unit = u;
        u = u->next;

        if(cur_unit->delete_cb) cur_unit->delete_cb(cur_unit);
        lv_free(cur_unit);
    }
    _draw_info.unit_head = NULL;
}
  1. 函数参数:

    • 无参数,这个函数用于清理和关闭绘制系统。
  2. 函数逻辑:

    • 函数首先检查是否定义了 LV_USE_OS,如果定义了,说明 LVGL 配置为在支持操作系统的环境中运行,这时会调用 lv_thread_sync_delete 来删除之前初始化的线程同步对象 _draw_info.sync
    • 接下来,函数遍历绘制单元链表 _draw_info.unit_head,这个链表包含了所有已创建的绘制单元。
    • 对于每个绘制单元,如果它有一个关联的删除回调函数 delete_cb,则调用该回调函数来执行任何必要的清理工作。
    • 遍历完成后,释放每个绘制单元所占用的内存,并将绘制单元头指针 _draw_info.unit_head 设置为 NULL,表示绘制单元链表已被清空。
  3. 使用场景:

    • lv_draw_deinit 函数通常在 LVGL 应用程序的退出流程中被调用,以确保所有绘制相关的资源都被正确释放。
  4. 注意事项:

    • 在调用 lv_draw_deinit 函数之前,应确保所有的绘制任务都已完成,且不再有对绘制系统的引用。
    • 如果应用程序不运行在支持操作系统的环境中,LV_USE_OS 宏可能不会被定义,这时线程同步删除代码将不会被执行。
    • 该函数的调用通常只需要进行一次,以确保绘制系统的清理。

通过 lv_draw_deinit 函数,LVGL 应用程序可以确保在应用程序结束时绘制系统占用的所有资源都得到了妥善处理,这对于避免资源泄漏和确保应用程序的稳定退出非常重要。

3. lv_draw_create_unit:


   - 创建一个新的绘制单元。lv_draw_create_unit 函数是 LVGL 图形库中用于创建新的绘制单元(lv_draw_unit_t)的函数。绘制单元是 LVGL 绘制系统中的一个概念,它代表了可以执行绘制任务的实体。这些单元可以是软件渲染单元,也可以是硬件加速单元,具体取决于 LVGL 的配置和目标平台的能力。

void * lv_draw_create_unit(size_t size)
{
    lv_draw_unit_t * new_unit = lv_malloc_zeroed(size);

    new_unit->next = _draw_info.unit_head;
    _draw_info.unit_head = new_unit;

    return new_unit;
}
  1. 函数参数:

    • size_t size: 要分配的内存大小,这个大小应该足以容纳 lv_draw_unit_t 结构体以及可能的额外数据。
  2. 函数逻辑:

    • 首先,函数调用 lv_malloc_zeroed 来分配指定大小的内存,并将其初始化为零。这样可以确保新创建的绘制单元的成员变量具有初始值。
    • 接着,函数将新创建的绘制单元 new_unit 的 next 指针设置为指向当前的绘制单元头 _draw_info.unit_head。这样做是为了将新单元添加到绘制单元链表的开头。
    • 然后,函数更新绘制单元头指针 _draw_info.unit_head 为指向新的绘制单元,这样新单元就成为了链表的第一个元素。
    • 最后,函数返回指向新创建的绘制单元的指针。
  3. 使用场景:

    • lv_draw_create_unit 函数通常在 LVGL 应用程序初始化阶段被调用,用于创建绘制单元以准备执行绘制任务。
    • 这个函数也可以在运行时动态创建新的绘制单元,例如,当需要增加额外的绘制能力或使用特定的硬件加速功能时。
  4. 注意事项:

    • 在调用 lv_draw_create_unit 函数时,传入的 size 参数必须确保足够大,以容纳 lv_draw_unit_t 结构体和任何额外的数据。
    • 创建绘制单元后,需要设置该单元的回调函数,如 delete_cbdispatch_cb 和 evaluate_cb,以便 LVGL 能够正确地使用该单元来执行绘制任务。
    • 该函数返回的 lv_draw_unit_t 指针应该被存储起来,以便在需要时可以对其进行操作或在不再需要时进行清理。

通过 lv_draw_create_unit 函数,LVGL 应用程序可以创建新的绘制单元,从而扩展其绘制能力。这些单元可以被配置和优化,以适应不同的绘制任务和性能要求。

4. lv_draw_add_task:


   - 向指定图层添加一个新的绘制任务。lv_draw_add_task 函数是 LVGL 图形库中用于向指定图层添加新的绘制任务的函数。绘制任务是 LVGL 绘制流程中的基本单位,代表了需要绘制到屏幕上的图形元素,如形状、文本、图像等。

lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords)
{
    LV_PROFILER_BEGIN;

    lv_draw_task_t * new_task = lv_malloc_zeroed(sizeof(lv_draw_task_t));

    new_task->area = *coords;  // 设置任务的坐标区域
    new_task->_real_area = *coords;  // 设置任务的实际坐标区域,通常与 area 相同
    new_task->clip_area = layer->_clip_area;  // 设置任务的裁剪区域为图层的裁剪区域
    new_task->state = LV_DRAW_TASK_STATE_QUEUED;  // 将任务状态设置为已排队

    // 查找图层的最后一个任务
    if(layer->draw_task_head == NULL) {
        layer->draw_task_head = new_task;  // 如果任务列表为空,则将新任务设为头节点
    } else {
        lv_draw_task_t * tail = layer->draw_task_head;
        while(tail->next) tail = tail->next;  // 遍历任务列表,找到最后一个任务

        tail->next = new_task;  // 将新任务添加到任务列表的末尾
    }

    LV_PROFILER_END;
    return new_task;  // 返回新创建的任务指针
}
  1. 函数参数:

    • lv_layer_t * layer: 指向目标图层的指针,新任务将添加到这个图层上。
    • const lv_area_t * coords: 指向 lv_area_t 结构体的指针,定义了任务的坐标区域。
  2. 函数逻辑:

    • 首先,函数使用 lv_malloc_zeroed 分配并初始化一个新的 lv_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值