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:
parent
1f9f5f475f
commit
51aaf7bcde
@ -9,11 +9,13 @@ depth, creating colors from hex code, converting between color depths,
|
||||
mixing colors, etc.
|
||||
|
||||
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:
|
||||
|
||||
Creating colors
|
||||
Creating Colors
|
||||
***************
|
||||
|
||||
RGB
|
||||
@ -123,6 +125,8 @@ Built-in colors
|
||||
:cpp:func:`lv_color_white` and :cpp:func:`lv_color_black` return ``0xFFFFFF`` and
|
||||
``0x000000`` respectively.
|
||||
|
||||
|
||||
|
||||
.. _color_opacity:
|
||||
|
||||
Opacity
|
||||
@ -135,13 +139,15 @@ Some special purpose defines are also introduced:
|
||||
completely transparent
|
||||
- :cpp:enumerator:`LV_OPA_10` Value: 25, means the color covers only a little
|
||||
- ``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
|
||||
opacity)
|
||||
|
||||
You can also use the ``LV_OPA_*`` defines in :cpp:func:`lv_color_mix` as a
|
||||
mixing *ratio*.
|
||||
|
||||
|
||||
|
||||
.. _color_api:
|
||||
|
||||
API
|
||||
|
@ -4,77 +4,194 @@
|
||||
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
|
||||
********
|
||||
|
||||
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
|
||||
LVGL creates a so called draw task.
|
||||
.. _draw tasks:
|
||||
|
||||
Draw unit
|
||||
---------
|
||||
Draw Tasks
|
||||
----------
|
||||
|
||||
The draw tasks are collected in a list and periodically dispatched to draw units. A
|
||||
draw unit can a CPU core, a GPU, just a new rendering library for certain or all draw tasks,
|
||||
or basically anything that can draw somehow.
|
||||
A "Draw Task" (:cpp:type:`lv_draw_task_t`) is a package of information that is
|
||||
created at the beginning of the Drawing Pipeline when a request to draw is made.
|
||||
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
|
||||
a gradient. If such a draw task were assigned to a different draw units, the screen might jitter a
|
||||
little bit. To resolve it each draw unit has an ``evaluate_cb`` which is called when a draw task is created.
|
||||
Based on the type and parameters of the draw task each draw unit can decide if it want to assign the
|
||||
draw task to itself. This way a certain type of draw task (e.g. rounded rectangle with horizontal
|
||||
gradient) will be always assigned to the same draw unit. It avoid the above mentioned issue of
|
||||
slight difference between draw units.
|
||||
When each :ref:`Draw Task <draw tasks>` is created, each existing Draw Unit is
|
||||
"consulted" as to its "appropriateness" for the task. It does this through
|
||||
an "evaluation callback" function pointer (a.k.a. ``evaluate_cb``), which each Draw
|
||||
Unit sets (for itself) during its initialization. Normally, that evaluation
|
||||
optionally examines the existing "preference score" for the task mentioned above,
|
||||
and if it can accomplish that type of task (e.g. line drawing) faster than other
|
||||
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
|
||||
-----------
|
||||
|
||||
While collecting draw tasks LVGL frequently tries to dispatch the collected draw tasks to the draw units.
|
||||
This handles via the ``dispatch_cb`` of the draw units.
|
||||
While collecting Draw Tasks LVGL frequently dispatches the collected Draw Tasks to
|
||||
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
|
||||
returns an available draw task. "Available draw task" means that, all the draw tasks which should be drawn under a draw task
|
||||
are ready and it is assigned to the given draw unit.
|
||||
:cpp:expr:`lv_draw_get_next_available_task(layer, previous_task, draw_unit_id)` is a
|
||||
useful helper function which is used by the ``dispatch_cb`` to get the next Draw Task
|
||||
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
|
||||
------
|
||||
|
||||
A layer is a buffer with a given area on which rendering happens. Each display has a "main" layer, but
|
||||
during rendering additional layers might be created internally to handle for example arbitrary widget transformations.
|
||||
A layer is a buffer with a given area on which the pixel rendering occurrs. Each
|
||||
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
|
||||
- display(s)
|
||||
- LVGL
|
||||
|
||||
- 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
|
||||
***
|
||||
|
Loading…
x
Reference in New Issue
Block a user