1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(docs): batch 10 of proofread/edited docs (#7357)

Co-authored-by: Liam <30486941+liamHowatt@users.noreply.github.com>
This commit is contained in:
Victor Wheeler 2025-01-07 04:39:19 -07:00 committed by GitHub
parent 1f9f5f475f
commit 51aaf7bcde
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 165 additions and 42 deletions

View File

@ -9,11 +9,13 @@ depth, creating colors from hex code, converting between color depths,
mixing colors, etc. mixing colors, etc.
The type :cpp:type:`lv_color_t` is used to store a color in RGB888 format. The type :cpp:type:`lv_color_t` is used to store a color in RGB888 format.
This type and format is used in almost all APIs regardless to :cpp:expr:`LV_COLOR_DEPTH`. This type and format is used in almost all APIs regardless of :cpp:expr:`LV_COLOR_DEPTH`.
.. _color_create: .. _color_create:
Creating colors Creating Colors
*************** ***************
RGB RGB
@ -123,6 +125,8 @@ Built-in colors
:cpp:func:`lv_color_white` and :cpp:func:`lv_color_black` return ``0xFFFFFF`` and :cpp:func:`lv_color_white` and :cpp:func:`lv_color_black` return ``0xFFFFFF`` and
``0x000000`` respectively. ``0x000000`` respectively.
.. _color_opacity: .. _color_opacity:
Opacity Opacity
@ -135,13 +139,15 @@ Some special purpose defines are also introduced:
completely transparent completely transparent
- :cpp:enumerator:`LV_OPA_10` Value: 25, means the color covers only a little - :cpp:enumerator:`LV_OPA_10` Value: 25, means the color covers only a little
- ``LV_OPA_20 ... OPA_80`` follow logically - ``LV_OPA_20 ... OPA_80`` follow logically
- :cpp:enumerator:`LV_OPA_90` Value: 229, means the color near completely covers - :cpp:enumerator:`LV_OPA_90` Value: 229, means the color nearly completely covers
- :cpp:enumerator:`LV_OPA_COVER` Value: 255, means the color completely covers (full - :cpp:enumerator:`LV_OPA_COVER` Value: 255, means the color completely covers (full
opacity) opacity)
You can also use the ``LV_OPA_*`` defines in :cpp:func:`lv_color_mix` as a You can also use the ``LV_OPA_*`` defines in :cpp:func:`lv_color_mix` as a
mixing *ratio*. mixing *ratio*.
.. _color_api: .. _color_api:
API API

View File

@ -4,77 +4,194 @@
Drawing Pipeline Drawing Pipeline
================ ================
LVGL has a flexible and extendable drawing pipeline. You can hook it to do
some rendering with a GPU or even completely replace the built-in
software renderer.
Overview Overview
******** ********
Draw task Drawing is writing pixel colors into a buffer where they will be delivered to a
--------- display panel as pixels. Sometimes it involves computing those colors before they
are written (e.g. combining them with other colors when an object has partial opacity).
On modern computing hardware meant to be used with larger display panels, there are
sometimes options for different ways drawing can be accomplished. For example, some
MCUs come with hardware that is very good (and fast) at certain types of drawing
tasks. Alternatively, you might have access to a drawing library that performs
certain types of drawing tasks with great efficiency. To make it possible to utilize
such facilities in the most efficient fashion, LVGL v9 and onwards implements a
"Drawing Pipeline", like an assembly line, where decisions are made as to which
drawing tasks (:ref:`Draw Tasks`) are given to which "logic entities"
(:ref:`Draw Units`) in order to be carried out.
This Pipeline is designed so that it is both flexible and extendable. As a
programmer, you can hook into it in order to provide LVGL with guidance as to what
Draw Units should receive what types of Draw Tasks, or replace LVGL's built-in
software rendering logic to any degree you choose.
When :cpp:expr:`lv_draw_rect`, :cpp:expr:`lv_draw_label` or similar functions are called .. _draw tasks:
LVGL creates a so called draw task.
Draw unit Draw Tasks
--------- ----------
The draw tasks are collected in a list and periodically dispatched to draw units. A A "Draw Task" (:cpp:type:`lv_draw_task_t`) is a package of information that is
draw unit can a CPU core, a GPU, just a new rendering library for certain or all draw tasks, created at the beginning of the Drawing Pipeline when a request to draw is made.
or basically anything that can draw somehow. Functions such as :cpp:expr:`lv_draw_rect()` and :cpp:expr:`lv_draw_label()` create
one or more Draw Tasks and pass them down the Drawing Pipeline. Each Draw Task
carries all the information required to:
Draw task evaluation - compute which :ref:`Draw Unit <draw units>` should receive this task, and
- give the Draw Unit all the details required to accomplish the drawing task.
A Draw Task carries the following information:
:type: defines the drawing algorithm involved (e.g. line, fill, border, image,
label, arc, triangle, etc.)
:area: defines the rectangle involved where drawing will occur
:transformation matrix: if :c:macro:`LV_DRAW_TRANSFORM_USE_MATRIX` is configured to '1'
:state: waiting, queued, in progress, completed
:drawing descriptor: carries details of the drawing to be performed
:preferred Draw Unit ID: the ID of the Draw Unit that should take this task
:preference score: value describing the speed of the specified Draw Unit relative
to software rendering (more on this below)
:next: a link to the next drawing task in the list.
Draw Tasks are collected in a list and periodically dispatched to Draw Units.
.. _draw units:
Draw Units
----------
A "Draw Unit" (based on :cpp:type:`lv_draw_unit_t`) is any "logic entity" that can
generate the output required by a :ref:`Draw Task <draw tasks>`. This can be a CPU
core, a GPU, a new rendering library for certain (or all) Draw Tasks, or anything
that can accomplish drawing.
During LVGL's initialization (:cpp:func:`lv_init`), a list of Draw Units is created.
If :c:macro:`LV_USE_DRAW_SW` is set to ``1`` in ``lv_conf.h`` (it is by default), the
Software Drawing Unit enters itself at the head of that list. If your platform has
other drawing units available, if they are configured to be used in ``lv_conf.h``,
they are added to this list during LVGL's initialization. If you are adding your own
Draw Unit(s), you add each available drawing unit to that list by calling
:cpp:expr:`lv_draw_create_unit(sizeof(your_draw_unit_t))`. With each call to that
function, the newly-created draw unit is added to the head of that list, pushing
already-existing draw units further back in the list, making the earliest Draw Unit
created last in the list. The order of this list (and thus the order in which
:ref:`Draw Task Evaluation` is performed) is governed by the order in which each Draw
Unit is created.
Building this list (and initializing the Draw Units) is normally handled automatically
by configuring the available Draw Units in ``lv_conf.h``, such as setting
:c:macro:`LV_USE_DRAW_OPENGLES` or
:c:macro:`LV_USE_PXP` or
:c:macro:`LV_USE_DRAW_SDL` or
:c:macro:`LV_USE_DRAW_VG_LITE`
to ``1``. However, if you are introducing your own Draw Unit(s), you will need to
create and initialize it (after :cpp:func:`lv_init`) as above. This will include
several things, but setting its ``evaluate_cb`` and ``dispatch_cb`` callbacks
(mentioned later) are two of them.
For an example of how draw-unit cration and initialization is done, see
:cpp:func:`lv_draw_sw_init` in lv_draw_sw.c_ or the other draw units whose ``init``
functions are optionally called in :cpp:func:`lv_init`.
.. _draw task evaluation:
Draw Task Evaluation
-------------------- --------------------
Different draw units might render slight different output for example for an image transformation or When each :ref:`Draw Task <draw tasks>` is created, each existing Draw Unit is
a gradient. If such a draw task were assigned to a different draw units, the screen might jitter a "consulted" as to its "appropriateness" for the task. It does this through
little bit. To resolve it each draw unit has an ``evaluate_cb`` which is called when a draw task is created. an "evaluation callback" function pointer (a.k.a. ``evaluate_cb``), which each Draw
Based on the type and parameters of the draw task each draw unit can decide if it want to assign the Unit sets (for itself) during its initialization. Normally, that evaluation
draw task to itself. This way a certain type of draw task (e.g. rounded rectangle with horizontal optionally examines the existing "preference score" for the task mentioned above,
gradient) will be always assigned to the same draw unit. It avoid the above mentioned issue of and if it can accomplish that type of task (e.g. line drawing) faster than other
slight difference between draw units. Draw Units that have already reported, it writes its own "preference score" and
"preferred Draw Unit ID" to the respective fields in the task. In this way, by the
time the evaluation sequence is complete, the task will contain the score and the ID
of the Drawing Unit that will be used to perform that task when it is
:ref:`dispatched <draw task dispatching>`.
As a side effect, this also ensures that the same Draw Unit will be selected
consistently, depending on the type (and nature) of the drawing task, avoiding any
possible screen jitter in case more than one Draw Unit is capable of performing a
given task type.
The sequence of the Draw Unit list (with the Software Draw Unit at the end) also
ensures that the Software Draw Unit is the "buck-stops-here" Draw Unit: if no other
Draw Unit reported it was better at a given drawing task, then the Software Draw Unit
will handle it.
.. _draw task dispatching:
Dispatching Dispatching
----------- -----------
While collecting draw tasks LVGL frequently tries to dispatch the collected draw tasks to the draw units. While collecting Draw Tasks LVGL frequently dispatches the collected Draw Tasks to
This handles via the ``dispatch_cb`` of the draw units. their assigned Draw Units. This is handled via the ``dispatch_cb`` of the Draw Units.
If a draw unit is busy with another draw task, it just returns. However, it is available it can take a draw task. If a Draw Unit is busy with another Draw Task, it just returns. However, if it is
available it can take a Draw Task.
:cpp:expr:`lv_draw_get_next_available_task(layer, previous_task, draw_unit_id)` is a useful helper function which :cpp:expr:`lv_draw_get_next_available_task(layer, previous_task, draw_unit_id)` is a
returns an available draw task. "Available draw task" means that, all the draw tasks which should be drawn under a draw task useful helper function which is used by the ``dispatch_cb`` to get the next Draw Task
are ready and it is assigned to the given draw unit. it should act on. If it handled the task, it sets the Draw Task's ``state`` field to
:cpp:enumerator:`LV_DRAW_TASK_STATE_READY` (meaning "completed"). "Available" in
this context means that has been queued and assigned to a given Draw Unit and is
ready to be carried out. The ramifications of having multiple drawing threads are
taken into account for this.
Layers Layers
------ ------
A layer is a buffer with a given area on which rendering happens. Each display has a "main" layer, but A layer is a buffer with a given area on which the pixel rendering occurrs. Each
during rendering additional layers might be created internally to handle for example arbitrary widget transformations. display has a "main" layer, but during rendering additional layers might be created
internally to handle for example arbitrary Widget transformations.
Hierarchy of modules Object Hierarchy
-------------------- ----------------
All these together looks like this All of the above have this relationship at run time:
- list of draw units - LVGL
- display(s)
- layer(s): Each display has its own list of layers - list of Draw Units
- list of Display(s)
- draw tasks: Each layer has its own list of draw tasks - Layer(s): Each Display has its own list of Layers
- Draw Tasks: Each Layer has its own list of Draw Tasks
References
**********
As a reference take a look at `lv_draw_sw.c <https://github.com/lvgl/lvgl/blob/master/src/draw/sw/lv_draw_sw.c>`__ .. _draw_events:
Events
******
- :cpp:enumerator:`LV_EVENT_DRAW_TASK_ADDED` when each :ref:`Draw Task <draw tasks>`
is created and before it is dispatched to the :ref:`Draw Unit <draw units>` that
will handle it.
.. admonition:: Further Reading
Learn more about :ref:`lv_obj_events` emitted by all Widgets.
Learn more about :ref:`events`.
lv_draw_sw.c_
.. _lv_draw_sw.c: https://github.com/lvgl/lvgl/blob/master/src/draw/sw/lv_draw_sw.c
API API
*** ***