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