1.. _draw: 2 3================ 4Drawing Pipeline 5================ 6 7 8Overview 9******** 10 11Drawing is writing pixel colors into a buffer where they will be delivered to a 12display panel as pixels. Sometimes it involves computing those colors before they 13are written (e.g. combining them with other colors when an object has partial opacity). 14 15On modern computing hardware meant to be used with larger display panels, there are 16sometimes options for different ways drawing can be accomplished. For example, some 17MCUs come with hardware that is very good (and fast) at certain types of drawing 18tasks. Alternatively, you might have access to a drawing library that performs 19certain types of drawing tasks with great efficiency. To make it possible to utilize 20such facilities in the most efficient fashion, LVGL v9 and onwards implements a 21"Drawing Pipeline", like an assembly line, where decisions are made as to which 22drawing tasks (:ref:`Draw Tasks`) are given to which "logic entities" 23(:ref:`Draw Units`) in order to be carried out. 24 25This Pipeline is designed so that it is both flexible and extendable. As a 26programmer, you can hook into it in order to provide LVGL with guidance as to what 27Draw Units should receive what types of Draw Tasks, or replace LVGL's built-in 28software rendering logic to any degree you choose. 29 30 31.. _draw tasks: 32 33Draw Tasks 34---------- 35 36A "Draw Task" (:cpp:type:`lv_draw_task_t`) is a package of information that is 37created at the beginning of the Drawing Pipeline when a request to draw is made. 38Functions such as :cpp:expr:`lv_draw_rect()` and :cpp:expr:`lv_draw_label()` create 39one or more Draw Tasks and pass them down the Drawing Pipeline. Each Draw Task 40carries all the information required to: 41 42- compute which :ref:`Draw Unit <draw units>` should receive this task, and 43- give the Draw Unit all the details required to accomplish the drawing task. 44 45A Draw Task carries the following information: 46 47:type: defines the drawing algorithm involved (e.g. line, fill, border, image, 48 label, arc, triangle, etc.) 49:area: defines the rectangle involved where drawing will occur 50:transformation matrix: if :c:macro:`LV_DRAW_TRANSFORM_USE_MATRIX` is configured to '1' 51:state: waiting, queued, in progress, completed 52:drawing descriptor: carries details of the drawing to be performed 53:preferred Draw Unit ID: the ID of the Draw Unit that should take this task 54:preference score: value describing the speed of the specified Draw Unit relative 55 to software rendering (more on this below) 56:next: a link to the next drawing task in the list. 57 58Draw Tasks are collected in a list and periodically dispatched to Draw Units. 59 60 61.. _draw units: 62 63Draw Units 64---------- 65 66A "Draw Unit" (based on :cpp:type:`lv_draw_unit_t`) is any "logic entity" that can 67generate the output required by a :ref:`Draw Task <draw tasks>`. This can be a CPU 68core, a GPU, a new rendering library for certain (or all) Draw Tasks, or anything 69that can accomplish drawing. 70 71During LVGL's initialization (:cpp:func:`lv_init`), a list of Draw Units is created. 72If :c:macro:`LV_USE_DRAW_SW` is set to ``1`` in ``lv_conf.h`` (it is by default), the 73Software Drawing Unit enters itself at the head of that list. If your platform has 74other drawing units available, if they are configured to be used in ``lv_conf.h``, 75they are added to this list during LVGL's initialization. If you are adding your own 76Draw Unit(s), you add each available drawing unit to that list by calling 77:cpp:expr:`lv_draw_create_unit(sizeof(your_draw_unit_t))`. With each call to that 78function, the newly-created draw unit is added to the head of that list, pushing 79already-existing draw units further back in the list, making the earliest Draw Unit 80created last in the list. The order of this list (and thus the order in which 81:ref:`Draw Task Evaluation` is performed) is governed by the order in which each Draw 82Unit is created. 83 84Building this list (and initializing the Draw Units) is normally handled automatically 85by configuring the available Draw Units in ``lv_conf.h``, such as setting 86:c:macro:`LV_USE_DRAW_OPENGLES` or 87:c:macro:`LV_USE_PXP` or 88:c:macro:`LV_USE_DRAW_SDL` or 89:c:macro:`LV_USE_DRAW_VG_LITE` 90to ``1``. However, if you are introducing your own Draw Unit(s), you will need to 91create and initialize it (after :cpp:func:`lv_init`) as above. This will include 92several things, but setting its ``evaluate_cb`` and ``dispatch_cb`` callbacks 93(mentioned later) are two of them. 94 95For an example of how draw-unit cration and initialization is done, see 96:cpp:func:`lv_draw_sw_init` in lv_draw_sw.c_ or the other draw units whose ``init`` 97functions are optionally called in :cpp:func:`lv_init`. 98 99 100.. _draw task evaluation: 101 102Draw Task Evaluation 103-------------------- 104 105When each :ref:`Draw Task <draw tasks>` is created, each existing Draw Unit is 106"consulted" as to its "appropriateness" for the task. It does this through 107an "evaluation callback" function pointer (a.k.a. ``evaluate_cb``), which each Draw 108Unit sets (for itself) during its initialization. Normally, that evaluation 109optionally examines the existing "preference score" for the task mentioned above, 110and if it can accomplish that type of task (e.g. line drawing) faster than other 111Draw Units that have already reported, it writes its own "preference score" and 112"preferred Draw Unit ID" to the respective fields in the task. In this way, by the 113time the evaluation sequence is complete, the task will contain the score and the ID 114of the Drawing Unit that will be used to perform that task when it is 115:ref:`dispatched <draw task dispatching>`. 116 117As a side effect, this also ensures that the same Draw Unit will be selected 118consistently, depending on the type (and nature) of the drawing task, avoiding any 119possible screen jitter in case more than one Draw Unit is capable of performing a 120given task type. 121 122The sequence of the Draw Unit list (with the Software Draw Unit at the end) also 123ensures that the Software Draw Unit is the "buck-stops-here" Draw Unit: if no other 124Draw Unit reported it was better at a given drawing task, then the Software Draw Unit 125will handle it. 126 127 128.. _draw task dispatching: 129 130Dispatching 131----------- 132 133While collecting Draw Tasks LVGL frequently dispatches the collected Draw Tasks to 134their assigned Draw Units. This is handled via the ``dispatch_cb`` of the Draw Units. 135 136If a Draw Unit is busy with another Draw Task, it just returns. However, if it is 137available it can take a Draw Task. 138 139:cpp:expr:`lv_draw_get_next_available_task(layer, previous_task, draw_unit_id)` is a 140useful helper function which is used by the ``dispatch_cb`` to get the next Draw Task 141it should act on. If it handled the task, it sets the Draw Task's ``state`` field to 142:cpp:enumerator:`LV_DRAW_TASK_STATE_READY` (meaning "completed"). "Available" in 143this context means that has been queued and assigned to a given Draw Unit and is 144ready to be carried out. The ramifications of having multiple drawing threads are 145taken into account for this. 146 147 148Layers 149------ 150 151A layer is a buffer with a given area on which the pixel rendering occurrs. Each 152display has a "main" layer, but during rendering additional layers might be created 153internally to handle for example arbitrary Widget transformations. 154 155 156Object Hierarchy 157---------------- 158 159All of the above have this relationship at run time: 160 161- LVGL 162 163 - list of Draw Units 164 - list of Display(s) 165 166 - Layer(s): Each Display has its own list of Layers 167 168 - Draw Tasks: Each Layer has its own list of Draw Tasks 169 170 171 172.. _draw_events: 173 174Events 175****** 176 177- :cpp:enumerator:`LV_EVENT_DRAW_TASK_ADDED` when each :ref:`Draw Task <draw tasks>` 178 is created and before it is dispatched to the :ref:`Draw Unit <draw units>` that 179 will handle it. 180 181 182 183.. admonition:: Further Reading 184 185 Learn more about :ref:`lv_obj_events` emitted by all Widgets. 186 187 Learn more about :ref:`events`. 188 189 lv_draw_sw.c_ 190 191 192.. _lv_draw_sw.c: https://github.com/lvgl/lvgl/blob/master/src/draw/sw/lv_draw_sw.c 193 194 195 196API 197*** 198 199