Compare commits
129 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6d7be00bf | ||
|
|
15433d69b9 | ||
|
|
9491c3ff6d | ||
|
|
3de61c76af | ||
|
|
09cc0de573 | ||
|
|
227ac02341 | ||
|
|
8b83fe7ea5 | ||
|
|
edd5ad28ad | ||
|
|
07bce7466d | ||
|
|
1713cd3fd8 | ||
|
|
cb602ea778 | ||
|
|
caf29ef0c5 | ||
|
|
a3199514ab | ||
|
|
78cbdfc151 | ||
|
|
75e6ef4e1d | ||
|
|
2376c57860 | ||
|
|
e3659c46b1 | ||
|
|
df96b57f4e | ||
|
|
67b3011f83 | ||
|
|
d87737612a | ||
|
|
6a89bd2d74 | ||
|
|
6843c191b7 | ||
|
|
1caafc55dd | ||
|
|
5ba90a5c41 | ||
|
|
630da9c6ca | ||
|
|
ee95e7dc25 | ||
|
|
45b13c378f | ||
|
|
2b56e04205 | ||
|
|
177900b033 | ||
|
|
203e7fc97d | ||
|
|
7345e62355 | ||
|
|
48d7878bac | ||
|
|
a0795b49e8 | ||
|
|
a150b15e45 | ||
|
|
a95714ba7c | ||
|
|
8536152d81 | ||
|
|
6314441839 | ||
|
|
88c51b22ad | ||
|
|
6b0092c0d9 | ||
|
|
aa313806d0 | ||
|
|
5e0e1c8c4e | ||
|
|
d0e19eb2d3 | ||
|
|
fd20fabfda | ||
|
|
399069b4a2 | ||
|
|
501230e0fc | ||
|
|
adcf166382 | ||
|
|
2f294aa76c | ||
|
|
9a870b34a9 | ||
|
|
0b7777f27a | ||
|
|
e8d8f399e0 | ||
|
|
0df09db23e | ||
|
|
e2386fd46d | ||
|
|
2944277f07 | ||
|
|
6af01798d8 | ||
|
|
77670fb1a5 | ||
|
|
f29514aa5c | ||
|
|
e7e8cf846d | ||
|
|
8b1270347f | ||
|
|
e6cd7063b6 | ||
|
|
34c545ef19 | ||
|
|
361ee79611 | ||
|
|
39f424767f | ||
|
|
1853cc5143 | ||
|
|
9faca8a8d4 | ||
|
|
8ea6f03fc3 | ||
|
|
c6c1b0b3d3 | ||
|
|
e529230f4b | ||
|
|
dbb15bb3ea | ||
|
|
47c8f8f982 | ||
|
|
2c0162b457 | ||
|
|
dec580b9f1 | ||
|
|
ad56dfaf70 | ||
|
|
c8e584f879 | ||
|
|
d2d886aae5 | ||
|
|
1e3ca25fed | ||
|
|
84cf05d8b2 | ||
|
|
2c17b28ac4 | ||
|
|
1ed026ca73 | ||
|
|
ae3825871e | ||
|
|
ae300acb2f | ||
|
|
41fa416134 | ||
|
|
68f6190f8e | ||
|
|
1173dcba96 | ||
|
|
716e5e2c8b | ||
|
|
bb2c2ac34a | ||
|
|
c4c400716e | ||
|
|
6825d4bd1d | ||
|
|
39d03a80f4 | ||
|
|
340a1cb60b | ||
|
|
e06f03db72 | ||
|
|
bd11ad8542 | ||
|
|
e050f5ca15 | ||
|
|
903e94b716 | ||
|
|
0732400e7b | ||
|
|
483b2a4322 | ||
|
|
5545ffc925 | ||
|
|
c8bee40410 | ||
|
|
755d363ecc | ||
|
|
dfd14fa778 | ||
|
|
1ab9aa5312 | ||
|
|
4d69cd865c | ||
|
|
832bef4346 | ||
|
|
d5b2a9b256 | ||
|
|
7640950216 | ||
|
|
8b605cc482 | ||
|
|
ece3495004 | ||
|
|
f6655c2aaf | ||
|
|
cba2aa95c8 | ||
|
|
660464c973 | ||
|
|
5156ee058d | ||
|
|
a0515ba30d | ||
|
|
1a46030918 | ||
|
|
f58dcd94fc | ||
|
|
d59bba12db | ||
|
|
5022476edc | ||
|
|
b884abae26 | ||
|
|
aa45d59852 | ||
|
|
55e95ed351 | ||
|
|
be485d7605 | ||
|
|
9024b72b48 | ||
|
|
9b998aa47d | ||
|
|
71913d300d | ||
|
|
284834e799 | ||
|
|
8544cc3806 | ||
|
|
62662f68e9 | ||
|
|
a283273bd2 | ||
|
|
9750c97aff | ||
|
|
2967172bee | ||
|
|
9e1b6166b0 |
4
.github/workflows/build_micropython.yml
vendored
4
.github/workflows/build_micropython.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
build:
|
||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
||||
name: Build ${{ matrix.port }} port
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
- name: Clone lv_micropython
|
||||
run: |
|
||||
git clone https://github.com/lvgl/lv_micropython.git .
|
||||
git checkout master
|
||||
git checkout release/v8
|
||||
- name: Initialize lv_bindings submodule
|
||||
run: git submodule update --init --recursive lib/lv_bindings
|
||||
- name: Update ${{ matrix.port }} port submodules
|
||||
|
||||
46
.github/workflows/esp_upload_component.yml
vendored
46
.github/workflows/esp_upload_component.yml
vendored
@@ -1,23 +1,23 @@
|
||||
name: Push LVGL release to Espressif Component Service
|
||||
|
||||
# If the commit is tagged, it will be uploaded. Other scenario silently fail.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
upload_components:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Upload component to component registry
|
||||
uses: espressif/github-actions/upload_components@master
|
||||
with:
|
||||
name: "lvgl"
|
||||
version: "git"
|
||||
namespace: "lvgl"
|
||||
api_token: ${{ secrets.ESP_IDF_COMPONENT_API_TOKEN }}
|
||||
name: Push LVGL release to Espressif Component Service
|
||||
|
||||
# If the commit is tagged, it will be uploaded. Other scenario silently fail.
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
upload_components:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Upload component to component registry
|
||||
uses: espressif/upload-components-ci-action@v1
|
||||
with:
|
||||
name: "lvgl"
|
||||
version: ${{ github.ref_name }}
|
||||
namespace: "lvgl"
|
||||
api_token: ${{ secrets.ESP_IDF_COMPONENT_API_TOKEN }}
|
||||
|
||||
17
Kconfig
17
Kconfig
@@ -42,11 +42,9 @@ menu "LVGL configuration"
|
||||
|
||||
config LV_COLOR_SCREEN_TRANSP
|
||||
bool "Enable more complex drawing routines to manage screens transparency."
|
||||
depends on LV_COLOR_DEPTH_32
|
||||
help
|
||||
Can be used if the UI is above another layer, e.g. an OSD menu or video player.
|
||||
Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to
|
||||
non LV_OPA_COVER value
|
||||
The screen's `bg_opa` should be set to non LV_OPA_COVER value
|
||||
|
||||
config LV_COLOR_MIX_ROUND_OFS
|
||||
int "Adjust color mix functions rounding"
|
||||
@@ -230,6 +228,16 @@ menu "LVGL configuration"
|
||||
Must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h"
|
||||
|
||||
config LV_USE_GPU_RA6M3_G2D
|
||||
bool "Enable RA6M3 G2D GPU."
|
||||
config LV_GPU_RA6M3_G2D_INCLUDE
|
||||
string "include path of target processor"
|
||||
depends on LV_USE_GPU_RA6M3_G2D
|
||||
default "hal_data.h"
|
||||
help
|
||||
Must be defined to include path of target processor
|
||||
e.g. "hal_data.h"
|
||||
|
||||
config LV_USE_GPU_SWM341_DMA2D
|
||||
bool "Enable SWM341 DMA2D GPU."
|
||||
config LV_GPU_SWM341_DMA2D_INCLUDE
|
||||
@@ -913,7 +921,8 @@ menu "LVGL configuration"
|
||||
string "Set the working directory"
|
||||
depends on LV_USE_FS_STDIO
|
||||
config LV_FS_STDIO_CACHE_SIZE
|
||||
string ">0 to cache this number of bytes in lv_fs_read()"
|
||||
int ">0 to cache this number of bytes in lv_fs_read()"
|
||||
default 0
|
||||
depends on LV_USE_FS_STDIO
|
||||
|
||||
config LV_USE_FS_POSIX
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#include "../../../lvgl.h"
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
|
||||
@@ -725,7 +725,8 @@ void lv_demo_benchmark_run_scene(int_fast16_t scene_no)
|
||||
scene_act = scene_no >> 1;
|
||||
|
||||
if(scenes[scene_act].create_cb) {
|
||||
lv_label_set_text_fmt(title, "%"LV_PRId32"/%d: %s%s", scene_act * 2 + (opa_mode ? 1 : 0), (int)(dimof(scenes) * 2) - 2,
|
||||
lv_label_set_text_fmt(title, "%"LV_PRId32"/%"LV_PRId32": %s%s", scene_act * 2 + (opa_mode ? 1 : 0),
|
||||
(int32_t)(dimof(scenes) * 2) - 2,
|
||||
scenes[scene_act].name, opa_mode ? " + opa" : "");
|
||||
lv_label_set_text(subtitle, "");
|
||||
|
||||
@@ -995,8 +996,8 @@ static void scene_next_task_cb(lv_timer_t * timer)
|
||||
}
|
||||
|
||||
if(scenes[scene_act].create_cb) {
|
||||
lv_label_set_text_fmt(title, "%"LV_PRId32"/%d: %s%s", scene_act * 2 + (opa_mode ? 1 : 0),
|
||||
(int)(dimof(scenes) * 2) - 2, scenes[scene_act].name, opa_mode ? " + opa" : "");
|
||||
lv_label_set_text_fmt(title, "%"LV_PRId32"/%"LV_PRId32": %s%s", scene_act * 2 + (opa_mode ? 1 : 0),
|
||||
(int32_t)(dimof(scenes) * 2) - 2, scenes[scene_act].name, opa_mode ? " + opa" : "");
|
||||
if(opa_mode) {
|
||||
lv_label_set_text_fmt(subtitle, "Result of \"%s\": %"LV_PRId32" FPS", scenes[scene_act].name,
|
||||
scenes[scene_act].fps_normal);
|
||||
|
||||
@@ -1,7 +1,239 @@
|
||||
# Changelog
|
||||
|
||||
## [v8.3.8](https://github.com/lvgl/lvgl/compare/v8.3.8...v8.3.7) 5 July 2023
|
||||
|
||||
## [v8.2.0](https://github.com/lvgl/lvgl/compare/v8.2.0...v8.2.0) 6 July 2022
|
||||
### New Features
|
||||
|
||||
- feat(rt-thread): make the rt-thread env recursively glob the UI files [`8b83fe7`](https://github.com/lvgl/lvgl/commit/8b83fe7ea53a597cdbae8204d0aa9be8ad3d2b89)
|
||||
|
||||
### Performance
|
||||
|
||||
- perf(pxp, vglite): improve performance and add more features [`4222`](https://github.com/lvgl/lvgl/pull/4222)
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix(stm32): static function prototypes moved from .h to .c [`4276`](https://github.com/lvgl/lvgl/pull/4276)
|
||||
- fix(png): fix decode image size and some warnings [`4248`](https://github.com/lvgl/lvgl/pull/4248)
|
||||
- fix(bidi): add more Hebrew checks to RTL characters set (#4171) [`4239`](https://github.com/lvgl/lvgl/pull/4239)
|
||||
- fix(img): fix getting the image type on big endian systems [`4215`](https://github.com/lvgl/lvgl/pull/4215)
|
||||
- fix(sdl): destroy texture after use if not stored in cache [`4173`](https://github.com/lvgl/lvgl/pull/4173)
|
||||
|
||||
- fix:(BtnMatrix) Backport https://github.com/lvgl/lvgl/pull/4185 [`cb602ea`](https://github.com/lvgl/lvgl/commit/cb602ea7785de21a187ef5ee5f7de4e3aa3f7e0e)
|
||||
- fix(arduino): fix messed up variable types [`e3659c4`](https://github.com/lvgl/lvgl/commit/e3659c46b128b2b715b196c3ccfb94b3de4c89f8)
|
||||
- fix:(BtnMatrix) Backport https://github.com/lvgl/lvgl/pull/4185 [`07bce74`](https://github.com/lvgl/lvgl/commit/07bce7466d471a15ba241a9db3239f7a116b0b46)
|
||||
- fix(chart): fix division by zero if there are no ticks [`67b3011`](https://github.com/lvgl/lvgl/commit/67b3011f835b08c77ff60ae2d1e6592a710ca2b1)
|
||||
- fix(msgbox): fix typo [`6a89bd2`](https://github.com/lvgl/lvgl/commit/6a89bd2d7409ac4d49ad32da73ba50a84f7c8990)
|
||||
- fix(tabview): remove the animation if the tab is selected by clicking the button on the header [`3de61c7`](https://github.com/lvgl/lvgl/commit/3de61c76af0aed1665e9d61e47b4dd50b9e8bdf1)
|
||||
- fix(btnmatrix): fix array out of bounds addressing with groups and no buttons [`edd5ad2`](https://github.com/lvgl/lvgl/commit/edd5ad28ad74d1025db0b442cfa390d8c01ae006)
|
||||
- fix(btnmatrix): fix using > 7 as button width [`75e6ef4`](https://github.com/lvgl/lvgl/commit/75e6ef4e1d66a85d68160b97ef931b0717e77212)
|
||||
- fix(draw): typo with LV_COLOR_DEPTH 8 [`45b13c3`](https://github.com/lvgl/lvgl/commit/45b13c378f6fc1728ddf1547c25daa61d62c9f76)
|
||||
- fix(disp): fix memory leak lv_scr_load_anim with auto_del and time=0 [`1caafc5`](https://github.com/lvgl/lvgl/commit/1caafc55dde46e1b7e3d17d8c5349fbf7cccba9f)
|
||||
|
||||
- fix(msgbox): add missing lv_obj_class_init_obj [`6843c19`](https://github.com/lvgl/lvgl/commit/6843c191b792f66829477827279adbbc763541c1)
|
||||
- fix(flex): register LV_STYLE_FLEX_GROW [`5ba90a5`](https://github.com/lvgl/lvgl/commit/5ba90a5c41f584a8eb3a4fc8e2f466729652ddb3)
|
||||
|
||||
### Examples
|
||||
|
||||
- example(tabview): fix tabview disable scrollig example [`9491c3f`](https://github.com/lvgl/lvgl/commit/9491c3ff6d2f8e56b13d8fb493d4b3ee98ef1a4b)
|
||||
|
||||
### Docs
|
||||
|
||||
- docs: mention incompatibility between software rotation and `direct_mode` or `full_refresh` [`4308`](https://github.com/lvgl/lvgl/pull/4308)
|
||||
- docs(faq): don't say 24 bit is support as LVGL can't render in RGB888 directly [`227ac02`](https://github.com/lvgl/lvgl/commit/227ac023419eeb253892b1c36113059f12b1f9f2)
|
||||
|
||||
### CI and tests
|
||||
|
||||
### Others
|
||||
|
||||
- chore(cmsis-pack): update cmsis-pack for v8.3.8 [`4340`](https://github.com/lvgl/lvgl/pull/4340)
|
||||
- add(docs): add renesas-ra6m3 get-started document [`4278`](https://github.com/lvgl/lvgl/pull/4278)
|
||||
- add(gpu): add renesas-ra6m3 gpu adaptation [`4270`](https://github.com/lvgl/lvgl/pull/4270)
|
||||
|
||||
- Revert "fix:(BtnMatrix) Backport https://github.com/lvgl/lvgl/pull/4185" [`1713cd3`](https://github.com/lvgl/lvgl/commit/1713cd3fd8f93aa575fbcf0e34b8626b6ee69ded)
|
||||
|
||||
|
||||
|
||||
|
||||
## [v8.3.7](https://github.com/lvgl/lvgl/compare/v8.3.7...v8.3.6) 3 May 2023
|
||||
|
||||
### New Features
|
||||
|
||||
- feat(btnmatrix): review ctrl map and allow width values to be max 15 [`a150b15`](https://github.com/lvgl/lvgl/commit/a150b15e45a922eb5497fe5a31a480e1cd689246)
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix (spinbox): doubling characters entered from the keyboard [`4190`](https://github.com/lvgl/lvgl/pull/4190)
|
||||
- fix(arm-2d): fix transform-chrome-keying issue [`4178`](https://github.com/lvgl/lvgl/pull/4178)
|
||||
- fix(menu): prevent setting the current page again [`4136`](https://github.com/lvgl/lvgl/pull/4136)
|
||||
- fix(esp): fix ESP-IDF pedantic builds (backport v8.3) [`4135`](https://github.com/lvgl/lvgl/pull/4135)
|
||||
- fix: color mixing with LV_COLOR_SWAP == 1 [`4101`](https://github.com/lvgl/lvgl/pull/4101)
|
||||
|
||||
- fix(indev): fix integer overflow in recursive zoom calculation [`a0795b4`](https://github.com/lvgl/lvgl/commit/a0795b49e82102ad68a27c86c36c37fffbe66d3c)
|
||||
- fix(style): fix trasition on bg_grad color [`48d7878`](https://github.com/lvgl/lvgl/commit/48d7878bac3f607322957ed6f710d6615d5e72e0)
|
||||
|
||||
|
||||
## [v8.3.6](https://github.com/lvgl/lvgl/compare/v8.3.6...v8.3.5) 3 April 2023
|
||||
|
||||
### New Features
|
||||
|
||||
- feat(msg): add lv_msg_unsubcribe_obj [`6af0179`](https://github.com/lvgl/lvgl/commit/6af01798d82f90f0c2ba6a9da39c4f10fb427df7)
|
||||
|
||||
### Performance
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix(group): fix default_group becomes wild pointer when deleted [`4076`](https://github.com/lvgl/lvgl/pull/4076)
|
||||
- fix(fs_posix): allow creating new file and set permission. [`3976`](https://github.com/lvgl/lvgl/pull/3976)
|
||||
- fix(img): support negative angles [`3846`](https://github.com/lvgl/lvgl/pull/3846)
|
||||
- fix(gif): synchronize with master [`4003`](https://github.com/lvgl/lvgl/pull/4003)
|
||||
- fix(gpu): fix STM GPU drivers for some variants [`4004`](https://github.com/lvgl/lvgl/pull/4004)
|
||||
- fix(img): possible divide by 0 exception (lvgl#3988) [`3990`](https://github.com/lvgl/lvgl/pull/3990)
|
||||
- fix(arc): fix knob area invalidation [`d0e19eb`](https://github.com/lvgl/lvgl/commit/d0e19eb2d38ba8a500399b0496d7a8363be4003e)
|
||||
- fix(slider): consider animations on pressing [`0b7777f`](https://github.com/lvgl/lvgl/commit/0b7777f27a7932efe3d594be426e1beb59d80ae3)
|
||||
- fix(bar): delete running animations when a new value is set without animation [`aa31380`](https://github.com/lvgl/lvgl/commit/aa313806d0ebde475fc2bc360a15172cc1b658a7)
|
||||
- docs: use a fixed commit of lv_web_emscripten [`501230e`](https://github.com/lvgl/lvgl/commit/501230e0fc95936199b3187d350873c3bb4a94e4)
|
||||
|
||||
### Examples
|
||||
|
||||
### Docs
|
||||
|
||||
- docs(arduino): add note to not use lv_examles library [`2f294aa`](https://github.com/lvgl/lvgl/commit/2f294aa76c8fece98a4fa72304bc6f267ed2a228)
|
||||
- docs: use a fixed commit of lv_web_emscripten [`501230e`](https://github.com/lvgl/lvgl/commit/501230e0fc95936199b3187d350873c3bb4a94e4)
|
||||
|
||||
### CI and tests
|
||||
|
||||
### Others
|
||||
|
||||
- chore(cmsis-pack): update cmsis-pack for v8.3.6 [`4108`](https://github.com/lvgl/lvgl/pull/4108)
|
||||
- chore: update the version numbers to v8.3.5-dev [`77670fb`](https://github.com/lvgl/lvgl/commit/77670fb1a55e0f2012ff7a057e535830e7253e22)
|
||||
- Update build_html_examples.sh [`399069b`](https://github.com/lvgl/lvgl/commit/399069b4a2423c11823581668fe71ce9a7c88e7d)
|
||||
|
||||
|
||||
## [v8.3.5](https://github.com/lvgl/lvgl/compare/v8.3.4...v8.3.5) 7 February 2023
|
||||
|
||||
### Performance
|
||||
|
||||
- perf(gpu): improve NXP's PXP and VGLite accelerators [`3952`](https://github.com/lvgl/lvgl/pull/3952)
|
||||
- perf(dam2d): rework stm32 dma2d [`3904`](https://github.com/lvgl/lvgl/pull/3904)
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix(monkey): remove executable permissions from source files [`3971`](https://github.com/lvgl/lvgl/pull/3971)
|
||||
- fix(ci): set Ubuntu version for MicroPython test [`3865`](https://github.com/lvgl/lvgl/pull/3865)
|
||||
- fix(Kconfig): fix wrong type of LV_FS_STDIO_CACHE_SIZE (v8.3) [`3906`](https://github.com/lvgl/lvgl/pull/3906)
|
||||
- docs(indev): fix the name of long_press_repeat_time (was long_press_rep_time) [`34c545e`](https://github.com/lvgl/lvgl/commit/34c545ef19dc97c8952a412e533a4cd3924b9fbc)
|
||||
- fix(roller): consider the recolor setting of the label [`39f4247`](https://github.com/lvgl/lvgl/commit/39f424767fa57376c4cb08cf22951fd56d854fd6)
|
||||
|
||||
### Examples
|
||||
|
||||
### Docs
|
||||
|
||||
- docs(indev): fix the name of long_press_repeat_time (was long_press_rep_time) [`34c545e`](https://github.com/lvgl/lvgl/commit/34c545ef19dc97c8952a412e533a4cd3924b9fbc)
|
||||
|
||||
### CI and tests
|
||||
|
||||
- ci(esp): fix push to the component registry on tag [`e529230`](https://github.com/lvgl/lvgl/commit/e529230f4bb97b4506c430aac96d5ddaef685dc4)
|
||||
|
||||
### Others
|
||||
|
||||
- chore(cmsis-pack): update cmsis-pack for v8.3.5 [`3972`](https://github.com/lvgl/lvgl/pull/3972)
|
||||
- chore: add an option to "LV_TICK_CUSTOM" [`3879`](https://github.com/lvgl/lvgl/pull/3879)
|
||||
|
||||
- bump version numbers to v8.3.5-dev [`47c8f8f`](https://github.com/lvgl/lvgl/commit/47c8f8f9822f4c0c0ffbe2f12b380bddefcec475)
|
||||
- Update layer.md [`9faca8a`](https://github.com/lvgl/lvgl/commit/9faca8a8d4125e21dedbf6e46aa1586a6b57e5b8)
|
||||
|
||||
## [v8.3.4](https://github.com/lvgl/lvgl/compare/v8.3.4...v8.3.3) 15 December 2022
|
||||
|
||||
### New Features
|
||||
|
||||
- feat(keyboard): ported arabic keyboard from release 7.10.0 [`3728`](https://github.com/lvgl/lvgl/pull/3728)
|
||||
- feat(table): scroll to the selected cell with key navigation [`39d03a8`](https://github.com/lvgl/lvgl/commit/39d03a80f45847a1977cfe9cc6a509b1613d0aca)
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix(rt-thread): sync rt-thread v5.0.0 rt_align [`3864`](https://github.com/lvgl/lvgl/pull/3864)
|
||||
- fix(draw): SDL2 gradient support #3848 [`3856`](https://github.com/lvgl/lvgl/pull/3856)
|
||||
- fix(esp.cmake): add demos and examples [`3784`](https://github.com/lvgl/lvgl/pull/3784)
|
||||
- fix(indev): fix scrolling on transformed obejcts [`84cf05d`](https://github.com/lvgl/lvgl/commit/84cf05d8b23b31e000db757a278545e58fcbcbe8)
|
||||
- fix(style): add the missing support for pct pivot in tranasform style properties [`c8e584f`](https://github.com/lvgl/lvgl/commit/c8e584f879a1e1427e7a8f5ff496af39f17df41d)
|
||||
- fix(flex): be sure obj->w_layout and h_layout can't be set at the same time [`c4c4007`](https://github.com/lvgl/lvgl/commit/c4c400716e80a279e7b3d43b8992915fe94441eb)
|
||||
- fix(chart): fix very dense bar charts [`bb2c2ac`](https://github.com/lvgl/lvgl/commit/bb2c2ac34ac943978513c7ed51885078979b1c10)
|
||||
- fix(draw): handle LV_COLOR_DEPTH == 1 too in lv_draw_sw_transform [`bd11ad8`](https://github.com/lvgl/lvgl/commit/bd11ad8542eac9ff51420e5afb80f7e6fcf36a5c)
|
||||
- fix(example): fix warnings [`1e3ca25`](https://github.com/lvgl/lvgl/commit/1e3ca25fed13bbf85c32a60d4b7041cf8bd525ab)
|
||||
- fix(benchmark): fix warnings [`1ed026c`](https://github.com/lvgl/lvgl/commit/1ed026ca7307957568fe419f1ff39a15b2535b3e)
|
||||
- fix(draw): fix text color with sub pixel rendering and BGR order [`e050f5c`](https://github.com/lvgl/lvgl/commit/e050f5ca156f79d752894f38f0a437c946205cb4)
|
||||
- fix(meter): fix setting part_draw_dsc.id in needle img drawing [`716e5e2`](https://github.com/lvgl/lvgl/commit/716e5e2c8bd2a22e7d56e8d7ca33054a11a1f4ed)
|
||||
- fix(gridnav): fix stucking in pressed state with encoder [`ad56dfa`](https://github.com/lvgl/lvgl/commit/ad56dfaf7046a9bb8c05e877a8c8852cd14a59af)
|
||||
- fix(darw): add back the disappeared antialising=0 support [`2c17b28`](https://github.com/lvgl/lvgl/commit/2c17b28ac476c95a4153ab6cabb77b1c7208bb74)
|
||||
- fix(msg): fix typos in API by adding wrappers [`41fa416`](https://github.com/lvgl/lvgl/commit/41fa41613455260ccdeb87ecb890ce026ff0a435)
|
||||
- fix(draw): fix transformation accuracy [`e06f03d`](https://github.com/lvgl/lvgl/commit/e06f03db72f98439078118518158f52439dd7bf8)
|
||||
- fix(style): remove the reduntant define of LV_GRADIENT_MAX_STOPS [`903e94b`](https://github.com/lvgl/lvgl/commit/903e94b716ca1b32cdb51de11df679953699e53b)
|
||||
- demo(benchmark): fix lv_label_set_text_fmt format strings [`ae38258`](https://github.com/lvgl/lvgl/commit/ae3825871e31cd42cad2f310bdfc605150670511)
|
||||
- demo(benchmark): fix warning [`1173dcb`](https://github.com/lvgl/lvgl/commit/1173dcba96621e20c9a7240c8572bd6573bce6a0)
|
||||
|
||||
## [v8.3.3](https://github.com/lvgl/lvgl/compare/v8.3.2...v8.3.3) 06 October 2022
|
||||
|
||||
v8.3.3 is the same as v8.3.2. It was released only because the version number was set incorrectly in lvgl.h.
|
||||
|
||||
## [v8.3.2](https://github.com/lvgl/lvgl/compare/v8.3.1...v8.3.2) 27 September 2022
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix(fragment): fixed child fragment event dispatch [`3683`](https://github.com/lvgl/lvgl/pull/3683)
|
||||
- fix(sdl): clear streaming/target texture with FillRect [`3682`](https://github.com/lvgl/lvgl/pull/3682)
|
||||
- fix(sdl): transformation with alpha (#3576) [`3678`](https://github.com/lvgl/lvgl/pull/3678)
|
||||
- fix(draw_sw): fix image cache to access the freed stack space [`3584`](https://github.com/lvgl/lvgl/pull/3584)
|
||||
- fix(style): use compile time prop_cnt for const styles [`3609`](https://github.com/lvgl/lvgl/pull/3609)
|
||||
- fix(demo): can not found lvgl.h file [`3477`](https://github.com/lvgl/lvgl/pull/3477)
|
||||
- fix(ci) checkout lv_micropython release/v8 branch [`3524`](https://github.com/lvgl/lvgl/pull/3524)
|
||||
- fix(canvas): fix clipéping on transformation [`b884aba`](https://github.com/lvgl/lvgl/commit/b884abae26f3824b27783a85d18ed51e550347c1)
|
||||
- fix(draw): allow drawing outline with LV_DRAW_COMPLEX == 0 too [`ece3495`](https://github.com/lvgl/lvgl/commit/ece34950040e218fc73605a4e88f1060c2a274f8)
|
||||
- fix(colorwheel): fix updating color when using lv_colorwheel_set_hsv [`d59bba1`](https://github.com/lvgl/lvgl/commit/d59bba12db115afb4b6aa53eed2625221dfff2fd)
|
||||
- fix(slider): find the nearest value on click instead of floor [`dfd14fa`](https://github.com/lvgl/lvgl/commit/dfd14fa778aef25d0db61748a58aa9989ce5e2c8)
|
||||
- fix(draw): fix border drawing with thick borders [`d5b2a9b`](https://github.com/lvgl/lvgl/commit/d5b2a9b2562cbfa327bf0ec03c11d28576037a14)
|
||||
- fix(refr): fix true double double buffering logic with transparent screens [`8b605cc`](https://github.com/lvgl/lvgl/commit/8b605cc48224d0497cdd936fa77229e0c3d606d2)
|
||||
- fix(group): be sure obj is removed from its current group in lv_group_add_obj [`5156ee0`](https://github.com/lvgl/lvgl/commit/5156ee058d5de674a00ffd84d15d460de7f0e53b)
|
||||
- fix(style): add missing invalidation in lv_obj_remove_local_style_prop [`a0515ba`](https://github.com/lvgl/lvgl/commit/a0515ba30dd74b8b22a6709d334eb03782ee1a4d)
|
||||
|
||||
### Docs
|
||||
|
||||
- docs(draw) remove reference to old lv_fs_add_drv function [`3564`](https://github.com/lvgl/lvgl/pull/3564)
|
||||
- docs(disp): LV_COLOR_SCREEN_TRANSP remove dependency on LV_COLOR_DEPTH_32 as transparency is supported across all color depths [`3556`](https://github.com/lvgl/lvgl/pull/3556)
|
||||
|
||||
### CI and tests
|
||||
|
||||
- ci: protect test.c with #if LV_BUILD_TEST [`be485d7`](https://github.com/lvgl/lvgl/commit/be485d7605136d2a5d6a633c7cb5b7c525cae7ee)
|
||||
|
||||
### Others
|
||||
|
||||
- chore(rt-thread) backport fixes from v9 [`3604`](https://github.com/lvgl/lvgl/pull/3604)
|
||||
|
||||
- chore: fix warnings [`7640950`](https://github.com/lvgl/lvgl/commit/76409502163ffe67cfbab9c7f24f2226cc8a5941)
|
||||
- remove accidentally added code [`5022476`](https://github.com/lvgl/lvgl/commit/5022476edc8676f2a6ef7b919d3578159edeef7c)
|
||||
|
||||
|
||||
## [v8.3.1](https://github.com/lvgl/lvgl/compare/v8.3.0...v8.3.1) 25 July 2022
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix(led): add bg_color draw descriptors back to led draw event to support LV_DRAW_COMPLEX 0 [`3515`](https://github.com/lvgl/lvgl/pull/3515)
|
||||
- fix(slider): fix knob drawing in symmetrical mode [`2967172`](https://github.com/lvgl/lvgl/commit/2967172bee806e77da6ee2307c79e867af3f76bc)
|
||||
- fix(refr): fix lv_refr_get_top_obj [`9750c97`](https://github.com/lvgl/lvgl/commit/9750c97aff4dc3de80559b150852b829f006d6bf)
|
||||
- fix(arc): fix arc knob invalidation in SYMMETRICAL mode [`a283273`](https://github.com/lvgl/lvgl/commit/a283273bd27599dae6b044a941b6591ad45e059b)
|
||||
|
||||
### Examples
|
||||
|
||||
- example(freetype): Update the Micropython example to use the Lato font [`71913d3`](https://github.com/lvgl/lvgl/commit/71913d300dde25d1b87d1b44fa1fa47854defd59)
|
||||
- example(freetype): replace the arial font with lato to avoid licensing issues [`8544cc3`](https://github.com/lvgl/lvgl/commit/8544cc38062d9c817013bbe6aedbb47112e580ad)
|
||||
|
||||
### Docs
|
||||
|
||||
- docs(readme): fix LVGL version typo (8.3.0) [`3462`](https://github.com/lvgl/lvgl/pull/3462)
|
||||
- docs(tasmota): support LVGL 8.3.0 (#3511) [`62662f6`](https://github.com/lvgl/lvgl/commit/62662f68e9cf90adcb96d42030eca5fa135b96a5)
|
||||
|
||||
|
||||
|
||||
## [v8.3.0](https://github.com/lvgl/lvgl/compare/v8.2.0...v8.3.0) 6 July 2022
|
||||
|
||||
|
||||
### Overview
|
||||
|
||||
@@ -52,9 +52,14 @@ In the INO file you can see how to register a display and a touchpad for LVGL an
|
||||
|
||||
Note that, there is no dedicated INO file for every example. Instead, you can load an example by calling an `lv_example_...` function. For example `lv_example_btn_1()`.
|
||||
|
||||
**IMPORTANT**
|
||||
**IMPORTANT NOTE 1**
|
||||
Due to some the limitations of Arduino's build system you need to copy `lvgl/examples` to `lvgl/src/examples`. Similarly for the demos `lvgl/demos` to `lvgl/src/demos`.
|
||||
|
||||
|
||||
**IMPORTANT NOTE 2**
|
||||
Note that the `lv_examples` library is for LVGL v7 and you shouldn't install it for this version (since LVGL v8)
|
||||
as the examples and demos are now part of the main LVGL library.
|
||||
|
||||
## Debugging and logging
|
||||
|
||||
LVGL can display debug information in case of trouble.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
nxp
|
||||
stm32
|
||||
espressif
|
||||
renesas
|
||||
arduino
|
||||
tasmota-berry
|
||||
cmake
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# NXP
|
||||
NXP has integrated LVGL into the MCUXpresso SDK packages for several of their general purpose and crossover
|
||||
microcontrollers, allowing easy evaluation and migration into your product design.
|
||||
NXP has integrated LVGL into the MCUXpresso SDK packages for general purpose and crossover microcontrollers, allowing
|
||||
easy evaluation and migration into your product design.
|
||||
[Download an SDK for a supported board](https://www.nxp.com/design/software/embedded-software/littlevgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY?&tid=vanLITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY)
|
||||
today and get started with your next GUI application.
|
||||
|
||||
@@ -10,42 +10,40 @@ with PXP/VGLite support if the modules are present), no additional integration w
|
||||
|
||||
## HW acceleration for NXP iMX RT platforms
|
||||
Depending on the RT platform used, the acceleration can be done by NXP PXP (PiXel Pipeline) and/or the Verisilicon GPU
|
||||
through an API named VGLite. There is a single NXP draw context that covers both GPUs allowing to have enabled either
|
||||
one or even both at the same time. While enableing both 2D accelerators, the VGLite can be used to accelerate widget
|
||||
drawing while the PXP accelerated blit and fill operations.
|
||||
|
||||
Supported draw callbacks are available in "src/draw/nxp/lv_gpu_nxp.c":
|
||||
```c
|
||||
nxp_draw_ctx->base_draw.draw_arc = lv_draw_nxp_arc;
|
||||
nxp_draw_ctx->base_draw.draw_rect = lv_draw_nxp_rect;
|
||||
nxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_nxp_img_decoded;
|
||||
nxp_draw_ctx->blend = lv_draw_nxp_blend;
|
||||
```
|
||||
|
||||
If enabled both GPUs, the PXP is the preffered one to be used for drawing operation. A fallback mechanism is
|
||||
implemented so that if the feature is not supported by PXP (or if PXP fails), the VGLite will take over to handle the
|
||||
task. At the end, the CPU will assure that every widget drawing is fully covered (if not already done by GPU).
|
||||
through an API named VGLite. Each accelerator has its own context that allows them to be used individually as well
|
||||
simultaneously (in LVGL multithreading mode).
|
||||
|
||||
### PXP accelerator
|
||||
Several drawing features in LVGL can be offloaded to the PXP engine. The VGLite (if supported) and CPU are available for
|
||||
other operations while the PXP is running. An RTOS is required to block the LVGL drawing thread and switch to another
|
||||
task or suspend the CPU for power savings.
|
||||
Several drawing features in LVGL can be offloaded to the PXP engine. The CPU is available for other operations while the
|
||||
PXP is running. RTOS is required to block the LVGL drawing thread and switch to another task or suspend the CPU for
|
||||
power savings.
|
||||
|
||||
Supported draw callbacks are available in "src/draw/nxp/pxp/lv_draw_pxp.c":
|
||||
```c
|
||||
pxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_pxp_img_decoded;
|
||||
pxp_draw_ctx->blend = lv_draw_pxp_blend;
|
||||
pxp_draw_ctx->base_draw.wait_for_finish = lv_draw_pxp_wait_for_finish;
|
||||
pxp_draw_ctx->base_draw.buffer_copy = lv_draw_pxp_buffer_copy;
|
||||
```
|
||||
|
||||
#### Features supported:
|
||||
All operations can be used in conjunction with optional transparency.
|
||||
|
||||
- RGB565 and ARGB8888 color formats
|
||||
- Area fill + optional transparency
|
||||
- BLIT (BLock Image Transfer) + optional transparency
|
||||
- Color keying + optional transparency
|
||||
- Recoloring (color tint) + optional transparency
|
||||
- Image Rotation (90, 180, 270 degree) + optional transparency
|
||||
- Recoloring (color tint) + Image Rotation (90, 180, 270 degree) + optional transparency
|
||||
- Area fill with color
|
||||
- BLIT (BLock Image Transfer)
|
||||
- Screen Rotation (90, 180, 270 degree)
|
||||
- Color keying
|
||||
- Recoloring (color tint)
|
||||
- Image Rotation (90, 180, 270 degree)
|
||||
- Buffer copy
|
||||
- RTOS integration layer
|
||||
- Default FreeRTOS and bare metal code provided
|
||||
|
||||
- Combination of recolor and/or rotation + color key/alpha blend/transparency is supported but PXP needs two steps.
|
||||
First step is to recolor/rotate the image to a temporarly buffer (please check LV_MEM_SIZE value for allocation limit)
|
||||
and another step is required to handle color keying, alpha chanel or to apply transparency.
|
||||
- Combination of recolor and/or rotation + color key/alpha blend/transparency is supported.
|
||||
That is achieved by PXP in two steps:
|
||||
- First step is to recolor/rotate the image to a temporary buffer (statically allocated)
|
||||
- Second step is required to handle color keying, alpha channel or to apply transparency
|
||||
|
||||
#### Known limitations:
|
||||
- Rotation is not supported for images unaligned to blocks of 16x16 pixels.
|
||||
@@ -78,51 +76,71 @@ and the final output image can look shifted.
|
||||
|
||||
#### Project setup:
|
||||
- Add PXP related files to project:
|
||||
- src/draw/nxp/pxp/lv_gpu_nxp_pxp.c, src/draw/nxp/pxp/lv_gpu_nxp_pxp.h: init, uninit, run/wait PXP device, log/trace
|
||||
- src/draw/nxp/pxp/lv_draw_pxp_blend.c, src/draw/nxp/pxp/lv_draw_pxp_blend.h: fill and blit (w/o transformation)
|
||||
- src/draw/nxp/pxp/lv_gpu_nxp_osa.c, src/draw/nxp/pxp/lv_gpu_osa.h: default implementation of OS-specific functions
|
||||
(bare metal and FreeRTOS only)
|
||||
- src/draw/nxp/pxp/lv_draw_pxp.c[.h]: draw context callbacks
|
||||
- src/draw/nxp/pxp/lv_draw_pxp_blend.c[.h]: fill and blit (with optional transformation)
|
||||
- src/draw/nxp/pxp/lv_gpu_nxp_pxp.c[.h]: init, uninit, run/wait PXP device
|
||||
- src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c[.h]: OS abstraction (FreeRTOS or bare metal)
|
||||
- optional, required only if `LV_USE_GPU_NXP_PXP_AUTO_INIT` is set to 1
|
||||
- PXP related code depends on two drivers provided by MCU SDK. These drivers need to be added to project:
|
||||
- fsl_pxp.c, fsl_pxp.h: PXP driver
|
||||
- fsl_cache.c, fsl_cache.h: CPU cache handling functions
|
||||
- fsl_pxp.c[.h]: PXP driver
|
||||
- fsl_cache.c[.h]: CPU cache handling functions
|
||||
|
||||
#### Logging:
|
||||
- By default, LV_GPU_NXP_PXP_LOG_ERRORS is enabled so that any PXP error will be seen on LVGL output
|
||||
- For tracing logs about the PXP limitations or size thresholds, the user can enable LV_GPU_NXP_PXP_LOG_TRACES
|
||||
- By default, `LV_GPU_NXP_PXP_LOG_ERRORS` is enabled so that any PXP error will be seen on SDK debug console
|
||||
- By default, `LV_GPU_NXP_PXP_LOG_TRACES` is disabled. Enable it for tracing logs (like PXP limitations)
|
||||
|
||||
#### Advanced configuration:
|
||||
- Implementation depends on multiple OS-specific functions. The struct `lv_nxp_pxp_cfg_t` with callback pointers is
|
||||
used as a parameter for the `lv_gpu_nxp_pxp_init()` function. Default implementation for FreeRTOS and baremetal is
|
||||
provided in lv_gpu_nxp_osa.c
|
||||
used as a parameter for the `lv_gpu_nxp_pxp_init()` function. Default implementation for FreeRTOS and bare metal is
|
||||
provided in lv_gpu_nxp_pxp_osa.c
|
||||
- `pxp_interrupt_init()`: Initialize PXP interrupt (HW setup, OS setup)
|
||||
- `pxp_interrupt_deinit()`: Deinitialize PXP interrupt (HW setup, OS setup)
|
||||
- `pxp_run()`: Start PXP job. Use OS-specific mechanism to block drawing thread. PXP must finish drawing before
|
||||
leaving this function.
|
||||
- There are configurable area thresholds which are used to decide whether the area will be processed by CPU or by PXP.
|
||||
Areas smaller than a defined value will be processed by CPU and those bigger than the threshold will be processed by
|
||||
PXP. These thresholds may be defined as preprocessor variables. Default values are defined in lv_draw_pxp_blend.h
|
||||
- `LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT`: size threshold for image BLIT, BLIT with color keying, BLIT with recolor and
|
||||
BLIT with rotation (OPA >= LV_OPA_MAX)
|
||||
- `LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT`: size threshold for image BLIT, BLIT with color keying, BLIT with recolor
|
||||
and BLIT with rotation and transparency (OPA < LV_OPA_MAX)
|
||||
- `LV_GPU_NXP_PXP_FILL_SIZE_LIMIT`: size threshold for fill operation (OPA >= LV_OPA_MAX)
|
||||
- `LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT`: size threshold for fill operation with transparency (OPA < LV_OPA_MAX)
|
||||
- Area threshold (size limit) is configurable and used to decide whether the area will be processed by PXP or not.
|
||||
Areas smaller than the defined value will be processed by CPU and those bigger than the threshold will be processed by
|
||||
PXP. The threshold is defined as a macro in lv_draw_pxp.c
|
||||
- `LV_GPU_NXP_PXP_SIZE_LIMIT`: size threshold for fill/blit (with optional transformation)
|
||||
|
||||
### VGLite accelerator
|
||||
Extra drawing features in LVGL can be handled by the VGLite engine. The PXP (if supported) and CPU are available for
|
||||
other operations while the VGLite is running. An RTOS is required to block the LVGL drawing thread and switch to another
|
||||
task or suspend the CPU for power savings.
|
||||
Extra drawing features in LVGL can be handled by the VGLite engine. The CPU is available for other operations while the
|
||||
VGLite is running. An RTOS is required to block the LVGL drawing thread and switch to another task or suspend the CPU
|
||||
for power savings.
|
||||
|
||||
Supported draw callbacks are available in "src/draw/nxp/vglite/lv_draw_vglite.c":
|
||||
```c
|
||||
vglite_draw_ctx->base_draw.init_buf = lv_draw_vglite_init_buf;
|
||||
vglite_draw_ctx->base_draw.draw_line = lv_draw_vglite_line;
|
||||
vglite_draw_ctx->base_draw.draw_arc = lv_draw_vglite_arc;
|
||||
vglite_draw_ctx->base_draw.draw_rect = lv_draw_vglite_rect;
|
||||
vglite_draw_ctx->base_draw.draw_img_decoded = lv_draw_vglite_img_decoded;
|
||||
vglite_draw_ctx->blend = lv_draw_vglite_blend;
|
||||
vglite_draw_ctx->base_draw.wait_for_finish = lv_draw_vglite_wait_for_finish;
|
||||
vglite_draw_ctx->base_draw.buffer_copy = lv_draw_vglite_buffer_copy;
|
||||
```
|
||||
|
||||
#### Features supported:
|
||||
All operations can be used in conjunction with optional transparency.
|
||||
|
||||
- RGB565 and ARGB8888 color formats
|
||||
- Area fill + optional transparency
|
||||
- BLIT (BLock Image Transfer) + optional transparency
|
||||
- Image Rotation (any degree with decimal) + optional transparency
|
||||
- Image Scale + optional transparency
|
||||
- Draw background rectangle with radius or gradient
|
||||
- Draw arc
|
||||
- RTOS integration layer
|
||||
- Area fill with color
|
||||
- BLIT (BLock Image Transfer)
|
||||
- Image Rotation (any degree with decimal)
|
||||
- Image Scale
|
||||
- Draw rectangle background with optional radius or gradient
|
||||
- Blit rectangle background image
|
||||
- Draw rectangle border/outline with optional rounded corners
|
||||
- Draw arc with optional rounded ending
|
||||
- Draw line or dashed line with optional rounded ending
|
||||
- Buffer copy
|
||||
|
||||
#### Known limitations:
|
||||
- Source image alignment:
|
||||
The byte alignment requirement for a pixel depends on the specific pixel format. Both buffer address and buffer stride
|
||||
must be aligned. As general rule, the alignment is set to 16 pixels. This makes the buffer address alignment to be
|
||||
32 bytes for RGB565 and 64 bytes for ARGB8888.
|
||||
- For pixel engine (PE) destination, the alignment should be 64 bytes for all tiled (4x4) buffer layouts.
|
||||
The pixel engine has no additional alignment requirement for linear buffer layouts (`VG_LITE_LINEAR`).
|
||||
|
||||
#### Basic configuration:
|
||||
- Select NXP VGLite engine in lv_conf.h: Set `LV_USE_GPU_NXP_VG_LITE` to 1
|
||||
@@ -130,8 +148,8 @@ task or suspend the CPU for power savings.
|
||||
|
||||
#### Basic initialization:
|
||||
- Initialize VGLite before calling `lv_init()` by specifying the width/height of tessellation window. Value should be
|
||||
a multiple of 16; minimum value is 16 pixels, maximum cannot be greater than frame width. If less than or equal to 0,
|
||||
then no tessellation buffer is created, in which case the function is used for a blit init.
|
||||
a multiple of 16; minimum value is 16 pixels, maximum cannot be greater than the frame width. If less than or equal
|
||||
to 0, then no tessellation buffer is created, in which case VGLite is initialized only for blitting.
|
||||
```c
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "vg_lite.h"
|
||||
@@ -144,25 +162,21 @@ task or suspend the CPU for power savings.
|
||||
|
||||
#### Project setup:
|
||||
- Add VGLite related files to project:
|
||||
- src/draw/nxp/vglite/lv_gpu_nxp_vglite.c, src/draw/nxp/vglite/lv_gpu_nxp_vglite.h: buffer init, log/trace
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_blend.c, src/draw/nxp/vglite/lv_draw_vglite_blend.h: fill and blit
|
||||
(w/o transformation)
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_rect.c, src/draw/nxp/vglite/lv_draw_vglite_rect.h: rectangle draw
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_arc.c, src/draw/nxp/vglite/lv_draw_vglite_arc.h: arc draw
|
||||
- src/draw/nxp/vglite/lv_draw_vglite.c[.h]: draw context callbacks
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_blend.c[.h]: fill and blit (with optional transformation)
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_rect.c[.h]: draw rectangle
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_arc.c[.h]: draw arc
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_line.c[.h]: draw line
|
||||
- src/draw/nxp/vglite/lv_vglite_buf.c[.h]: init/get vglite buffer
|
||||
- src/draw/nxp/vglite/lv_vglite_utils.c[.h]: function helpers
|
||||
|
||||
#### Logging:
|
||||
- By default, LV_GPU_NXP_VG_LITE_LOG_ERRORS is enabled so that any VGLite error will be seen on LVGL output
|
||||
- For tracing logs about the VGLite limitations, size thresholds or stride alignment, the user can enable
|
||||
LV_GPU_NXP_VG_LITE_LOG_TRACES
|
||||
- By default, `LV_GPU_NXP_VG_LITE_LOG_ERRORS` is enabled so that any VGLite error will be seen on SDK debug console
|
||||
- By default, `LV_GPU_NXP_VG_LITE_LOG_TRACES` is disabled. Enable it for tracing logs (like blit split workaround or
|
||||
VGLite fallback to CPU due to any error on the driver)
|
||||
|
||||
#### Advanced configuration:
|
||||
- There are configurable area thresholds which are used to decide whether the area will be processed by CPU or by
|
||||
VGLite. Areas smaller than a defined value will be processed by CPU and those bigger than the threshold will be
|
||||
processed by VGLite. These thresholds may be defined as preprocessor variables. Default values are defined in
|
||||
lv_draw_vglite_blend.h
|
||||
- `LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT`: size threshold for image BLIT, BLIT with scale and BLIT with rotation
|
||||
(OPA >= LV_OPA_MAX)
|
||||
- `LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT`: size threshold for image BLIT, BLIT with scale and BLIT with rotation
|
||||
and transparency (OPA < LV_OPA_MAX)
|
||||
- `LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT`: size threshold for fill operation (OPA >= LV_OPA_MAX)
|
||||
- `LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT`: size threshold for fill operation with transparency (OPA < LV_OPA_MAX)
|
||||
- Area threshold (size limit) is configurable and used to decide whether the area will be processed by VGLite or not.
|
||||
Areas smaller than the defined value will be processed by CPU and those bigger than the threshold will be processed by
|
||||
VGLite. The threshold is defined as a macro in lv_draw_vglite.c
|
||||
- `LV_GPU_NXP_VG_LITE_SIZE_LIMIT`: size threshold for fill/blit (with optional transformation)
|
||||
|
||||
129
docs/get-started/platforms/renesas.md
Normal file
129
docs/get-started/platforms/renesas.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Renesas
|
||||
The [HMI-Board](https://bit.ly/3I9nfUo) development board SDK now comes with LVGL integration for quick evaluation. Simply download the [SDK](https://github.com/RT-Thread-Studio/sdk-bsp-ra6m3-hmi-board/tree/main/projects/hmi-board-lvgl) for the supported motherboard and you’ll be on your way to creating your next GUI application in no time. For more information, check out the [Software design description](https://github.com/RT-Thread-Studio/sdk-bsp-ra6m3-hmi-board/blob/main/projects/hmi-board-lvgl/README.md).
|
||||
|
||||
## Creating new project with LVGL
|
||||
It is recommended to start your project by downloading the HMI-Board SDK example project. It comes fully equipped with LVGL and dave-2d support (if the modules are present), so you won’t need to do any additional integration work.
|
||||
|
||||
## HW acceleration for Renesas RA6M3 platforms
|
||||
For RA6M3 platforms, hardware acceleration can be achieved using the dave-2d GPU, depending on the platform used. Each accelerator has its own context, allowing them to be used individually or simultaneously in LVGL’s multithreading mode.
|
||||
|
||||
### Dave-2d accelerator
|
||||
LVGL can offload several drawing features to the dave-2d engine, freeing up the CPU for other operations while dave-2d runs. An RTOS is required to block the LVGL drawing thread and switch to another task or suspend the CPU for power savings. Supported draw callbacks can be found in “src/draw/renesas/lv_gpu_d2_ra6m3.c”.
|
||||
|
||||
LVGL can offload several drawing features to the dave-2d engine, freeing up the CPU for other operations while dave-2d runs. An RTOS is required to block the LVGL drawing thread and switch to another task or suspend the CPU for power savings. Supported draw callbacks can be found in “src/draw/renesas/lv_gpu_d2_ra6m3.c”.
|
||||
|
||||
```c
|
||||
ra_2d_draw_ctx->blend = lv_draw_ra6m3_2d_blend;
|
||||
ra_2d_draw_ctx->base_draw.draw_img_decoded = lv_port_gpu_img_decoded;
|
||||
ra_2d_draw_ctx->base_draw.wait_for_finish = lv_port_gpu_wait;
|
||||
ra_2d_draw_ctx->base_draw.draw_letter = lv_draw_gpu_letter;
|
||||
```
|
||||
|
||||
### Features supported:
|
||||
All operations can be used in conjunction with optional transparency.
|
||||
|
||||
- RGB565 and ARGB8888 color formats
|
||||
- Area fill with color
|
||||
- BLIT (BLock Image Transfer)
|
||||
- Color conversion
|
||||
- Rotate and scale
|
||||
- Alpha blending
|
||||
- Bilinear filtering
|
||||
- RTOS integration layer
|
||||
- Default RT-Thread code provided
|
||||
- Subpixel exact placement
|
||||
|
||||
### Basic configuration:
|
||||
- Select Renesas dave-2d engine in lv_conf.h: Set `LV_USE_GPU_RA6M3_G2D` to 1
|
||||
- Set referenced header file in lv_conf.h: `#define LV_GPU_RA6M3_G2D_INCLUDE "hal_data.h"`
|
||||
|
||||
### RT-Thread Example:
|
||||
|
||||
```c
|
||||
#define COLOR_BUFFER (LV_HOR_RES_MAX * LV_VER_RES_MAX)
|
||||
|
||||
static lv_disp_drv_t disp_drv;
|
||||
|
||||
/*A static or global variable to store the buffers*/
|
||||
static lv_color_t buf_1[COLOR_BUFFER];
|
||||
```
|
||||
|
||||
- After initializing your peripherals (such as SPI, GPIOs, and LCD) in the `lv_port_disp_init()` function, you can initialize LVGL using [`lv_init()`.](https://docs.lvgl.io/master/API/core/lv_obj.html#_CPPv47lv_initv) Next, register the frame buffers using `lv_disp_draw_buf_init()` and create a new display driver using `lv_disp_drv_init()`.
|
||||
|
||||
```c
|
||||
/*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
|
||||
lv_disp_draw_buf_init(&disp_buf, buf_1, RT_NULL, COLOR_BUFFER);
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
|
||||
/*Set the resolution of the display*/
|
||||
disp_drv.hor_res = LV_HOR_RES_MAX;
|
||||
disp_drv.ver_res = LV_VER_RES_MAX;
|
||||
|
||||
/*Set a display buffer*/
|
||||
disp_drv.draw_buf = &disp_buf;
|
||||
|
||||
/*Used to copy the buffer's content to the display*/
|
||||
disp_drv.flush_cb = disp_flush;
|
||||
|
||||
/* Initialize GPU module */
|
||||
lv_port_gpu_hw_init();
|
||||
|
||||
/*Finally register the driver*/
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
```
|
||||
|
||||
* To run LVGL, you’ll need to create a thread. You can find examples of how to do this using RT-Thread in the `env_support/rt-thread/lv_rt_thread_port.c` file.
|
||||
|
||||
```c
|
||||
static void lvgl_thread_entry(void *parameter)
|
||||
{
|
||||
#if LV_USE_LOG
|
||||
lv_log_register_print_cb(lv_rt_log);
|
||||
#endif /* LV_USE_LOG */
|
||||
lv_init();
|
||||
lv_port_disp_init();
|
||||
lv_port_indev_init();
|
||||
lv_user_gui_init();
|
||||
|
||||
/* handle the tasks of LVGL */
|
||||
while(1)
|
||||
{
|
||||
lv_task_handler();
|
||||
rt_thread_mdelay(LV_DISP_DEF_REFR_PERIOD);
|
||||
}
|
||||
}
|
||||
|
||||
static int lvgl_thread_init(void)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
/* create lvgl thread */
|
||||
err = rt_thread_init(&lvgl_thread, "LVGL", lvgl_thread_entry, RT_NULL,
|
||||
&lvgl_thread_stack[0], sizeof(lvgl_thread_stack), PKG_LVGL_THREAD_PRIO, 10);
|
||||
if(err != RT_EOK)
|
||||
{
|
||||
LOG_E("Failed to create LVGL thread");
|
||||
return -1;
|
||||
}
|
||||
rt_thread_startup(&lvgl_thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_ENV_EXPORT(lvgl_thread_init);
|
||||
```
|
||||
|
||||
- The last step is to create a function to output the frame buffer to your LCD. The specifics of this function will depend on the features of your MCU. Here’s an example for a typical MCU interface: `my_flush_cb`.
|
||||
|
||||
```c
|
||||
static void my_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
#ifdef PKG_USING_ILI9341
|
||||
lcd_fill_array_spi(area->x1, area->y1, area->x2, area->y2, color_p);
|
||||
#elif LV_USE_GPU_RA6M3_G2D
|
||||
lv_port_gpu_blit(area->x1, area->y1, color_p, area);
|
||||
#else
|
||||
......
|
||||
#endif
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
```
|
||||
@@ -31,7 +31,7 @@ In 2021, Tasmota added full support of LVGL for ESP32 based devices. It also int
|
||||
|
||||
A comprehensive mapping of LVGL in Berry language is now available, similar to the mapping of Micropython. It allows to use +98% of all LVGL features. It is also possible to write custom widgets in Berry.
|
||||
|
||||
Versions supported: LVGL v8.0.2, LodePNG v20201017, Freetype 2.10.4
|
||||
Versions supported: LVGL v8.3.0, LodePNG v20201017, Freetype 2.10.4
|
||||
|
||||
### Tasmota + Berry + LVGL could be used for:
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ LVGL needs just one simple driver function to copy an array of pixels into a giv
|
||||
If you can do this with your display then you can use it with LVGL.
|
||||
|
||||
Some examples of the supported display types:
|
||||
- TFTs with 16 or 24 bit color depth
|
||||
- TFTs with 16 or 32 bit color depth
|
||||
- Monitors with an HDMI port
|
||||
- Small monochrome displays
|
||||
- Gray-scale displays
|
||||
|
||||
@@ -63,11 +63,10 @@ See the [Display background](#display-background) section for more details. If t
|
||||
This configuration (transparent screen and display) could be used to create for example OSD menus where a video is played on a lower layer, and a menu is overlayed on an upper layer.
|
||||
|
||||
To handle transparent displays, special (slower) color mixing algorithms need to be used by LVGL so this feature needs to enabled with `LV_COLOR_SCREEN_TRANSP` in `lv_conf.h`.
|
||||
As this mode operates on the Alpha channel of the pixels `LV_COLOR_DEPTH = 32` is also required. The Alpha channel of 32-bit colors will be 0 where there are no objects and 255 where there are solid objects.
|
||||
The Alpha channel of 32-bit colors will be 0 where there are no objects and 255 where there are solid objects.
|
||||
|
||||
In summary, to enable transparent screens and displays for OSD menu-like UIs:
|
||||
- Enable `LV_COLOR_SCREEN_TRANSP` in `lv_conf.h`
|
||||
- Be sure to use `LV_COLOR_DEPTH 32`
|
||||
- Set the screen's opacity to `LV_OPA_TRANSP` e.g. with `lv_obj_set_style_local_bg_opa(lv_scr_act(), LV_OBJMASK_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP)`
|
||||
- Set the display opacity to `LV_OPA_TRANSP` with `lv_disp_set_bg_opa(NULL, LV_OPA_TRANSP);`
|
||||
|
||||
|
||||
@@ -34,11 +34,11 @@ lv_label_set_text(label2, "Button 2"); /*Set the text of the label*/
|
||||
lv_obj_del(label2);
|
||||
```
|
||||
|
||||
## Bring to the foreground
|
||||
## Change order
|
||||
|
||||
There are four explicit ways to bring an object to the foreground:
|
||||
- Use `lv_obj_move_foreground(obj)` to bring an object to the foreground. Similarly, use `lv_obj_move_background(obj)` to move it to the background.
|
||||
- Use `lv_obj_move_up(obj)` to move an object one position up in the hierarchy, Similarly, use `lv_obj_move_down(obj)` to move an object one position down in the hierarchy.
|
||||
- Use `lv_obj_move_to_index(obj, idx)` to move an object to a given index in the order of children. (0: backgroud, child_num - 1: foreground, <0: count from the top, to move forward (up): `lv_obj_move_to_index(obj, lv_obj_get_index(obj) - 1)`)
|
||||
- Use `lv_obj_swap(obj1, obj2)` to swap the relative layer position of two objects.
|
||||
- When `lv_obj_set_parent(obj, new_parent)` is used, `obj` will be on the foreground of the `new_parent`.
|
||||
|
||||
|
||||
@@ -1,4 +1,32 @@
|
||||
# ARM-2D GPU
|
||||
# Arm-2D GPU
|
||||
|
||||
TODO
|
||||
Arm-2D is not a GPU but **an abstraction layer for 2D GPUs dedicated to Microcontrollers**. It supports all Cortex-M processors ranging from Cortex-M0 to the latest Cortex-M85.
|
||||
|
||||
Arm-2D is an open-source project on Github. For more, please refer to: https://github.com/ARM-software/Arm-2D.
|
||||
|
||||
|
||||
|
||||
## How to Use
|
||||
|
||||
In general, you can set the macro `LV_USE_GPU_ARM2D` to `1`in `lv_conf.h` to enable Arm-2D acceleration for LVGL.
|
||||
|
||||
If you are using **[CMSIS-Pack](https://github.com/lvgl/lvgl/tree/master/env_support/cmsis-pack)** to deploy the LVGL. You don't have to define the macro `LV_USE_GPU_ARM2D` manually, instead, please select the component `GPU Arm-2D` in the **RTE** dialog. This step will define the macro for us.
|
||||
|
||||
|
||||
|
||||
## Design Considerations
|
||||
|
||||
As mentioned before, Arm-2D is an abstraction layer for 2D GPU; hence if there is no accelerator or dedicated instruction set (such as Helium or ACI) available for Arm-2D, it provides negligible performance boost for LVGL (sometimes worse) for regular Cortex-M processors.
|
||||
|
||||
**We highly recommend you enable Arm-2D acceleration for LVGL** when:
|
||||
|
||||
- The target processors are **Cortex-M55** and/or **Cortex-M85**
|
||||
- The target processors support **[Helium](https://developer.arm.com/documentation/102102/0103/?lang=en)**.
|
||||
- The device vendor provides an arm-2d compliant driver for their propriotory 2D accelerators and/or customized instruction set.
|
||||
- The target device contains [DMA-350](https://community.arm.com/arm-community-blogs/b/internet-of-things-blog/posts/arm-corelink-dma-350-next-generation-direct-memory-access-for-endpoint-ai)
|
||||
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
- [A Cortex-M55 (supports Helium) based MDK Project, PC emulation is available.](https://github.com/lvgl/lv_port_an547_cm55_sim)
|
||||
|
||||
@@ -204,6 +204,8 @@ The default rotation of your display when it is initialized can be set using the
|
||||
|
||||
Display rotation can also be changed at runtime using the `lv_disp_set_rotation(disp, rot)` API.
|
||||
|
||||
Note that when using software rotation, you cannot use neither `direct_mode` nor `full_refresh` in the driver. When using either of these, you will have to rotate the pixels yourself e.g. in the `flush_cb`.
|
||||
|
||||
Support for software rotation is a new feature, so there may be some glitches/bugs depending on your configuration. If you encounter a problem please open an issue on [GitHub](https://github.com/lvgl/lvgl/issues).
|
||||
|
||||
### Decoupling the display refresh timer
|
||||
|
||||
@@ -114,7 +114,7 @@ You need to have 3 buttons available:
|
||||
- `LV_KEY_RIGHT` will simulate turning encoder right
|
||||
- other keys will be passed to the focused widget
|
||||
|
||||
If you hold the keys it will simulate an encoder advance with period specified in `indev_drv.long_press_rep_time`.
|
||||
If you hold the keys it will simulate an encoder advance with period specified in `indev_drv.long_press_repeat_time`.
|
||||
|
||||
```c
|
||||
indev_drv.type = LV_INDEV_TYPE_ENCODER;
|
||||
@@ -172,7 +172,7 @@ The default value of the following parameters can be changed in `lv_indev_drv_t`
|
||||
- `scroll_limit` Number of pixels to slide before actually scrolling the object.
|
||||
- `scroll_throw` Scroll throw (momentum) slow-down in [%]. Greater value means faster slow-down.
|
||||
- `long_press_time` Press time to send `LV_EVENT_LONG_PRESSED` (in milliseconds)
|
||||
- `long_press_rep_time` Interval of sending `LV_EVENT_LONG_PRESSED_REPEAT` (in milliseconds)
|
||||
- `long_press_repeat_time` Interval of sending `LV_EVENT_LONG_PRESSED_REPEAT` (in milliseconds)
|
||||
- `read_timer` pointer to the `lv_timer` which reads the input device. Its parameters can be changed by `lv_timer_...()` functions. `LV_INDEV_DEF_READ_PERIOD` in `lv_conf.h` sets the default read period.
|
||||
|
||||
### Feedback
|
||||
|
||||
@@ -25,7 +25,7 @@ So in the example the first row will have 2 buttons each with 50% width and a se
|
||||
The buttons' width can be set relative to the other button in the same row with `lv_btnmatrix_set_btn_width(btnm, btn_id, width)`
|
||||
E.g. in a line with two buttons: *btnA, width = 1* and *btnB, width = 2*, *btnA* will have 33 % width and *btnB* will have 66 % width.
|
||||
It's similar to how the [`flex-grow`](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow) property works in CSS.
|
||||
The width must be in the \[1..7\] range and the default width is 1.
|
||||
The width must be in the \[1..15\] range and the default width is 1.
|
||||
|
||||
In addition to the width, each button can be customized with the following parameters:
|
||||
- `LV_BTNMATRIX_CTRL_HIDDEN` Makes a button hidden (hidden buttons still take up space in the layout, they are just not visible or clickable)
|
||||
|
||||
@@ -12,22 +12,43 @@ if(LV_MICROPYTHON)
|
||||
${LVGL_ROOT_DIR}/../
|
||||
REQUIRES
|
||||
main)
|
||||
|
||||
target_compile_definitions(${COMPONENT_LIB}
|
||||
INTERFACE "-DLV_CONF_INCLUDE_SIMPLE")
|
||||
|
||||
if(CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM)
|
||||
target_compile_definitions(${COMPONENT_LIB}
|
||||
INTERFACE "-DLV_ATTRIBUTE_FAST_MEM=IRAM_ATTR")
|
||||
endif()
|
||||
else()
|
||||
idf_component_register(SRCS ${SOURCES} INCLUDE_DIRS ${LVGL_ROOT_DIR}
|
||||
${LVGL_ROOT_DIR}/src ${LVGL_ROOT_DIR}/../)
|
||||
|
||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_CONF_INCLUDE_SIMPLE")
|
||||
|
||||
if(CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM)
|
||||
target_compile_definitions(${COMPONENT_LIB}
|
||||
PUBLIC "-DLV_ATTRIBUTE_FAST_MEM=IRAM_ATTR")
|
||||
if(CONFIG_LV_BUILD_EXAMPLES)
|
||||
file(GLOB_RECURSE EXAMPLE_SOURCES ${LVGL_ROOT_DIR}/examples/*.c)
|
||||
set_source_files_properties(${EXAMPLE_SOURCES} COMPILE_FLAGS "-Wno-unused-variable -Wno-format")
|
||||
endif()
|
||||
|
||||
if(CONFIG_LV_USE_DEMO_WIDGETS)
|
||||
file(GLOB_RECURSE DEMO_WIDGETS_SOURCES ${LVGL_ROOT_DIR}/demos/widgets/*.c)
|
||||
list(APPEND DEMO_SOURCES ${DEMO_WIDGETS_SOURCES})
|
||||
endif()
|
||||
if(CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER)
|
||||
file(GLOB_RECURSE DEMO_KEYPAD_AND_ENCODER_SOURCES ${LVGL_ROOT_DIR}/demos/keypad_encoder/*.c)
|
||||
list(APPEND DEMO_SOURCES ${DEMO_KEYPAD_AND_ENCODER_SOURCES})
|
||||
endif()
|
||||
if(CONFIG_LV_USE_DEMO_BENCHMARK)
|
||||
file(GLOB_RECURSE DEMO_BENCHMARK_SOURCES ${LVGL_ROOT_DIR}/demos/benchmark/*.c)
|
||||
list(APPEND DEMO_SOURCES ${DEMO_BENCHMARK_SOURCES})
|
||||
endif()
|
||||
if(CONFIG_LV_USE_DEMO_STRESS)
|
||||
file(GLOB_RECURSE DEMO_STRESS_SOURCES ${LVGL_ROOT_DIR}/demos/stress/*.c)
|
||||
list(APPEND DEMO_SOURCES ${DEMO_STRESS_SOURCES})
|
||||
endif()
|
||||
if(CONFIG_LV_USE_DEMO_MUSIC)
|
||||
file(GLOB_RECURSE DEMO_MUSIC_SOURCES ${LVGL_ROOT_DIR}/demos/music/*.c)
|
||||
list(APPEND DEMO_SOURCES ${DEMO_MUSIC_SOURCES})
|
||||
set_source_files_properties(${DEMO_MUSIC_SOURCES} COMPILE_FLAGS "-Wno-format")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${SOURCES} ${EXAMPLE_SOURCES} ${DEMO_SOURCES}
|
||||
INCLUDE_DIRS ${LVGL_ROOT_DIR} ${LVGL_ROOT_DIR}/src ${LVGL_ROOT_DIR}/../
|
||||
${LVGL_ROOT_DIR}/examples ${LVGL_ROOT_DIR}/demos
|
||||
REQUIRES esp_timer)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLV_CONF_INCLUDE_SIMPLE")
|
||||
|
||||
if(CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM)
|
||||
target_compile_definitions(${COMPONENT_LIB}
|
||||
PUBLIC "-DLV_ATTRIBUTE_FAST_MEM=IRAM_ATTR")
|
||||
endif()
|
||||
|
||||
Binary file not shown.
@@ -20,7 +20,7 @@
|
||||
-->
|
||||
|
||||
|
||||
<package schemaVersion="1.4" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="PACK.xsd">
|
||||
<package schemaVersion="1.4" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="https://raw.githubusercontent.com/Open-CMSIS-Pack/Open-CMSIS-Pack-Spec/v1.7.7/schema/PACK.xsd">
|
||||
<vendor>LVGL</vendor>
|
||||
<name>lvgl</name>
|
||||
<description>LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create an embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint.</description>
|
||||
@@ -36,12 +36,31 @@
|
||||
<repository type="git">https://github.com/lvgl/lvgl.git</repository>
|
||||
|
||||
<releases>
|
||||
<release date="2022-07-06" version="1.0.6" url="https://raw.githubusercontent.com/lvgl/lvgl/master/env_support/cmsis-pack/LVGL.lvgl.1.0.6.pack">
|
||||
- LVGL 8.3.0 release
|
||||
- Apply patch for memory leaking issue
|
||||
- Apply patch to speed up non normal blend mode
|
||||
- Add 9-key input mode to pinyin
|
||||
- Other minor changes
|
||||
<release date="2023-07-04" version="8.3.8" url="https://raw.githubusercontent.com/lvgl/lvgl/master/env_support/cmsis-pack/LVGL.lvgl.8.3.8.pack">
|
||||
- LVGL 8.3.8
|
||||
- Add renesas-ra6m3 gpu adaptation
|
||||
- Improve performance and add more features for PXP and VGLite
|
||||
- Minor updates
|
||||
</release>
|
||||
<release date="2023-04-28" version="8.3.7" url="https://github.com/lvgl/lvgl/raw/2b56e04205481daa6575bd5f7ab5df59d11676eb/env_support/cmsis-pack/LVGL.lvgl.8.3.7.pack">
|
||||
- LVGL 8.3.7
|
||||
- Minor updates
|
||||
</release>
|
||||
<release date="2023-04-02" version="8.3.6" url="https://github.com/lvgl/lvgl/raw/6b0092c0d91b2c7bfded48e04cc7b486ed3a72bd/env_support/cmsis-pack/LVGL.lvgl.8.3.6.pack">
|
||||
- LVGL 8.3.6 release
|
||||
- Various fixes, See CHANGELOG.md
|
||||
</release>
|
||||
<release date="2023-02-06" version="8.3.5" url="https://github.com/lvgl/lvgl/raw/e7e8cf846dce96f7542e27b5c9655bab680c31a1/env_support/cmsis-pack/LVGL.lvgl.8.3.5.pack">
|
||||
- LVGL 8.3.5 release
|
||||
- Use LVGL version as the cmsis-pack version
|
||||
- Fix GPU support for NXP PXP and NXP VGLite
|
||||
- Rework stm32 DMA2D support
|
||||
- Various fixes
|
||||
</release>
|
||||
<release date="2022-12-31" version="1.0.6-p1" url="https://github.com/lvgl/lvgl/raw/dbb15bb3ea0365373bc1ba8b182556f937e61e7d/env_support/cmsis-pack/LVGL.lvgl.1.0.6-p1.pack">
|
||||
- LVGL 8.3.4 release
|
||||
- Update GPU Arm-2D support
|
||||
- Various fixes
|
||||
</release>
|
||||
<release date="2022-06-29" version="1.0.5" url="https://github.com/GorgonMeducer/lvgl/raw/922108dbbe6d1c0be1069c342ca8693afee8c169/env_support/cmsis-pack/LVGL.lvgl.1.0.5.pack">
|
||||
- LVGL 8.3.0-dev
|
||||
@@ -159,6 +178,90 @@
|
||||
<require Cclass="Acceleration" Cgroup="Arm-2D"/>
|
||||
</condition>
|
||||
|
||||
<condition id="LVGL-GPU-Arm-2D">
|
||||
<description>Enable LVGL Arm-2D GPU Support</description>
|
||||
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
||||
<!--<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU Arm-2D"/>-->
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU STM32-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU SWM341-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-PXP"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-VGLite"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU GD32-IPA"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="LVGL-GPU-RA6M3-G2D"/>
|
||||
</condition>
|
||||
|
||||
<condition id="LVGL-GPU-STM32-DMA2D">
|
||||
<description>Enable LVGL Arm-2D GPU Support</description>
|
||||
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU Arm-2D"/>
|
||||
<!--<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU STM32-DMA2D"/>-->
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU SWM341-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-PXP"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-VGLite"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU GD32-IPA"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="LVGL-GPU-RA6M3-G2D"/>
|
||||
</condition>
|
||||
|
||||
<condition id="LVGL-GPU-SWM341-DMA2D">
|
||||
<description>Enable LVGL Arm-2D GPU Support</description>
|
||||
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU Arm-2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU STM32-DMA2D"/>
|
||||
<!--<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU SWM341-DMA2D"/>-->
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-PXP"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-VGLite"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU GD32-IPA"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="LVGL-GPU-RA6M3-G2D"/>
|
||||
</condition>
|
||||
|
||||
<condition id="LVGL-GPU-NXP-PXP">
|
||||
<description>Enable LVGL Arm-2D GPU Support</description>
|
||||
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU Arm-2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU STM32-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU SWM341-DMA2D"/>
|
||||
<!--<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-PXP"/>-->
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-VGLite"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU GD32-IPA"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="LVGL-GPU-RA6M3-G2D"/>
|
||||
</condition>
|
||||
|
||||
<condition id="LVGL-GPU-NXP-VGLite">
|
||||
<description>Enable LVGL Arm-2D GPU Support</description>
|
||||
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU Arm-2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU STM32-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU SWM341-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-PXP"/>
|
||||
<!--<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-VGLite"/>-->
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU GD32-IPA"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="LVGL-GPU-RA6M3-G2D"/>
|
||||
</condition>
|
||||
|
||||
<condition id="LVGL-GPU-GD32-IPA">
|
||||
<description>Enable LVGL Arm-2D GPU Support</description>
|
||||
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU Arm-2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU STM32-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU SWM341-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-PXP"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-VGLite"/>
|
||||
<!--<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU GD32-IPA"/>-->
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="LVGL-GPU-RA6M3-G2D"/>
|
||||
</condition>
|
||||
|
||||
<condition id="LVGL-GPU-RA6M3-G2D">
|
||||
<description>Enable LVGL Arm-2D GPU Support</description>
|
||||
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU Arm-2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU STM32-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU SWM341-DMA2D"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-PXP"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU NXP-VGLite"/>
|
||||
<deny Cclass="LVGL" Cgroup="lvgl" Csub="GPU GD32-IPA"/>
|
||||
<!--<deny Cclass="LVGL" Cgroup="lvgl" Csub="LVGL-GPU-RA6M3-G2D"/>-->
|
||||
</condition>
|
||||
|
||||
</conditions>
|
||||
<!-- apis section (optional - for Application Programming Interface descriptions) -->
|
||||
<!--
|
||||
@@ -191,7 +294,7 @@
|
||||
-->
|
||||
|
||||
<components>
|
||||
<bundle Cbundle="LVGL" Cclass="LVGL" Cversion="8.3.0">
|
||||
<bundle Cbundle="LVGL" Cclass="LVGL" Cversion="8.3.8">
|
||||
<description>LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create an embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint.</description>
|
||||
<doc></doc>
|
||||
<component Cgroup="lvgl" Csub="Essential" >
|
||||
@@ -324,10 +427,18 @@
|
||||
<file category="sourceC" name="src/widgets/lv_textarea.c" />
|
||||
|
||||
<!-- general -->
|
||||
<file category="preIncludeGlobal" name="lv_conf_cmsis.h" attr="config" version="1.0.2" />
|
||||
<file category="preIncludeGlobal" name="lv_conf_cmsis.h" attr="config" version="1.0.3" />
|
||||
<file category="sourceC" name="lv_cmsis_pack.c" attr="config" version="1.0.0" />
|
||||
<file category="header" name="lvgl.h" />
|
||||
<file category="doc" name="README.md"/>
|
||||
|
||||
<!-- code template -->
|
||||
<file category="header" name="examples/porting/lv_port_disp_template.h" attr="template" select="Display port template" version="2.0.0"/>
|
||||
<file category="sourceC" name="examples/porting/lv_port_disp_template.c" attr="template" select="Display port template" version="2.0.0"/>
|
||||
<file category="header" name="examples/porting/lv_port_indev_template.h" attr="template" select="Input devices port template" version="2.0.0"/>
|
||||
<file category="sourceC" name="examples/porting/lv_port_indev_template.c" attr="template" select="Input devices port template" version="2.0.0"/>
|
||||
<file category="header" name="examples/porting/lv_port_fs_template.h" attr="template" select="File system port template" version="2.0.0"/>
|
||||
<file category="sourceC" name="examples/porting/lv_port_fs_template.c" attr="template" select="File system port template" version="2.0.0"/>
|
||||
|
||||
</files>
|
||||
|
||||
@@ -360,7 +471,7 @@
|
||||
</files>
|
||||
</component>
|
||||
|
||||
<component Cgroup="lvgl" Csub="GPU Arm-2D" condition="LVGL-Essential" Cversion="1.0.3">
|
||||
<component Cgroup="lvgl" Csub="GPU Arm-2D" condition="LVGL-GPU-Arm-2D" Cversion="1.2.2">
|
||||
<description>A 2D image processing library from Arm (i.e. Arm-2D) for All Cortex-M processors including Cortex-M0</description>
|
||||
<files>
|
||||
<file category="sourceC" name="src/draw/arm2d/lv_gpu_arm2d.c" condition="Arm-2D"/>
|
||||
@@ -375,7 +486,7 @@
|
||||
|
||||
</component>
|
||||
|
||||
<component Cgroup="lvgl" Csub="GPU STM32-DMA2D" condition="LVGL-Essential">
|
||||
<component Cgroup="lvgl" Csub="GPU STM32-DMA2D" condition="LVGL-GPU-STM32-DMA2D">
|
||||
<description>An hardware acceleration from STM32-DMA2D</description>
|
||||
<files>
|
||||
<file category="sourceC" name="src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c" />
|
||||
@@ -389,7 +500,7 @@
|
||||
|
||||
</component>
|
||||
|
||||
<component Cgroup="lvgl" Csub="GPU SWM341-DMA2D" condition="LVGL-Essential">
|
||||
<component Cgroup="lvgl" Csub="GPU SWM341-DMA2D" condition="LVGL-GPU-SWM341-DMA2D">
|
||||
<description>An hardware acceleration from SWM341-DMA2D</description>
|
||||
<files>
|
||||
<file category="sourceC" name="src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c" />
|
||||
@@ -403,13 +514,13 @@
|
||||
|
||||
</component>
|
||||
|
||||
<component Cgroup="lvgl" Csub="GPU NXP-PXP" condition="LVGL-Essential">
|
||||
<component Cgroup="lvgl" Csub="GPU NXP-PXP" condition="LVGL-GPU-NXP-PXP">
|
||||
<description>An hardware acceleration from NXP-PXP</description>
|
||||
<files>
|
||||
<file category="sourceC" name="src/draw/nxp/lv_gpu_nxp.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/pxp/lv_draw_pxp_blend.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/pxp/lv_gpu_nxp_pxp.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/pxp/lv_draw_pxp.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/pxp/lv_draw_pxp_blend.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/pxp/lv_gpu_nxp_pxp.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c" />
|
||||
</files>
|
||||
|
||||
<RTE_Components_h>
|
||||
@@ -420,14 +531,16 @@
|
||||
|
||||
</component>
|
||||
|
||||
<component Cgroup="lvgl" Csub="GPU NXP-VGLite" condition="LVGL-Essential">
|
||||
<component Cgroup="lvgl" Csub="GPU NXP-VGLite" condition="LVGL-GPU-NXP-VGLite">
|
||||
<description>An hardware acceleration from NXP-VGLite</description>
|
||||
<files>
|
||||
<file category="sourceC" name="src/draw/nxp/lv_gpu_nxp.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_draw_vglite_arc.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_draw_vglite_blend.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_draw_vglite_rect.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_gpu_nxp_vglite.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_draw_vglite.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_draw_vglite_arc.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_draw_vglite_blend.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_draw_vglite_line.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_draw_vglite_rect.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_vglite_buf.c" />
|
||||
<file category="sourceC" name="src/draw/nxp/vglite/lv_vglite_utils.c" />
|
||||
</files>
|
||||
|
||||
<RTE_Components_h>
|
||||
@@ -438,6 +551,22 @@
|
||||
|
||||
</component>
|
||||
|
||||
|
||||
<component Cgroup="lvgl" Csub="GPU RA6M3-G2D" condition="LVGL-GPU-RA6M3-G2D">
|
||||
<description>An hardware acceleration from Renesas RA6M3-G2D</description>
|
||||
<files>
|
||||
<file category="sourceC" name="src/draw/renesas/lv_gpu_d2_draw_label.c" />
|
||||
<file category="sourceC" name="src/draw/renesas/lv_gpu_d2_ra6m3.c" />
|
||||
</files>
|
||||
|
||||
<RTE_Components_h>
|
||||
|
||||
/*! \brief enable RA6M3-G2D */
|
||||
#define LV_USE_GPU_RA6M3_G2D 1
|
||||
</RTE_Components_h>
|
||||
|
||||
</component>
|
||||
|
||||
<component Cgroup="lvgl" Csub="Extra Themes" condition="LVGL-Essential">
|
||||
<description>Extra Themes, Widgets and Layouts</description>
|
||||
<files>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<index schemaVersion="1.0.0" xs:noNamespaceSchemaLocation="PackIndex.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<vendor>LVGL</vendor>
|
||||
<url>https://raw.githubusercontent.com/lvgl/lvgl/master/env_support/cmsis-pack/</url>
|
||||
<timestamp>2022-07-06T00:09:27</timestamp>
|
||||
<timestamp>2023-07-04</timestamp>
|
||||
<pindex>
|
||||
<pdsc url="https://raw.githubusercontent.com/lvgl/lvgl/master/env_support/cmsis-pack/" vendor="LVGL" name="lvgl" version="1.0.6"/>
|
||||
<pdsc url="https://raw.githubusercontent.com/lvgl/lvgl/release/v8.3/env_support/cmsis-pack/" vendor="LVGL" name="lvgl" version="8.3.8"/>
|
||||
</pindex>
|
||||
</index>
|
||||
@@ -21,8 +21,8 @@ if [ `uname -s` = "Linux" ]
|
||||
CMSIS_PACK_PATH="/home/$USER/.arm/Packs/ARM/CMSIS/5.7.0/"
|
||||
PATH_TO_ADD="$CMSIS_PACK_PATH/CMSIS/Utilities/Linux64/"
|
||||
else
|
||||
CMSIS_PACK_PATH="/C/Users/gabriel/AppData/Local/Arm/Packs/ARM/CMSIS/5.7.0"
|
||||
PATH_TO_ADD="/C/Program Files (x86)/7-Zip/:$CMSIS_PACK_PATH/CMSIS/Utilities/Win32/:/C/xmllint/"
|
||||
CMSIS_PACK_PATH="/C/Users/$USER/AppData/Local/Arm/Packs/ARM/CMSIS/5.7.0"
|
||||
PATH_TO_ADD="/C/Program Files (x86)/7-Zip/:/C/Program Files/7-Zip/:$CMSIS_PACK_PATH/CMSIS/Utilities/Win32/:/C/xmllint/"
|
||||
fi
|
||||
[[ ":$PATH:" != *":$PATH_TO_ADD}:"* ]] && PATH="${PATH}:${PATH_TO_ADD}"
|
||||
echo $PATH_TO_ADD appended to PATH
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
* Configuration file for v8.3.0
|
||||
* Configuration file for v8.3.8
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
@@ -82,19 +82,17 @@
|
||||
#define LV_TICK_CUSTOM 1
|
||||
#if LV_TICK_CUSTOM
|
||||
extern uint32_t SystemCoreClock;
|
||||
#define LV_TICK_CUSTOM_INCLUDE "perf_counter.h"
|
||||
|
||||
#if __PER_COUNTER_VER__ < 10902ul
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR ((uint32_t)get_system_ticks() / (SystemCoreClock / 1000ul))
|
||||
#else
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR get_system_ms()
|
||||
#endif
|
||||
#define LV_TICK_CUSTOM_INCLUDE "perf_counter.h"
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR get_system_ms()
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
#else
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#if LV_TICK_CUSTOM
|
||||
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
||||
/*If using lvgl as ESP32 component*/
|
||||
// #define LV_TICK_CUSTOM_INCLUDE "esp_timer.h"
|
||||
// #define LV_TICK_CUSTOM_SYS_TIME_EXPR ((esp_timer_get_time() / 1000LL))
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
#endif /*__PERF_COUNTER__*/
|
||||
|
||||
@@ -183,7 +181,7 @@
|
||||
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
/*Must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
e.g. "stm32f7xx.h" or "stm32f4xx.h"*/
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
#endif
|
||||
|
||||
@@ -202,6 +200,12 @@
|
||||
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_RA6M3_G2D
|
||||
/*include path of target processor
|
||||
e.g. "hal_data.h"*/
|
||||
#define LV_GPU_RA6M3_G2D_INCLUDE "hal_data.h"
|
||||
#endif
|
||||
|
||||
/*Use SDL renderer API*/
|
||||
#define LV_USE_GPU_SDL 0
|
||||
#if LV_USE_GPU_SDL
|
||||
@@ -227,11 +231,11 @@
|
||||
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
*LV_LOG_LEVEL_USER Only logs added by the user
|
||||
*LV_LOG_LEVEL_NONE Do not log anything*/
|
||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_USER
|
||||
|
||||
/*1: Print the log with 'printf';
|
||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
||||
#define LV_LOG_PRINTF 0
|
||||
#define LV_LOG_PRINTF 1
|
||||
|
||||
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
|
||||
#define LV_LOG_TRACE_MEM 1
|
||||
@@ -350,9 +354,9 @@
|
||||
*https://fonts.google.com/specimen/Montserrat*/
|
||||
#define LV_FONT_MONTSERRAT_8 0
|
||||
#define LV_FONT_MONTSERRAT_10 0
|
||||
#define LV_FONT_MONTSERRAT_12 0
|
||||
#define LV_FONT_MONTSERRAT_12 1
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#define LV_FONT_MONTSERRAT_16 0
|
||||
#define LV_FONT_MONTSERRAT_16 1
|
||||
#define LV_FONT_MONTSERRAT_18 0
|
||||
#define LV_FONT_MONTSERRAT_20 0
|
||||
#define LV_FONT_MONTSERRAT_22 0
|
||||
|
||||
@@ -71,7 +71,11 @@
|
||||
# define LV_BIG_ENDIAN_SYSTEM 0
|
||||
#endif
|
||||
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN ALIGN(4)
|
||||
#ifdef rt_align /* >= RT-Thread v5.0.0 */
|
||||
# define LV_ATTRIBUTE_MEM_ALIGN rt_align(RT_ALIGN_SIZE)
|
||||
#else
|
||||
# define LV_ATTRIBUTE_MEM_ALIGN ALIGN(RT_ALIGN_SIZE)
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
|
||||
@@ -31,6 +31,12 @@ extern void lv_port_indev_init(void);
|
||||
extern void lv_user_gui_init(void);
|
||||
|
||||
static struct rt_thread lvgl_thread;
|
||||
|
||||
#ifdef rt_align
|
||||
rt_align(RT_ALIGN_SIZE)
|
||||
#else
|
||||
ALIGN(RT_ALIGN_SIZE)
|
||||
#endif
|
||||
static rt_uint8_t lvgl_thread_stack[PKG_LVGL_THREAD_STACK_SIZE];
|
||||
|
||||
#if LV_USE_LOG
|
||||
|
||||
4
env_support/rt-thread/squareline/README.md
Normal file
4
env_support/rt-thread/squareline/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
This folder is for LVGL SquareLine Studio
|
||||
|
||||
SquareLine Studio can automatically put the generated C files into `ui` folder, so that rt-thread will automatically detect them; or, as a user, you can move the generated C files into `ui` folder manually.
|
||||
|
||||
25
env_support/rt-thread/squareline/SConscript
Normal file
25
env_support/rt-thread/squareline/SConscript
Normal file
@@ -0,0 +1,25 @@
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
inc = [cwd]
|
||||
|
||||
# check if .h or .hpp files exsit
|
||||
def check_h_hpp_exsit(path):
|
||||
file_dirs = os.listdir(path)
|
||||
for file_dir in file_dirs:
|
||||
if os.path.splitext(file_dir)[1] in ['.h', '.hpp']:
|
||||
return True
|
||||
return False
|
||||
|
||||
sls_src_cwd = cwd
|
||||
for root, dirs, files in os.walk(sls_src_cwd):
|
||||
for dir in dirs:
|
||||
current_path = os.path.join(root, dir)
|
||||
src = src + Glob(os.path.join(current_path,'*.c')) # add all .c files
|
||||
if check_h_hpp_exsit(current_path): # add .h and .hpp path
|
||||
inc = inc + [current_path]
|
||||
|
||||
group = DefineGroup('LVGL-SquareLine', src, depend = ['PKG_USING_LVGL_SQUARELINE'], CPPPATH = inc)
|
||||
|
||||
Return('group')
|
||||
19
env_support/rt-thread/squareline/lv_ui_entry.c
Normal file
19
env_support/rt-thread/squareline/lv_ui_entry.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-05-13 Meco Man First version
|
||||
*/
|
||||
|
||||
#ifdef __RTTHREAD__
|
||||
|
||||
void lv_user_gui_init(void)
|
||||
{
|
||||
extern void ui_init(void);
|
||||
ui_init();
|
||||
}
|
||||
|
||||
#endif /* __RTTHREAD__ */
|
||||
15
env_support/rt-thread/squareline/ui/lvgl/lvgl.h
Normal file
15
env_support/rt-thread/squareline/ui/lvgl/lvgl.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-11-20 Meco Man The first version
|
||||
*/
|
||||
|
||||
#ifdef __RTTHREAD__
|
||||
|
||||
#include "../../../../../lvgl.h" /* back to the root folder's lvgl.h */
|
||||
|
||||
#endif /* __RTTHREAD__ */
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_SLIDER && LV_USE_CHART && LV_USE_BTN
|
||||
#if LV_BUILD_EXAMPLES && LV_USE_SLIDER && LV_USE_CHART && LV_USE_BTN && LV_USE_GRID
|
||||
|
||||
/**
|
||||
* the example show the use of cubic-bezier3 in animation.
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
/*Using LVGL with Arduino requires some extra steps:
|
||||
*Be sure to read the docs here: https://docs.lvgl.io/master/get-started/platforms/arduino.html */
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <TFT_eSPI.h>
|
||||
/*If you want to use the LVGL examples,
|
||||
make sure to install the lv_examples Arduino library
|
||||
and uncomment the following line.
|
||||
#include <lv_examples.h>
|
||||
*/
|
||||
|
||||
#include <lv_demo.h>
|
||||
/*To use the built-in examples and demos of LVGL uncomment the includes below respectively.
|
||||
*You also need to copy `lvgl/examples` to `lvgl/src/examples`. Similarly for the demos `lvgl/demos` to `lvgl/src/demos`.
|
||||
Note that the `lv_examples` library is for LVGL v7 and you shouldn't install it for this version (since LVGL v8)
|
||||
as the examples and demos are now part of the main LVGL library. */
|
||||
|
||||
/*Change to your screen resolution*/
|
||||
static const uint16_t screenWidth = 480;
|
||||
static const uint16_t screenHeight = 320;
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf[ screenWidth * 10 ];
|
||||
static lv_color_t buf[ screenWidth * screenHeight / 10 ];
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */
|
||||
|
||||
@@ -27,7 +28,7 @@ void my_print(const char * buf)
|
||||
#endif
|
||||
|
||||
/* Display flushing */
|
||||
void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p )
|
||||
void my_disp_flush( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p )
|
||||
{
|
||||
uint32_t w = ( area->x2 - area->x1 + 1 );
|
||||
uint32_t h = ( area->y2 - area->y1 + 1 );
|
||||
@@ -37,11 +38,11 @@ void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *colo
|
||||
tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );
|
||||
tft.endWrite();
|
||||
|
||||
lv_disp_flush_ready( disp );
|
||||
lv_disp_flush_ready( disp_drv );
|
||||
}
|
||||
|
||||
/*Read the touchpad*/
|
||||
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
|
||||
void my_touchpad_read( lv_indev_drv_t * indev_drv, lv_indev_data_t * data )
|
||||
{
|
||||
uint16_t touchX, touchY;
|
||||
|
||||
@@ -92,7 +93,7 @@ void setup()
|
||||
uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
|
||||
tft.setTouch( calData );
|
||||
|
||||
lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 10 );
|
||||
lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * screenHeight / 10 );
|
||||
|
||||
/*Initialize the display*/
|
||||
static lv_disp_drv_t disp_drv;
|
||||
@@ -110,26 +111,25 @@ void setup()
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = my_touchpad_read;
|
||||
lv_indev_drv_register( &indev_drv );
|
||||
|
||||
#if 0
|
||||
|
||||
/* Create simple label */
|
||||
lv_obj_t *label = lv_label_create( lv_scr_act() );
|
||||
lv_label_set_text( label, LVGL_Arduino.c_str() );
|
||||
lv_label_set_text( label, "Hello Ardino and LVGL!");
|
||||
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
|
||||
#else
|
||||
/* Try an example from the lv_examples Arduino library
|
||||
make sure to include it as written above.
|
||||
lv_example_btn_1();
|
||||
*/
|
||||
|
||||
// uncomment one of these demos
|
||||
lv_demo_widgets(); // OK
|
||||
// lv_demo_benchmark(); // OK
|
||||
// lv_demo_keypad_encoder(); // works, but I haven't an encoder
|
||||
// lv_demo_music(); // NOK
|
||||
|
||||
/* Try an example. See all the examples
|
||||
* online: https://docs.lvgl.io/master/examples.html
|
||||
* source codes: https://github.com/lvgl/lvgl/tree/e7f88efa5853128bf871dde335c0ca8da9eb7731/examples */
|
||||
//lv_example_btn_1();
|
||||
|
||||
/*Or try out a demo. Don't forget to enable the demos in lv_conf.h. E.g. LV_USE_DEMOS_WIDGETS*/
|
||||
//lv_demo_widgets();
|
||||
// lv_demo_benchmark();
|
||||
// lv_demo_keypad_encoder();
|
||||
// lv_demo_music();
|
||||
// lv_demo_printer();
|
||||
// lv_demo_stress(); // seems to be OK
|
||||
#endif
|
||||
// lv_demo_stress();
|
||||
|
||||
Serial.println( "Setup done" );
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ void lv_example_flex_1(void)
|
||||
lv_obj_set_size(obj, 100, LV_PCT(100));
|
||||
|
||||
label = lv_label_create(obj);
|
||||
lv_label_set_text_fmt(label, "Item: %u", i);
|
||||
lv_label_set_text_fmt(label, "Item: %"LV_PRIu32, i);
|
||||
lv_obj_center(label);
|
||||
|
||||
/*Add items to the column*/
|
||||
|
||||
BIN
examples/libs/freetype/Lato-Regular.ttf
Normal file
BIN
examples/libs/freetype/Lato-Regular.ttf
Normal file
Binary file not shown.
Binary file not shown.
@@ -10,7 +10,7 @@ void lv_example_freetype_1(void)
|
||||
/*Create a font*/
|
||||
static lv_ft_info_t info;
|
||||
/*FreeType uses C standard file system, so no driver letter is required.*/
|
||||
info.name = "./lvgl/examples/libs/freetype/arial.ttf";
|
||||
info.name = "./lvgl/examples/libs/freetype/Lato-Regular.ttf";
|
||||
info.weight = 24;
|
||||
info.style = FT_FONT_STYLE_NORMAL;
|
||||
info.mem = NULL;
|
||||
|
||||
@@ -4,7 +4,7 @@ import display_driver
|
||||
import fs_driver
|
||||
|
||||
info = lv.ft_info_t()
|
||||
info.name ="./arial.ttf"
|
||||
info.name ="./Lato-Regular.ttf"
|
||||
info.weight = 24
|
||||
info.style = lv.FT_FONT_STYLE.NORMAL
|
||||
info.font_init()
|
||||
|
||||
@@ -14,7 +14,7 @@ void lv_example_animimg_1(void)
|
||||
{
|
||||
lv_obj_t * animimg0 = lv_animimg_create(lv_scr_act());
|
||||
lv_obj_center(animimg0);
|
||||
lv_animimg_set_src(animimg0, (lv_img_dsc_t **) anim_imgs, 3);
|
||||
lv_animimg_set_src(animimg0, (const void **) anim_imgs, 3);
|
||||
lv_animimg_set_duration(animimg0, 1000);
|
||||
lv_animimg_set_repeat_count(animimg0, LV_ANIM_REPEAT_INFINITE);
|
||||
lv_animimg_start(animimg0);
|
||||
|
||||
@@ -18,11 +18,11 @@ static void float_btn_event_cb(lv_event_t * e)
|
||||
|
||||
cont = lv_menu_cont_create(sub_page);
|
||||
label = lv_label_create(cont);
|
||||
lv_label_set_text_fmt(label, "Hello, I am hiding inside %i", btn_cnt);
|
||||
lv_label_set_text_fmt(label, "Hello, I am hiding inside %"LV_PRIu32, btn_cnt);
|
||||
|
||||
cont = lv_menu_cont_create(main_page);
|
||||
label = lv_label_create(cont);
|
||||
lv_label_set_text_fmt(label, "Item %i", btn_cnt);
|
||||
lv_label_set_text_fmt(label, "Item %"LV_PRIu32, btn_cnt);
|
||||
lv_menu_set_load_page_event(menu, cont, sub_page);
|
||||
|
||||
lv_obj_scroll_to_view_recursive(cont, LV_ANIM_ON);
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_TABVIEW && LV_BUILD_EXAMPLES
|
||||
|
||||
static void scroll_begin_event(lv_event_t * e)
|
||||
{
|
||||
/*Disable the scroll animations. Triggered when a tab button is clicked */
|
||||
if(lv_event_get_code(e) == LV_EVENT_SCROLL_BEGIN) {
|
||||
lv_anim_t * a = lv_event_get_param(e);
|
||||
if(a) a->time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_example_tabview_2(void)
|
||||
{
|
||||
/*Create a Tab view object*/
|
||||
lv_obj_t * tabview;
|
||||
tabview = lv_tabview_create(lv_scr_act(), LV_DIR_LEFT, 80);
|
||||
lv_obj_add_event_cb(lv_tabview_get_content(tabview), scroll_begin_event, LV_EVENT_SCROLL_BEGIN, NULL);
|
||||
|
||||
lv_obj_set_style_bg_color(tabview, lv_palette_lighten(LV_PALETTE_RED, 2), 0);
|
||||
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
def scroll_begin_event(e):
|
||||
|
||||
#Disable the scroll animations. Triggered when a tab button is clicked */
|
||||
if e.get_code() == lv.EVENT.SCROLL_BEGIN:
|
||||
a = lv.anim_t.__cast__(e.get_param())
|
||||
if a:
|
||||
a.time = 0
|
||||
|
||||
# Create a Tab view object
|
||||
tabview = lv.tabview(lv.scr_act(), lv.DIR.LEFT, 80)
|
||||
tabview.get_content().add_event_cb(scroll_begin_event, lv.EVENT.SCROLL_BEGIN, None)
|
||||
|
||||
tabview.set_style_bg_color(lv.palette_lighten(lv.PALETTE.RED, 2), 0)
|
||||
|
||||
tab_btns = tabview.get_tab_btns()
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
description: LVGL - Light and Versatile Graphics Library
|
||||
url: https://github.com/lvgl/lvgl
|
||||
description: LVGL - Light and Versatile Graphics Library
|
||||
url: https://lvgl.io/
|
||||
repository: https://github.com/lvgl/lvgl.git
|
||||
documentation: https://docs.lvgl.io/
|
||||
issues: https://github.com/lvgl/lvgl/issues
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lvgl",
|
||||
"version": "8.3.0",
|
||||
"version": "8.3.8",
|
||||
"keywords": "graphics, gui, embedded, tft, lvgl",
|
||||
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
|
||||
"repository": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name=lvgl
|
||||
version=8.3.0
|
||||
version=8.3.8
|
||||
author=kisvegabor
|
||||
maintainer=kisvegabor,embeddedt,pete-pjb
|
||||
sentence=Full-featured Graphics Library for Embedded Systems
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
* Configuration file for v8.3.0
|
||||
* Configuration file for v8.3.8
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -89,6 +89,9 @@
|
||||
#if LV_TICK_CUSTOM
|
||||
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
||||
/*If using lvgl as ESP32 component*/
|
||||
// #define LV_TICK_CUSTOM_INCLUDE "esp_timer.h"
|
||||
// #define LV_TICK_CUSTOM_SYS_TIME_EXPR ((esp_timer_get_time() / 1000LL))
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
|
||||
@@ -180,10 +183,18 @@
|
||||
#define LV_USE_GPU_STM32_DMA2D 0
|
||||
#if LV_USE_GPU_STM32_DMA2D
|
||||
/*Must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
e.g. "stm32f7xx.h" or "stm32f4xx.h"*/
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
#endif
|
||||
|
||||
/*Enable RA6M3 G2D GPU*/
|
||||
#define LV_USE_GPU_RA6M3_G2D 0
|
||||
#if LV_USE_GPU_RA6M3_G2D
|
||||
/*include path of target processor
|
||||
e.g. "hal_data.h"*/
|
||||
#define LV_GPU_RA6M3_G2D_INCLUDE "hal_data.h"
|
||||
#endif
|
||||
|
||||
/*Use SWM341's DMA2D GPU*/
|
||||
#define LV_USE_GPU_SWM341_DMA2D 0
|
||||
#if LV_USE_GPU_SWM341_DMA2D
|
||||
|
||||
2
lvgl.h
2
lvgl.h
@@ -15,7 +15,7 @@ extern "C" {
|
||||
***************************/
|
||||
#define LVGL_VERSION_MAJOR 8
|
||||
#define LVGL_VERSION_MINOR 3
|
||||
#define LVGL_VERSION_PATCH 0
|
||||
#define LVGL_VERSION_PATCH 8
|
||||
#define LVGL_VERSION_INFO ""
|
||||
|
||||
/*********************
|
||||
|
||||
@@ -6,6 +6,7 @@ rm -rf emscripten_builder
|
||||
git clone https://github.com/lvgl/lv_sim_emscripten.git emscripten_builder
|
||||
scripts/genexamplelist.sh > emscripten_builder/examplelist.c
|
||||
cd emscripten_builder
|
||||
git checkout 45e0bc5c8d3e55cfbcaf8214361d2335b8b9a7b4
|
||||
git submodule update --init -- lvgl
|
||||
cd lvgl
|
||||
git checkout $CURRENT_REF
|
||||
|
||||
@@ -262,6 +262,7 @@ void lv_scr_load_anim(lv_obj_t * new_scr, lv_scr_load_anim_t anim_type, uint32_t
|
||||
/*Shortcut for immediate load*/
|
||||
if(time == 0 && delay == 0) {
|
||||
scr_load_internal(new_scr);
|
||||
if(auto_del) lv_obj_del(act_scr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ void lv_group_del(lv_group_t * group)
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
|
||||
if(default_group == group) default_group = NULL;
|
||||
_lv_ll_clear(&(group->obj_ll));
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_group_ll), group);
|
||||
lv_mem_free(group);
|
||||
@@ -113,6 +114,9 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
|
||||
LV_LOG_TRACE("begin");
|
||||
|
||||
/*Be sure the object is removed from its current group*/
|
||||
lv_group_remove_obj(obj);
|
||||
|
||||
/*Do not add the object twice*/
|
||||
lv_obj_t ** obj_i;
|
||||
_LV_LL_READ(&group->obj_ll, obj_i) {
|
||||
|
||||
@@ -852,8 +852,6 @@ static void indev_proc_press(_lv_indev_proc_t * proc)
|
||||
if(indev_reset_check(proc)) return;
|
||||
}
|
||||
|
||||
lv_obj_transform_point(indev_obj_act, &proc->types.pointer.act_point, true, true);
|
||||
|
||||
/*If a new object was found reset some variables and send a pressed event handler*/
|
||||
if(indev_obj_act != proc->types.pointer.act_obj) {
|
||||
proc->types.pointer.last_point.x = proc->types.pointer.act_point.x;
|
||||
@@ -987,6 +985,27 @@ static void indev_proc_release(_lv_indev_proc_t * proc)
|
||||
proc->pr_timestamp = 0;
|
||||
proc->longpr_rep_timestamp = 0;
|
||||
|
||||
|
||||
/*Get the transformed vector with this object*/
|
||||
if(scroll_obj) {
|
||||
int16_t angle = 0;
|
||||
int16_t zoom = 256;
|
||||
lv_point_t pivot = { 0, 0 };
|
||||
lv_obj_t * parent = scroll_obj;
|
||||
while(parent) {
|
||||
angle += lv_obj_get_style_transform_angle(parent, 0);
|
||||
zoom *= (lv_obj_get_style_transform_zoom(parent, 0) / 256);
|
||||
parent = lv_obj_get_parent(parent);
|
||||
}
|
||||
|
||||
if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) {
|
||||
angle = -angle;
|
||||
zoom = (256 * 256) / zoom;
|
||||
lv_point_transform(&proc->types.pointer.scroll_throw_vect, angle, zoom, &pivot);
|
||||
lv_point_transform(&proc->types.pointer.scroll_throw_vect_ori, angle, zoom, &pivot);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*The reset can be set in the Call the ancestor's event handler function.
|
||||
|
||||
@@ -45,12 +45,13 @@ static lv_coord_t elastic_diff(lv_obj_t * scroll_obj, lv_coord_t diff, lv_coord_
|
||||
|
||||
void _lv_indev_scroll_handler(_lv_indev_proc_t * proc)
|
||||
{
|
||||
if(proc->types.pointer.vect.x == 0 && proc->types.pointer.vect.y == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj;
|
||||
/*If there is no scroll object yet try to find one*/
|
||||
if(scroll_obj == NULL) {
|
||||
proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x;
|
||||
proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y;
|
||||
|
||||
scroll_obj = find_scroll_obj(proc);
|
||||
if(scroll_obj == NULL) return;
|
||||
|
||||
@@ -61,35 +62,50 @@ void _lv_indev_scroll_handler(_lv_indev_proc_t * proc)
|
||||
}
|
||||
|
||||
/*Set new position or scroll if the vector is not zero*/
|
||||
if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {
|
||||
lv_coord_t diff_x = 0;
|
||||
lv_coord_t diff_y = 0;
|
||||
|
||||
if(proc->types.pointer.scroll_dir == LV_DIR_HOR) {
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
||||
diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr, LV_DIR_HOR);
|
||||
}
|
||||
else {
|
||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
||||
diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb, LV_DIR_VER);
|
||||
}
|
||||
|
||||
lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj);
|
||||
if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0;
|
||||
if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0;
|
||||
if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0;
|
||||
if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0;
|
||||
|
||||
/*Respect the scroll limit area*/
|
||||
scroll_limit_diff(proc, &diff_x, &diff_y);
|
||||
|
||||
_lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y);
|
||||
if(proc->reset_query) return;
|
||||
proc->types.pointer.scroll_sum.x += diff_x;
|
||||
proc->types.pointer.scroll_sum.y += diff_y;
|
||||
int16_t angle = 0;
|
||||
int16_t zoom = 256;
|
||||
lv_obj_t * parent = scroll_obj;
|
||||
while(parent) {
|
||||
angle += lv_obj_get_style_transform_angle(parent, 0);
|
||||
zoom *= (lv_obj_get_style_transform_zoom(parent, 0) / 256);
|
||||
parent = lv_obj_get_parent(parent);
|
||||
}
|
||||
|
||||
if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) {
|
||||
angle = -angle;
|
||||
zoom = (256 * 256) / zoom;
|
||||
lv_point_t pivot = { 0, 0 };
|
||||
lv_point_transform(&proc->types.pointer.vect, angle, zoom, &pivot);
|
||||
}
|
||||
|
||||
|
||||
|
||||
lv_coord_t diff_x = 0;
|
||||
lv_coord_t diff_y = 0;
|
||||
if(proc->types.pointer.scroll_dir == LV_DIR_HOR) {
|
||||
lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj);
|
||||
lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj);
|
||||
diff_x = elastic_diff(scroll_obj, proc->types.pointer.vect.x, sl, sr, LV_DIR_HOR);
|
||||
}
|
||||
else {
|
||||
lv_coord_t st = lv_obj_get_scroll_top(scroll_obj);
|
||||
lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj);
|
||||
diff_y = elastic_diff(scroll_obj, proc->types.pointer.vect.y, st, sb, LV_DIR_VER);
|
||||
}
|
||||
|
||||
lv_dir_t scroll_dir = lv_obj_get_scroll_dir(scroll_obj);
|
||||
if((scroll_dir & LV_DIR_LEFT) == 0 && diff_x > 0) diff_x = 0;
|
||||
if((scroll_dir & LV_DIR_RIGHT) == 0 && diff_x < 0) diff_x = 0;
|
||||
if((scroll_dir & LV_DIR_TOP) == 0 && diff_y > 0) diff_y = 0;
|
||||
if((scroll_dir & LV_DIR_BOTTOM) == 0 && diff_y < 0) diff_y = 0;
|
||||
|
||||
/*Respect the scroll limit area*/
|
||||
scroll_limit_diff(proc, &diff_x, &diff_y);
|
||||
|
||||
_lv_obj_scroll_by_raw(scroll_obj, diff_x, diff_y);
|
||||
if(proc->reset_query) return;
|
||||
proc->types.pointer.scroll_sum.x += diff_x;
|
||||
proc->types.pointer.scroll_sum.y += diff_y;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +115,6 @@ void _lv_indev_scroll_throw_handler(_lv_indev_proc_t * proc)
|
||||
if(scroll_obj == NULL) return;
|
||||
if(proc->types.pointer.scroll_dir == LV_DIR_NONE) return;
|
||||
|
||||
|
||||
lv_indev_t * indev_act = lv_indev_get_act();
|
||||
lv_coord_t scroll_throw = indev_act->driver->scroll_throw;
|
||||
|
||||
@@ -259,14 +274,37 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc)
|
||||
/*Decide if it's a horizontal or vertical scroll*/
|
||||
bool hor_en = false;
|
||||
bool ver_en = false;
|
||||
if(LV_ABS(proc->types.pointer.scroll_sum.x) > LV_ABS(proc->types.pointer.scroll_sum.y)) {
|
||||
hor_en = true;
|
||||
}
|
||||
else {
|
||||
ver_en = true;
|
||||
}
|
||||
|
||||
proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x;
|
||||
proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y;
|
||||
|
||||
while(obj_act) {
|
||||
/*Get the transformed scroll_sum with this object*/
|
||||
int16_t angle = 0;
|
||||
int32_t zoom = 256;
|
||||
lv_point_t pivot = { 0, 0 };
|
||||
lv_obj_t * parent = obj_act;
|
||||
while(parent) {
|
||||
angle += lv_obj_get_style_transform_angle(parent, 0);
|
||||
int32_t zoom_act = lv_obj_get_style_transform_zoom(parent, 0);
|
||||
zoom = (zoom * zoom_act) >> 8;
|
||||
parent = lv_obj_get_parent(parent);
|
||||
}
|
||||
|
||||
lv_point_t obj_scroll_sum = proc->types.pointer.scroll_sum;
|
||||
if(angle != 0 || zoom != LV_IMG_ZOOM_NONE) {
|
||||
angle = -angle;
|
||||
zoom = (256 * 256) / zoom;
|
||||
lv_point_transform(&obj_scroll_sum, angle, zoom, &pivot);
|
||||
}
|
||||
|
||||
if(LV_ABS(obj_scroll_sum.x) > LV_ABS(obj_scroll_sum.y)) {
|
||||
hor_en = true;
|
||||
}
|
||||
else {
|
||||
ver_en = true;
|
||||
}
|
||||
|
||||
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLLABLE) == false) {
|
||||
/*If this object don't want to chain the scroll to the parent stop searching*/
|
||||
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN_HOR) == false && hor_en) break;
|
||||
@@ -300,15 +338,15 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc)
|
||||
*is propagated to this object it can show at least elastic scroll effect.
|
||||
*But if not hor/ver scrollable do not scroll it at all (so it's not a good candidate)*/
|
||||
if((st > 0 || sb > 0) &&
|
||||
((up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) ||
|
||||
(down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit))) {
|
||||
((up_en && obj_scroll_sum.y >= scroll_limit) ||
|
||||
(down_en && obj_scroll_sum.y <= - scroll_limit))) {
|
||||
obj_candidate = obj_act;
|
||||
dir_candidate = LV_DIR_VER;
|
||||
}
|
||||
|
||||
if((sl > 0 || sr > 0) &&
|
||||
((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) ||
|
||||
(right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit))) {
|
||||
((left_en && obj_scroll_sum.x >= scroll_limit) ||
|
||||
(right_en && obj_scroll_sum.x <= - scroll_limit))) {
|
||||
obj_candidate = obj_act;
|
||||
dir_candidate = LV_DIR_HOR;
|
||||
}
|
||||
@@ -318,11 +356,11 @@ static lv_obj_t * find_scroll_obj(_lv_indev_proc_t * proc)
|
||||
if(sl <= 0) left_en = false;
|
||||
if(sr <= 0) right_en = false;
|
||||
|
||||
/*If the object really can be scrolled into the current direction the use it.*/
|
||||
if((left_en && proc->types.pointer.scroll_sum.x >= scroll_limit) ||
|
||||
(right_en && proc->types.pointer.scroll_sum.x <= - scroll_limit) ||
|
||||
(up_en && proc->types.pointer.scroll_sum.y >= scroll_limit) ||
|
||||
(down_en && proc->types.pointer.scroll_sum.y <= - scroll_limit)) {
|
||||
/*If the object really can be scrolled into the current direction then use it.*/
|
||||
if((left_en && obj_scroll_sum.x >= scroll_limit) ||
|
||||
(right_en && obj_scroll_sum.x <= - scroll_limit) ||
|
||||
(up_en && obj_scroll_sum.y >= scroll_limit) ||
|
||||
(down_en && obj_scroll_sum.y <= - scroll_limit)) {
|
||||
proc->types.pointer.scroll_dir = hor_en ? LV_DIR_HOR : LV_DIR_VER;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
#include "../draw/stm32_dma2d/lv_gpu_stm32_dma2d.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_RA6M3_G2D
|
||||
#include "../draw/renesas/lv_gpu_d2_ra6m3.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_SWM341_DMA2D
|
||||
#include "../draw/swm341_dma2d/lv_gpu_swm341_dma2d.h"
|
||||
#endif
|
||||
@@ -119,6 +123,11 @@ void lv_init(void)
|
||||
lv_draw_stm32_dma2d_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_RA6M3_G2D
|
||||
/*Initialize G2D GPU*/
|
||||
lv_draw_ra6m3_g2d_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_SWM341_DMA2D
|
||||
/*Initialize DMA2D GPU*/
|
||||
lv_draw_swm341_dma2d_init();
|
||||
|
||||
@@ -1160,9 +1160,21 @@ static void transform_point(const lv_obj_t * obj, lv_point_t * p, bool inv)
|
||||
|
||||
if(angle == 0 && zoom == LV_IMG_ZOOM_NONE) return;
|
||||
|
||||
lv_point_t pivot;
|
||||
pivot.x = obj->coords.x1 + lv_obj_get_style_transform_pivot_x(obj, 0);
|
||||
pivot.y = obj->coords.y1 + lv_obj_get_style_transform_pivot_y(obj, 0);
|
||||
lv_point_t pivot = {
|
||||
.x = lv_obj_get_style_transform_pivot_x(obj, 0),
|
||||
.y = lv_obj_get_style_transform_pivot_y(obj, 0)
|
||||
};
|
||||
|
||||
if(LV_COORD_IS_PCT(pivot.x)) {
|
||||
pivot.x = (LV_COORD_GET_PCT(pivot.x) * lv_area_get_width(&obj->coords)) / 100;
|
||||
}
|
||||
if(LV_COORD_IS_PCT(pivot.y)) {
|
||||
pivot.y = (LV_COORD_GET_PCT(pivot.y) * lv_area_get_height(&obj->coords)) / 100;
|
||||
}
|
||||
|
||||
pivot.x = obj->coords.x1 + pivot.x;
|
||||
pivot.y = obj->coords.y1 + pivot.y;
|
||||
|
||||
if(inv) {
|
||||
angle = -angle;
|
||||
zoom = (256 * 256) / zoom;
|
||||
|
||||
@@ -314,7 +314,12 @@ bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_sty
|
||||
/*The style is not found*/
|
||||
if(i == obj->style_cnt) return false;
|
||||
|
||||
return lv_style_remove_prop(obj->styles[i].style, prop);
|
||||
lv_res_t res = lv_style_remove_prop(obj->styles[i].style, prop);
|
||||
if(res == LV_RES_OK) {
|
||||
lv_obj_refresh_style(obj, selector, prop);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void _lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state, lv_state_t new_state,
|
||||
@@ -744,6 +749,7 @@ static void trans_anim_cb(void * _tr, int32_t v)
|
||||
else value_final.ptr = tr->end_value.ptr;
|
||||
break;
|
||||
case LV_STYLE_BG_COLOR:
|
||||
case LV_STYLE_BG_GRAD_COLOR:
|
||||
case LV_STYLE_BORDER_COLOR:
|
||||
case LV_STYLE_TEXT_COLOR:
|
||||
case LV_STYLE_SHADOW_COLOR:
|
||||
|
||||
@@ -323,15 +323,8 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
|
||||
|
||||
refr_invalid_areas();
|
||||
|
||||
|
||||
/*If refresh happened ...*/
|
||||
if(disp_refr->inv_p != 0) {
|
||||
if(disp_refr->driver->full_refresh) {
|
||||
lv_area_t disp_area;
|
||||
lv_area_set(&disp_area, 0, 0, lv_disp_get_hor_res(disp_refr) - 1, lv_disp_get_ver_res(disp_refr) - 1);
|
||||
disp_refr->driver->draw_ctx->buf_area = &disp_area;
|
||||
draw_buf_flush(disp_refr);
|
||||
}
|
||||
|
||||
/*Clean up*/
|
||||
lv_memset_00(disp_refr->inv_areas, sizeof(disp_refr->inv_areas));
|
||||
@@ -620,9 +613,15 @@ static void refr_area_part(lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr);
|
||||
|
||||
if(draw_ctx->init_buf)
|
||||
draw_ctx->init_buf(draw_ctx);
|
||||
|
||||
/* Below the `area_p` area will be redrawn into the draw buffer.
|
||||
* In single buffered mode wait here until the buffer is freed.*/
|
||||
if(draw_buf->buf1 && !draw_buf->buf2) {
|
||||
* In single buffered mode wait here until the buffer is freed.
|
||||
* In full double buffered mode wait here while the buffers are swapped and a buffer becomes available*/
|
||||
bool full_sized = draw_buf->size == (uint32_t)disp_refr->driver->hor_res * disp_refr->driver->ver_res;
|
||||
if((draw_buf->buf1 && !draw_buf->buf2) ||
|
||||
(draw_buf->buf1 && draw_buf->buf2 && full_sized)) {
|
||||
while(draw_buf->flushing) {
|
||||
if(disp_refr->driver->wait_cb) disp_refr->driver->wait_cb(disp_refr->driver);
|
||||
}
|
||||
@@ -710,11 +709,7 @@ static void refr_area_part(lv_draw_ctx_t * draw_ctx)
|
||||
refr_obj_and_children(draw_ctx, lv_disp_get_layer_top(disp_refr));
|
||||
refr_obj_and_children(draw_ctx, lv_disp_get_layer_sys(disp_refr));
|
||||
|
||||
/*In true double buffered mode flush only once when all areas were rendered.
|
||||
*In normal mode flush after every area*/
|
||||
if(disp_refr->driver->full_refresh == false) {
|
||||
draw_buf_flush(disp_refr);
|
||||
}
|
||||
draw_buf_flush(disp_refr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -738,9 +733,9 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
lv_event_send(obj, LV_EVENT_COVER_CHECK, &info);
|
||||
if(info.res == LV_COVER_RES_MASKED) return NULL;
|
||||
|
||||
uint32_t i;
|
||||
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
|
||||
for(i = 0; i < child_cnt; i++) {
|
||||
int32_t i;
|
||||
int32_t child_cnt = lv_obj_get_child_cnt(obj);
|
||||
for(i = child_cnt - 1; i >= 0; i--) {
|
||||
lv_obj_t * child = obj->spec_attr->children[i];
|
||||
found_p = lv_refr_get_top_obj(area_p, child);
|
||||
|
||||
@@ -922,6 +917,13 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj)
|
||||
.y = lv_obj_get_style_transform_pivot_y(obj, 0)
|
||||
};
|
||||
|
||||
if(LV_COORD_IS_PCT(pivot.x)) {
|
||||
pivot.x = (LV_COORD_GET_PCT(pivot.x) * lv_area_get_width(&obj->coords)) / 100;
|
||||
}
|
||||
if(LV_COORD_IS_PCT(pivot.y)) {
|
||||
pivot.y = (LV_COORD_GET_PCT(pivot.y) * lv_area_get_height(&obj->coords)) / 100;
|
||||
}
|
||||
|
||||
lv_draw_img_dsc_t draw_dsc;
|
||||
lv_draw_img_dsc_init(&draw_dsc);
|
||||
draw_dsc.opa = opa;
|
||||
@@ -1189,24 +1191,13 @@ static void draw_buf_flush(lv_disp_t * disp)
|
||||
lv_draw_ctx_t * draw_ctx = disp->driver->draw_ctx;
|
||||
if(draw_ctx->wait_for_finish) draw_ctx->wait_for_finish(draw_ctx);
|
||||
|
||||
/* In double buffered mode wait until the other buffer is freed
|
||||
/* In partial double buffered mode wait until the other buffer is freed
|
||||
* and driver is ready to receive the new buffer */
|
||||
if(draw_buf->buf1 && draw_buf->buf2) {
|
||||
bool full_sized = draw_buf->size == (uint32_t)disp_refr->driver->hor_res * disp_refr->driver->ver_res;
|
||||
if(draw_buf->buf1 && draw_buf->buf2 && !full_sized) {
|
||||
while(draw_buf->flushing) {
|
||||
if(disp_refr->driver->wait_cb) disp_refr->driver->wait_cb(disp_refr->driver);
|
||||
}
|
||||
|
||||
/*If the screen is transparent initialize it when the flushing is ready*/
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp_refr->driver->screen_transp) {
|
||||
if(disp_refr->driver->clear_cb) {
|
||||
disp_refr->driver->clear_cb(disp_refr->driver, disp_refr->driver->draw_buf->buf_act, disp_refr->driver->draw_buf->size);
|
||||
}
|
||||
else {
|
||||
lv_memset_00(disp_refr->driver->draw_buf->buf_act, disp_refr->driver->draw_buf->size * LV_IMG_PX_SIZE_ALPHA_BYTE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
draw_buf->flushing = 1;
|
||||
@@ -1225,6 +1216,7 @@ static void draw_buf_flush(lv_disp_t * disp)
|
||||
call_flush_cb(disp->driver, draw_ctx->buf_area, draw_ctx->buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*If there are 2 buffers swap them. With direct mode swap only on the last area*/
|
||||
if(draw_buf->buf1 && draw_buf->buf2 && (!disp->driver->direct_mode || flushing_last)) {
|
||||
if(draw_buf->buf_act == draw_buf->buf1)
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2023 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
@@ -39,6 +57,7 @@
|
||||
#include "../../core/lv_refr.h"
|
||||
|
||||
#if LV_USE_GPU_ARM2D
|
||||
#define __ARM_2D_IMPL__
|
||||
#include "arm_2d.h"
|
||||
#include "__arm_2d_impl.h"
|
||||
|
||||
@@ -89,10 +108,14 @@
|
||||
#define __arm_2d_impl_cl_key_copy __arm_2d_impl_rgb16_cl_key_copy
|
||||
#define __arm_2d_impl_alpha_blending_colour_keying \
|
||||
__arm_2d_impl_rgb565_alpha_blending_colour_keying
|
||||
#define arm_2d_tile_transform_with_src_mask_and_opacity \
|
||||
arm_2d_rgb565_tile_transform_with_src_mask_and_opacity
|
||||
#define arm_2d_tile_transform_with_opacity \
|
||||
arm_2d_rgb565_tile_transform_with_opacity
|
||||
#define arm_2d_tile_transform_with_src_mask_and_opacity_prepare \
|
||||
arm_2dp_rgb565_tile_transform_with_src_mask_and_opacity_prepare
|
||||
#define arm_2d_tile_transform_with_opacity_prepare \
|
||||
arm_2dp_rgb565_tile_transform_with_opacity_prepare
|
||||
#define arm_2d_tile_transform_only_with_opacity_prepare \
|
||||
arm_2dp_rgb565_tile_transform_only_with_opacity_prepare
|
||||
#define arm_2d_tile_transform_prepare \
|
||||
arm_2dp_rgb565_tile_transform_prepare
|
||||
|
||||
#define __ARM_2D_PIXEL_BLENDING_OPA __ARM_2D_PIXEL_BLENDING_OPA_RGB565
|
||||
|
||||
@@ -124,10 +147,14 @@
|
||||
#define __arm_2d_impl_cl_key_copy __arm_2d_impl_rgb32_cl_key_copy
|
||||
#define __arm_2d_impl_alpha_blending_colour_keying \
|
||||
__arm_2d_impl_cccn888_alpha_blending_colour_keying
|
||||
#define arm_2d_tile_transform_with_src_mask_and_opacity \
|
||||
arm_2d_cccn888_tile_transform_with_src_mask_and_opacity
|
||||
#define arm_2d_tile_transform_with_opacity \
|
||||
arm_2d_cccn888_tile_transform_with_opacity
|
||||
#define arm_2d_tile_transform_with_src_mask_and_opacity_prepare \
|
||||
arm_2dp_cccn888_tile_transform_with_src_mask_and_opacity_prepare
|
||||
#define arm_2d_tile_transform_with_opacity_prepare \
|
||||
arm_2dp_cccn888_tile_transform_with_opacity_prepare
|
||||
#define arm_2d_tile_transform_only_with_opacity_prepare \
|
||||
arm_2dp_cccn888_tile_transform_only_with_opacity_prepare
|
||||
#define arm_2d_tile_transform_prepare \
|
||||
arm_2dp_cccn888_tile_transform_prepare
|
||||
|
||||
#define __ARM_2D_PIXEL_BLENDING_OPA __ARM_2D_PIXEL_BLENDING_OPA_CCCN888
|
||||
|
||||
@@ -298,11 +325,88 @@
|
||||
/* replace src_buf for the following operation */ \
|
||||
src_buf = (const uint8_t *)rgb_tmp_buf; \
|
||||
} \
|
||||
__VA_ARGS__ \
|
||||
do { \
|
||||
__VA_ARGS__ \
|
||||
} while(0); \
|
||||
if (NULL != rgb_tmp_buf) { \
|
||||
lv_mem_buf_release(rgb_tmp_buf); \
|
||||
} \
|
||||
} while(0);
|
||||
} while(0); \
|
||||
src_buf = src_buf_org;
|
||||
|
||||
#define __RECOLOUR_BEGIN() \
|
||||
do { \
|
||||
lv_color_t *rgb_tmp_buf = NULL; \
|
||||
if(draw_dsc->recolor_opa > LV_OPA_MIN) { \
|
||||
rgb_tmp_buf \
|
||||
= lv_mem_buf_get(src_w * src_h * sizeof(lv_color_t)); \
|
||||
if (NULL == rgb_tmp_buf) { \
|
||||
LV_LOG_WARN( \
|
||||
"Failed to allocate memory for accelerating recolour, " \
|
||||
"use normal route instead."); \
|
||||
break; \
|
||||
} \
|
||||
lv_memcpy(rgb_tmp_buf, src_buf, src_w * src_h * sizeof(lv_color_t));\
|
||||
arm_2d_size_t copy_size = { \
|
||||
.iWidth = src_w, \
|
||||
.iHeight = src_h, \
|
||||
}; \
|
||||
/* apply re-colour */ \
|
||||
__arm_2d_impl_colour_filling_with_opacity( \
|
||||
(color_int *)rgb_tmp_buf, \
|
||||
src_w, \
|
||||
©_size, \
|
||||
(color_int)draw_dsc->recolor.full, \
|
||||
draw_dsc->recolor_opa); \
|
||||
\
|
||||
/* replace src_buf for the following operation */ \
|
||||
src_buf = (const uint8_t *)rgb_tmp_buf; \
|
||||
} \
|
||||
do {
|
||||
|
||||
#define __RECOLOUR_END() \
|
||||
} while(0); \
|
||||
if (NULL != rgb_tmp_buf) { \
|
||||
lv_mem_buf_release(rgb_tmp_buf); \
|
||||
} \
|
||||
} while(0); \
|
||||
src_buf = src_buf_org;
|
||||
|
||||
#define __ARM_2D_PREPARE_TRANS_AND_TARGET_REGION(__TRANS_PREPARE, ...) \
|
||||
do { \
|
||||
__TRANS_PREPARE( \
|
||||
NULL, \
|
||||
__VA_ARGS__); \
|
||||
\
|
||||
target_region = (arm_2d_region_t) { \
|
||||
.tLocation = { \
|
||||
.iX = coords->x1 - draw_ctx->clip_area->x1, \
|
||||
.iY = coords->y1 - draw_ctx->clip_area->y1, \
|
||||
}, \
|
||||
.tSize = { \
|
||||
.iWidth = lv_area_get_width(coords), \
|
||||
.iHeight = lv_area_get_height(coords), \
|
||||
}, \
|
||||
}; \
|
||||
\
|
||||
arm_2d_size_t tTransSize \
|
||||
= ARM_2D_CTRL.DefaultOP \
|
||||
.tTransform.Source.ptTile->tRegion.tSize; \
|
||||
\
|
||||
if (target_region.tSize.iWidth < tTransSize.iWidth) { \
|
||||
int16_t iDelta = tTransSize.iWidth - target_region.tSize.iWidth;\
|
||||
target_region.tLocation.iX -= iDelta / 2; \
|
||||
target_region.tSize.iWidth = tTransSize.iWidth; \
|
||||
} \
|
||||
\
|
||||
if (target_region.tSize.iHeight < tTransSize.iHeight) { \
|
||||
int16_t iDelta \
|
||||
= tTransSize.iHeight - target_region.tSize.iHeight; \
|
||||
target_region.tLocation.iY -= iDelta / 2; \
|
||||
target_region.tSize.iHeight = tTransSize.iHeight; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/**********************
|
||||
@@ -601,18 +705,26 @@ static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend
|
||||
lv_area_t blend_area;
|
||||
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) return;
|
||||
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
//lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
bool is_accelerated = false;
|
||||
do {
|
||||
if(NULL != disp->driver->set_px_cb) {
|
||||
break;
|
||||
|
||||
/* target buffer */
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
if(disp->driver->screen_transp == 0) {
|
||||
dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) + (blend_area.x1 - draw_ctx->buf_area->x1);
|
||||
}
|
||||
else {
|
||||
/*With LV_COLOR_DEPTH 16 it means ARGB8565 (3 bytes format)*/
|
||||
uint8_t * dest_buf8 = (uint8_t *) dest_buf;
|
||||
dest_buf8 += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) * LV_IMG_PX_SIZE_ALPHA_BYTE;
|
||||
dest_buf8 += (blend_area.x1 - draw_ctx->buf_area->x1) * LV_IMG_PX_SIZE_ALPHA_BYTE;
|
||||
dest_buf = (lv_color_t *)dest_buf8;
|
||||
}
|
||||
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1)
|
||||
+ (blend_area.x1 - draw_ctx->buf_area->x1);
|
||||
|
||||
/* source buffer */
|
||||
const lv_color_t * src_buf = dsc->src_buf;
|
||||
lv_coord_t src_stride;
|
||||
if(src_buf) {
|
||||
@@ -634,7 +746,9 @@ static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend
|
||||
|
||||
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
|
||||
if(disp->driver->screen_transp) {
|
||||
break;
|
||||
}
|
||||
if(dsc->src_buf == NULL) {
|
||||
if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) {
|
||||
is_accelerated = arm_2d_fill_normal(dest_buf,
|
||||
@@ -645,14 +759,8 @@ static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend
|
||||
mask,
|
||||
mask_stride);
|
||||
}
|
||||
#if LV_DRAW_COMPLEX
|
||||
else {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
||||
if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) {
|
||||
is_accelerated = arm_2d_copy_normal(dest_buf,
|
||||
&blend_area,
|
||||
@@ -663,11 +771,6 @@ static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend
|
||||
mask,
|
||||
mask_stride);
|
||||
}
|
||||
#if LV_DRAW_COMPLEX
|
||||
else {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} while(0);
|
||||
|
||||
@@ -698,15 +801,11 @@ static bool arm_2d_fill_normal(lv_color_t * dest_buf,
|
||||
}
|
||||
/*Has opacity*/
|
||||
else {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
return false;
|
||||
#else
|
||||
__arm_2d_impl_colour_filling_with_opacity((color_int *)dest_buf,
|
||||
dest_stride,
|
||||
&target_size,
|
||||
color.full,
|
||||
opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*Masked*/
|
||||
@@ -722,9 +821,6 @@ static bool arm_2d_fill_normal(lv_color_t * dest_buf,
|
||||
}
|
||||
/*With opacity*/
|
||||
else {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
return false;
|
||||
#else
|
||||
__arm_2d_impl_colour_filling_mask_opacity((color_int *)dest_buf,
|
||||
dest_stride,
|
||||
(uint8_t *)mask,
|
||||
@@ -732,7 +828,6 @@ static bool arm_2d_fill_normal(lv_color_t * dest_buf,
|
||||
&target_size,
|
||||
color.full,
|
||||
opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -759,10 +854,6 @@ static bool arm_2d_copy_normal(lv_color_t * dest_buf,
|
||||
.iHeight = lv_area_get_height(dest_area),
|
||||
};
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
#endif
|
||||
|
||||
/*Simple fill (maybe with opacity), no masking*/
|
||||
if(mask == NULL) {
|
||||
if(opa >= LV_OPA_MAX) {
|
||||
@@ -773,25 +864,18 @@ static bool arm_2d_copy_normal(lv_color_t * dest_buf,
|
||||
©_size);
|
||||
}
|
||||
else {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
return false;
|
||||
#else
|
||||
__arm_2d_impl_alpha_blending((color_int *)src_buf,
|
||||
src_stride,
|
||||
(color_int *)dest_buf,
|
||||
dest_stride,
|
||||
©_size,
|
||||
opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*Masked*/
|
||||
else {
|
||||
/*Only the mask matters*/
|
||||
if(opa > LV_OPA_MAX) {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
return false;
|
||||
#else
|
||||
__arm_2d_impl_src_msk_copy((color_int *)src_buf,
|
||||
src_stride,
|
||||
(uint8_t *)mask,
|
||||
@@ -800,13 +884,9 @@ static bool arm_2d_copy_normal(lv_color_t * dest_buf,
|
||||
(color_int *)dest_buf,
|
||||
dest_stride,
|
||||
©_size);
|
||||
#endif
|
||||
}
|
||||
/*Handle opa and mask values too*/
|
||||
else {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
return false;
|
||||
#else
|
||||
__arm_2d_impl_gray8_alpha_blending((uint8_t *)mask,
|
||||
mask_stride,
|
||||
(uint8_t *)mask,
|
||||
@@ -822,7 +902,6 @@ static bool arm_2d_copy_normal(lv_color_t * dest_buf,
|
||||
(color_int *)dest_buf,
|
||||
dest_stride,
|
||||
©_size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -839,6 +918,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
/*Use the clip area as draw area*/
|
||||
lv_area_t draw_area;
|
||||
lv_area_copy(&draw_area, draw_ctx->clip_area);
|
||||
const uint8_t * src_buf_org = src_buf;
|
||||
|
||||
bool mask_any = lv_draw_mask_is_any(&draw_area);
|
||||
bool transform = draw_dsc->angle != 0 || draw_dsc->zoom != LV_IMG_ZOOM_NONE ? true : false;
|
||||
@@ -851,6 +931,13 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
blend_dsc.blend_mode = draw_dsc->blend_mode;
|
||||
blend_dsc.blend_area = &blend_area;
|
||||
|
||||
if(lv_img_cf_is_chroma_keyed(cf)) cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
|
||||
else if(cf == LV_IMG_CF_ALPHA_8BIT) {}
|
||||
else if(cf == LV_IMG_CF_RGB565A8) {}
|
||||
else if(lv_img_cf_has_alpha(cf)) cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
||||
else cf = LV_IMG_CF_TRUE_COLOR;
|
||||
|
||||
|
||||
/*The simplest case just copy the pixels into the draw_buf*/
|
||||
if(!mask_any && !transform && cf == LV_IMG_CF_TRUE_COLOR && draw_dsc->recolor_opa == LV_OPA_TRANSP) {
|
||||
blend_dsc.src_buf = (const lv_color_t *)src_buf;
|
||||
@@ -859,6 +946,9 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
lv_draw_sw_blend(draw_ctx, &blend_dsc);
|
||||
}
|
||||
else if(!mask_any && !transform && cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
lv_area_t clipped_coords;
|
||||
if(!_lv_area_intersect(&clipped_coords, coords, draw_ctx->clip_area)) return;
|
||||
|
||||
blend_dsc.mask_buf = (lv_opa_t *)src_buf;
|
||||
blend_dsc.mask_area = coords;
|
||||
blend_dsc.src_buf = NULL;
|
||||
@@ -869,7 +959,8 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
lv_draw_sw_blend(draw_ctx, &blend_dsc);
|
||||
}
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
else if(!mask_any && !transform && cf == LV_IMG_CF_RGB565A8 && draw_dsc->recolor_opa == LV_OPA_TRANSP) {
|
||||
else if(!mask_any && !transform && cf == LV_IMG_CF_RGB565A8 && draw_dsc->recolor_opa == LV_OPA_TRANSP &&
|
||||
blend_dsc.opa >= LV_OPA_MAX) {
|
||||
lv_coord_t src_w = lv_area_get_width(coords);
|
||||
lv_coord_t src_h = lv_area_get_height(coords);
|
||||
blend_dsc.src_buf = (const lv_color_t *)src_buf;
|
||||
@@ -922,6 +1013,23 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
blend_dsc.mask_res = mask_res_def;
|
||||
|
||||
if(cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
/* original code:
|
||||
lv_color_fill(rgb_buf, draw_dsc->recolor, buf_size);
|
||||
*/
|
||||
arm_2d_size_t copy_size = {
|
||||
.iWidth = buf_w,
|
||||
.iHeight = buf_h,
|
||||
};
|
||||
|
||||
/* apply re-colour */
|
||||
__arm_2d_impl_colour_filling(
|
||||
(color_int *)rgb_buf,
|
||||
buf_w,
|
||||
©_size,
|
||||
(color_int)draw_dsc->recolor.full);
|
||||
}
|
||||
|
||||
bool is_accelerated = false;
|
||||
|
||||
if(!transform) {
|
||||
@@ -968,7 +1076,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
}
|
||||
else if((LV_COLOR_DEPTH == 32)
|
||||
&& !mask_any
|
||||
&& (cf == LV_IMG_CF_TRUE_COLOR_ALPHA)) {
|
||||
&& (LV_IMG_CF_TRUE_COLOR_ALPHA == cf)) {
|
||||
/* accelerate copy-with-source-masks-and-opacity */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
@@ -1025,6 +1133,63 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
)
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
else if(!mask_any
|
||||
&& (LV_IMG_CF_RGB565A8 == cf)) {
|
||||
/* accelerate copy-with-source-masks-and-opacity */
|
||||
|
||||
uint8_t * mask_after_rgb = src_buf + sizeof(lv_color_t) * src_w * src_h;
|
||||
/* *INDENT-OFF* */
|
||||
__RECOLOUR_WRAPPER(
|
||||
__PREPARE_LL_ACCELERATION__();
|
||||
|
||||
uint8_t * mask_temp_buf = NULL;
|
||||
if(blend_dsc.opa < LV_OPA_MAX) {
|
||||
mask_temp_buf = lv_mem_buf_get(copy_size.iHeight * copy_size.iWidth);
|
||||
if(NULL == mask_temp_buf) {
|
||||
LV_LOG_WARN(
|
||||
"Failed to allocate memory for alpha mask,"
|
||||
" use normal route instead.");
|
||||
break;
|
||||
}
|
||||
lv_memset_00(mask_temp_buf, copy_size.iHeight * copy_size.iWidth);
|
||||
|
||||
__arm_2d_impl_gray8_colour_filling_mask_opacity(
|
||||
mask_temp_buf,
|
||||
src_stride,
|
||||
mask_after_rgb,
|
||||
src_stride,
|
||||
©_size,
|
||||
0xFF,
|
||||
blend_dsc.opa);
|
||||
|
||||
__arm_2d_impl_src_msk_copy(
|
||||
(color_int *)src_buf_tmp,
|
||||
src_stride,
|
||||
mask_temp_buf,
|
||||
src_stride,
|
||||
©_size,
|
||||
(color_int *)dest_buf,
|
||||
dest_stride,
|
||||
©_size);
|
||||
|
||||
lv_mem_buf_release(mask_temp_buf);
|
||||
}
|
||||
else {
|
||||
__arm_2d_impl_src_msk_copy(
|
||||
(color_int *)src_buf_tmp,
|
||||
src_stride,
|
||||
mask_after_rgb,
|
||||
src_stride,
|
||||
©_size,
|
||||
(color_int *)dest_buf,
|
||||
dest_stride,
|
||||
©_size);
|
||||
}
|
||||
|
||||
is_accelerated = true;
|
||||
)
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
else if(!mask_any && (cf == LV_IMG_CF_TRUE_COLOR)) {
|
||||
/* accelerate copy-with-source-masks-and-opacity */
|
||||
|
||||
@@ -1063,6 +1228,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
&& (draw_dsc->recolor_opa == LV_OPA_TRANSP)
|
||||
&& (((LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED == cf)
|
||||
|| (LV_IMG_CF_TRUE_COLOR == cf))
|
||||
|| (LV_IMG_CF_RGB565A8 == cf)
|
||||
#if defined(__ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__) && __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__
|
||||
|| ((LV_IMG_CF_TRUE_COLOR_ALPHA == cf)
|
||||
&& (LV_COLOR_DEPTH == 32))
|
||||
@@ -1070,6 +1236,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
)
|
||||
) {
|
||||
|
||||
uint8_t * mask_after_rgb = src_buf + sizeof(lv_color_t) * src_w * src_h;
|
||||
/* *INDENT-OFF* */
|
||||
__RECOLOUR_WRAPPER(
|
||||
/* accelerate transform without re-color */
|
||||
@@ -1108,17 +1275,6 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
&target_tile,
|
||||
false);
|
||||
|
||||
target_region = (arm_2d_region_t) {
|
||||
.tLocation = {
|
||||
.iX = coords->x1 - draw_ctx->clip_area->x1,
|
||||
.iY = coords->y1 - draw_ctx->clip_area->y1,
|
||||
},
|
||||
.tSize = {
|
||||
.iWidth = lv_area_get_width(coords),
|
||||
.iHeight = lv_area_get_height(coords),
|
||||
},
|
||||
};
|
||||
|
||||
static arm_2d_tile_t source_tile;
|
||||
|
||||
source_tile = (arm_2d_tile_t) {
|
||||
@@ -1132,46 +1288,99 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
.pchBuffer = (uint8_t *)src_buf,
|
||||
};
|
||||
|
||||
static arm_2d_tile_t mask_tile;
|
||||
mask_tile = source_tile;
|
||||
|
||||
mask_tile.tInfo.bHasEnforcedColour = true;
|
||||
mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_CHANNEL_8in32;
|
||||
mask_tile.pchBuffer += 3;
|
||||
|
||||
static arm_2d_location_t source_center, target_center;
|
||||
source_center.iX = draw_dsc->pivot.x;
|
||||
source_center.iY = draw_dsc->pivot.y;
|
||||
|
||||
if(LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED == cf) {
|
||||
|
||||
if((LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED == cf) ||
|
||||
(LV_IMG_CF_TRUE_COLOR == cf)) {
|
||||
arm_2d_tile_transform_with_opacity(
|
||||
__ARM_2D_PREPARE_TRANS_AND_TARGET_REGION(
|
||||
arm_2d_tile_transform_with_opacity_prepare,
|
||||
&source_tile,
|
||||
&target_tile,
|
||||
&target_region,
|
||||
source_center,
|
||||
ARM_2D_ANGLE((draw_dsc->angle / 10.0f)),
|
||||
draw_dsc->zoom / 256.0f,
|
||||
(color_int)LV_COLOR_CHROMA_KEY.full,
|
||||
blend_dsc.opa);
|
||||
|
||||
is_accelerated = true;
|
||||
}
|
||||
#if defined(__ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__) \
|
||||
&& __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__
|
||||
else if((LV_IMG_CF_TRUE_COLOR_ALPHA == cf) &&
|
||||
(LV_COLOR_DEPTH == 32)) {
|
||||
arm_2d_tile_transform_with_src_mask_and_opacity(
|
||||
&source_tile,
|
||||
&mask_tile,
|
||||
arm_2d_tile_transform(
|
||||
&target_tile,
|
||||
&target_region,
|
||||
NULL
|
||||
);
|
||||
is_accelerated = true;
|
||||
}
|
||||
#if ARM_2D_VERISON >= 10103
|
||||
else if (LV_IMG_CF_TRUE_COLOR == cf) {
|
||||
__ARM_2D_PREPARE_TRANS_AND_TARGET_REGION(
|
||||
arm_2d_tile_transform_only_with_opacity_prepare,
|
||||
&source_tile,
|
||||
source_center,
|
||||
ARM_2D_ANGLE((draw_dsc->angle / 10.0f)),
|
||||
draw_dsc->zoom / 256.0f,
|
||||
blend_dsc.opa);
|
||||
|
||||
arm_2d_tile_transform(
|
||||
&target_tile,
|
||||
&target_region,
|
||||
NULL
|
||||
);
|
||||
is_accelerated = true;
|
||||
}
|
||||
#endif
|
||||
else if (LV_IMG_CF_RGB565A8 == cf) {
|
||||
static arm_2d_tile_t mask_tile;
|
||||
mask_tile = source_tile;
|
||||
|
||||
mask_tile.tInfo.bHasEnforcedColour = true;
|
||||
mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_COLOUR_GRAY8;
|
||||
mask_tile.pchBuffer = mask_after_rgb;
|
||||
|
||||
__ARM_2D_PREPARE_TRANS_AND_TARGET_REGION(
|
||||
arm_2d_tile_transform_with_src_mask_and_opacity_prepare,
|
||||
&source_tile,
|
||||
&mask_tile,
|
||||
source_center,
|
||||
ARM_2D_ANGLE((draw_dsc->angle / 10.0f)),
|
||||
draw_dsc->zoom / 256.0f,
|
||||
blend_dsc.opa
|
||||
);
|
||||
|
||||
arm_2d_tile_transform(
|
||||
&target_tile,
|
||||
&target_region,
|
||||
NULL
|
||||
);
|
||||
|
||||
is_accelerated = true;
|
||||
}
|
||||
#if defined(__ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__) \
|
||||
&& __ARM_2D_CFG_SUPPORT_COLOUR_CHANNEL_ACCESS__
|
||||
else if((LV_IMG_CF_TRUE_COLOR_ALPHA == cf) &&
|
||||
(LV_COLOR_DEPTH == 32)) {
|
||||
static arm_2d_tile_t mask_tile;
|
||||
mask_tile = source_tile;
|
||||
|
||||
mask_tile.tInfo.bHasEnforcedColour = true;
|
||||
mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_CHANNEL_8in32;
|
||||
mask_tile.pchBuffer += 3;
|
||||
|
||||
__ARM_2D_PREPARE_TRANS_AND_TARGET_REGION(
|
||||
arm_2d_tile_transform_with_src_mask_and_opacity_prepare,
|
||||
&source_tile,
|
||||
&mask_tile,
|
||||
source_center,
|
||||
ARM_2D_ANGLE((draw_dsc->angle / 10.0f)),
|
||||
draw_dsc->zoom / 256.0f,
|
||||
blend_dsc.opa
|
||||
);
|
||||
|
||||
arm_2d_tile_transform(
|
||||
&target_tile,
|
||||
&target_region,
|
||||
NULL
|
||||
);
|
||||
|
||||
is_accelerated = true;
|
||||
}
|
||||
#endif
|
||||
@@ -1208,7 +1417,7 @@ static void lv_draw_arm2d_img_decoded(struct _lv_draw_ctx_t * draw_ctx,
|
||||
(color_int)draw_dsc->recolor.full,
|
||||
draw_dsc->recolor_opa);
|
||||
}
|
||||
#if LV_DRAW_COMPLEX
|
||||
#if LV_USE_DRAW_MASKS
|
||||
/*Apply the masks if any*/
|
||||
if(mask_any) {
|
||||
lv_coord_t y;
|
||||
@@ -1275,7 +1484,7 @@ static void convert_cb(const lv_area_t * dest_area, const void * src_buf, lv_coo
|
||||
|
||||
if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
|
||||
uint32_t px_cnt = lv_area_get_size(dest_area);
|
||||
lv_memset_ff(abuf, px_cnt);
|
||||
lv_memset(abuf, 0xff, px_cnt);
|
||||
|
||||
src_tmp8 += (src_stride * dest_area->y1 * sizeof(lv_color_t)) + dest_area->x1 * sizeof(lv_color_t);
|
||||
uint32_t dest_w = lv_area_get_width(dest_area);
|
||||
|
||||
@@ -72,6 +72,7 @@ typedef struct _lv_draw_ctx_t {
|
||||
*/
|
||||
const lv_area_t * clip_area;
|
||||
|
||||
void (*init_buf)(struct _lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
void (*draw_rect)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
|
||||
@@ -69,18 +69,19 @@ void lv_draw_img(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc, const
|
||||
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
lv_res_t res;
|
||||
lv_res_t res = LV_RES_INV;
|
||||
|
||||
if(draw_ctx->draw_img) {
|
||||
res = draw_ctx->draw_img(draw_ctx, dsc, coords, src);
|
||||
}
|
||||
else {
|
||||
|
||||
if(res != LV_RES_OK) {
|
||||
res = decode_and_draw(draw_ctx, dsc, coords, src);
|
||||
}
|
||||
|
||||
if(res == LV_RES_INV) {
|
||||
if(res != LV_RES_OK) {
|
||||
LV_LOG_WARN("Image draw error");
|
||||
show_error(draw_ctx, coords, "No\ndata");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,11 +198,19 @@ lv_img_src_t lv_img_src_get_type(const void * src)
|
||||
if(src == NULL) return img_src_type;
|
||||
const uint8_t * u8_p = src;
|
||||
|
||||
/*The first byte shows the type of the image source*/
|
||||
/*The first or fourth byte depending on platform endianess shows the type of the image source*/
|
||||
#if LV_BIG_ENDIAN_SYSTEM
|
||||
if(u8_p[3] >= 0x20 && u8_p[3] <= 0x7F) {
|
||||
#else
|
||||
if(u8_p[0] >= 0x20 && u8_p[0] <= 0x7F) {
|
||||
#endif
|
||||
img_src_type = LV_IMG_SRC_FILE; /*If it's an ASCII character then it's file name*/
|
||||
}
|
||||
#if LV_BIG_ENDIAN_SYSTEM
|
||||
else if(u8_p[3] >= 0x80) {
|
||||
#else
|
||||
else if(u8_p[0] >= 0x80) {
|
||||
#endif
|
||||
img_src_type = LV_IMG_SRC_SYMBOL; /*Symbols begins after 0x7F*/
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -144,7 +144,7 @@ void _lv_img_decoder_init(void);
|
||||
* Get information about an image.
|
||||
* Try the created image decoder one by one. Once one is able to get info that info will be used.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_drv_register()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param header the image info will be stored here
|
||||
@@ -157,7 +157,7 @@ lv_res_t lv_img_decoder_get_info(const void * src, lv_img_header_t * header);
|
||||
* Try the created image decoders one by one. Once one is able to open the image that decoder is saved in `dsc`
|
||||
* @param dsc describes a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_drv_register())`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param color The color of the image with `LV_IMG_CF_ALPHA_...`
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
CSRCS += lv_gpu_nxp.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp
|
||||
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp
|
||||
|
||||
|
||||
@@ -1,418 +0,0 @@
|
||||
/**
|
||||
* @file lv_gpu_nxp.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2022 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_gpu_nxp.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE
|
||||
|
||||
/*
|
||||
* allow to use both PXP and VGLITE
|
||||
|
||||
* both 2D accelerators can be used at the same time:
|
||||
* thus VGLITE can be used to accelerate widget drawing
|
||||
* while PXP accelerates Blit & Fill operations.
|
||||
*/
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
#include "pxp/lv_draw_pxp_blend.h"
|
||||
#endif
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "vglite/lv_draw_vglite_blend.h"
|
||||
#include "vglite/lv_draw_vglite_rect.h"
|
||||
#include "vglite/lv_draw_vglite_arc.h"
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH != 32
|
||||
#include "../../core/lv_refr.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void lv_draw_nxp_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf);
|
||||
|
||||
static void lv_draw_nxp_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
|
||||
|
||||
static void lv_draw_nxp_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
static lv_res_t draw_nxp_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
static void lv_draw_nxp_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
||||
uint16_t radius, uint16_t start_angle, uint16_t end_angle);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_nxp_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_draw_sw_init_ctx(drv, draw_ctx);
|
||||
|
||||
lv_draw_nxp_ctx_t * nxp_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx;
|
||||
|
||||
nxp_draw_ctx->base_draw.draw_arc = lv_draw_nxp_arc;
|
||||
nxp_draw_ctx->base_draw.draw_rect = lv_draw_nxp_rect;
|
||||
nxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_nxp_img_decoded;
|
||||
nxp_draw_ctx->blend = lv_draw_nxp_blend;
|
||||
//nxp_draw_ctx->base_draw.wait_for_finish = lv_draw_nxp_wait_cb;
|
||||
}
|
||||
|
||||
void lv_draw_nxp_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_draw_sw_deinit_ctx(drv, draw_ctx);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* During rendering, LVGL might initializes new draw_ctxs and start drawing into
|
||||
* a separate buffer (called layer). If the content to be rendered has "holes",
|
||||
* e.g. rounded corner, LVGL temporarily sets the disp_drv.screen_transp flag.
|
||||
* It means the renderers should draw into an ARGB buffer.
|
||||
* With 32 bit color depth it's not a big problem but with 16 bit color depth
|
||||
* the target pixel format is ARGB8565 which is not supported by the GPU.
|
||||
* In this case, the NXP callbacks should fallback to SW rendering.
|
||||
*/
|
||||
static inline bool need_argb8565_support()
|
||||
{
|
||||
#if LV_COLOR_DEPTH != 32
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
if(disp->driver->screen_transp == 1)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void lv_draw_nxp_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
||||
{
|
||||
lv_area_t blend_area;
|
||||
|
||||
/*Let's get the blend area which is the intersection of the area to fill and the clip area.*/
|
||||
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
/*Make the blend area relative to the buffer*/
|
||||
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
bool done = false;
|
||||
|
||||
/*Fill/Blend only non masked, normal blended*/
|
||||
if(dsc->mask_buf == NULL && dsc->blend_mode == LV_BLEND_MODE_NORMAL && !need_argb8565_support()) {
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
lv_coord_t dest_width = lv_area_get_width(draw_ctx->buf_area);
|
||||
lv_coord_t dest_height = lv_area_get_height(draw_ctx->buf_area);
|
||||
#endif
|
||||
|
||||
const lv_color_t * src_buf = dsc->src_buf;
|
||||
|
||||
if(src_buf == NULL) {
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
done = (lv_gpu_nxp_pxp_fill(dest_buf, dest_stride, &blend_area,
|
||||
dsc->color, dsc->opa) == LV_RES_OK);
|
||||
if(!done)
|
||||
PXP_LOG_TRACE("PXP fill failed. Fallback.");
|
||||
|
||||
#endif
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
if(!done) {
|
||||
done = (lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &blend_area,
|
||||
dsc->color, dsc->opa) == LV_RES_OK);
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite fill failed. Fallback.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
done = (lv_gpu_nxp_pxp_blit(dest_buf, &blend_area, dest_stride, src_buf, dsc->blend_area,
|
||||
dsc->opa, LV_DISP_ROT_NONE) == LV_RES_OK);
|
||||
if(!done)
|
||||
PXP_LOG_TRACE("PXP blit failed. Fallback.");
|
||||
#endif
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
if(!done) {
|
||||
lv_gpu_nxp_vglite_blit_info_t blit;
|
||||
lv_coord_t src_stride = lv_area_get_width(dsc->blend_area);
|
||||
|
||||
blit.src = src_buf;
|
||||
blit.src_width = lv_area_get_width(dsc->blend_area);
|
||||
blit.src_height = lv_area_get_height(dsc->blend_area);
|
||||
blit.src_stride = src_stride * (int32_t)sizeof(lv_color_t);
|
||||
blit.src_area.x1 = (blend_area.x1 - (dsc->blend_area->x1 - draw_ctx->buf_area->x1));
|
||||
blit.src_area.y1 = (blend_area.y1 - (dsc->blend_area->y1 - draw_ctx->buf_area->y1));
|
||||
blit.src_area.x2 = blit.src_area.x1 + blit.src_width - 1;
|
||||
blit.src_area.y2 = blit.src_area.y1 + blit.src_height - 1;
|
||||
|
||||
blit.dst = dest_buf;
|
||||
blit.dst_width = dest_width;
|
||||
blit.dst_height = dest_height;
|
||||
blit.dst_stride = dest_stride * (int32_t)sizeof(lv_color_t);
|
||||
blit.dst_area.x1 = blend_area.x1;
|
||||
blit.dst_area.y1 = blend_area.y1;
|
||||
blit.dst_area.x2 = blend_area.x2;
|
||||
blit.dst_area.y2 = blend_area.y2;
|
||||
|
||||
blit.opa = dsc->opa;
|
||||
blit.zoom = LV_IMG_ZOOM_NONE;
|
||||
blit.angle = 0;
|
||||
|
||||
done = (lv_gpu_nxp_vglite_blit(&blit) == LV_RES_OK);
|
||||
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite blit failed. Fallback.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(!done)
|
||||
lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||
}
|
||||
|
||||
static void lv_draw_nxp_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf)
|
||||
{
|
||||
/*Use the clip area as draw area*/
|
||||
lv_area_t draw_area;
|
||||
lv_area_copy(&draw_area, draw_ctx->clip_area);
|
||||
bool mask_any = lv_draw_mask_is_any(&draw_area);
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
bool recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
|
||||
#endif
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
bool scale = (dsc->zoom != LV_IMG_ZOOM_NONE);
|
||||
#endif
|
||||
bool done = false;
|
||||
|
||||
lv_area_t blend_area;
|
||||
/*Let's get the blend area which is the intersection of the area to fill and the clip area.*/
|
||||
if(!_lv_area_intersect(&blend_area, coords, draw_ctx->clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
/*Make the blend area relative to the buffer*/
|
||||
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
const lv_color_t * src_buf = (const lv_color_t *)map_p;
|
||||
if(!src_buf) {
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
if(!mask_any && !scale && !need_argb8565_support()
|
||||
#if LV_COLOR_DEPTH!=32
|
||||
&& !lv_img_cf_has_alpha(cf)
|
||||
#endif
|
||||
) {
|
||||
done = (lv_gpu_nxp_pxp_blit_transform(dest_buf, &blend_area, dest_stride, src_buf, coords,
|
||||
dsc, cf) == LV_RES_OK);
|
||||
if(!done)
|
||||
PXP_LOG_TRACE("PXP blit transform failed. Fallback.");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
if(!done && !mask_any && !need_argb8565_support() &&
|
||||
!lv_img_cf_is_chroma_keyed(cf) && !recolor
|
||||
#if LV_COLOR_DEPTH!=32
|
||||
&& !lv_img_cf_has_alpha(cf)
|
||||
#endif
|
||||
) {
|
||||
lv_gpu_nxp_vglite_blit_info_t blit;
|
||||
lv_coord_t src_stride = lv_area_get_width(coords);
|
||||
|
||||
blit.src = src_buf;
|
||||
blit.src_width = lv_area_get_width(coords);
|
||||
blit.src_height = lv_area_get_height(coords);
|
||||
blit.src_stride = src_stride * (int32_t)sizeof(lv_color_t);
|
||||
blit.src_area.x1 = (blend_area.x1 - (coords->x1 - draw_ctx->buf_area->x1));
|
||||
blit.src_area.y1 = (blend_area.y1 - (coords->y1 - draw_ctx->buf_area->y1));
|
||||
blit.src_area.x2 = blit.src_area.x1 + blit.src_width - 1;
|
||||
blit.src_area.y2 = blit.src_area.y1 + blit.src_height - 1;
|
||||
|
||||
blit.dst = dest_buf;
|
||||
blit.dst_width = lv_area_get_width(draw_ctx->buf_area);
|
||||
blit.dst_height = lv_area_get_height(draw_ctx->buf_area);
|
||||
blit.dst_stride = dest_stride * (int32_t)sizeof(lv_color_t);
|
||||
blit.dst_area.x1 = blend_area.x1;
|
||||
blit.dst_area.y1 = blend_area.y1;
|
||||
blit.dst_area.x2 = blend_area.x2;
|
||||
blit.dst_area.y2 = blend_area.y2;
|
||||
|
||||
blit.opa = dsc->opa;
|
||||
blit.angle = dsc->angle;
|
||||
blit.pivot = dsc->pivot;
|
||||
blit.zoom = dsc->zoom;
|
||||
|
||||
done = (lv_gpu_nxp_vglite_blit_transform(&blit) == LV_RES_OK);
|
||||
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite blit transform failed. Fallback.");
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!done)
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
|
||||
}
|
||||
|
||||
static void lv_draw_nxp_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
bool done = false;
|
||||
lv_draw_rect_dsc_t nxp_dsc;
|
||||
|
||||
lv_memcpy(&nxp_dsc, dsc, sizeof(nxp_dsc));
|
||||
#if LV_DRAW_COMPLEX
|
||||
/* Draw only the shadow */
|
||||
nxp_dsc.bg_opa = 0;
|
||||
nxp_dsc.bg_img_opa = 0;
|
||||
nxp_dsc.border_opa = 0;
|
||||
nxp_dsc.outline_opa = 0;
|
||||
|
||||
lv_draw_sw_rect(draw_ctx, &nxp_dsc, coords);
|
||||
|
||||
/* Draw the background */
|
||||
nxp_dsc.shadow_opa = 0;
|
||||
nxp_dsc.bg_opa = dsc->bg_opa;
|
||||
done = (draw_nxp_bg(draw_ctx, &nxp_dsc, coords) == LV_RES_OK);
|
||||
#endif /*LV_DRAW_COMPLEX*/
|
||||
|
||||
/* Draw the remaining parts */
|
||||
nxp_dsc.shadow_opa = 0;
|
||||
if(done)
|
||||
nxp_dsc.bg_opa = 0;
|
||||
nxp_dsc.bg_img_opa = dsc->bg_img_opa;
|
||||
nxp_dsc.border_opa = dsc->border_opa;
|
||||
nxp_dsc.outline_opa = dsc->outline_opa;
|
||||
|
||||
lv_draw_sw_rect(draw_ctx, &nxp_dsc, coords);
|
||||
}
|
||||
|
||||
static lv_res_t draw_nxp_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->bg_opa <= LV_OPA_MIN)
|
||||
return LV_RES_INV;
|
||||
|
||||
lv_area_t bg_coords;
|
||||
lv_area_copy(&bg_coords, coords);
|
||||
|
||||
/*If the border fully covers make the bg area 1px smaller to avoid artifacts on the corners*/
|
||||
if(dsc->border_width > 1 && dsc->border_opa >= (lv_opa_t)LV_OPA_MAX && dsc->radius != 0) {
|
||||
bg_coords.x1 += (dsc->border_side & LV_BORDER_SIDE_LEFT) ? 1 : 0;
|
||||
bg_coords.y1 += (dsc->border_side & LV_BORDER_SIDE_TOP) ? 1 : 0;
|
||||
bg_coords.x2 -= (dsc->border_side & LV_BORDER_SIDE_RIGHT) ? 1 : 0;
|
||||
bg_coords.y2 -= (dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? 1 : 0;
|
||||
}
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!_lv_area_intersect(&clipped_coords, &bg_coords, draw_ctx->clip_area))
|
||||
return LV_RES_INV;
|
||||
|
||||
lv_grad_dir_t grad_dir = dsc->bg_grad.dir;
|
||||
lv_color_t bg_color = grad_dir == LV_GRAD_DIR_NONE ? dsc->bg_color : dsc->bg_grad.stops[0].color;
|
||||
if(bg_color.full == dsc->bg_grad.stops[1].color.full) grad_dir = LV_GRAD_DIR_NONE;
|
||||
|
||||
bool mask_any = lv_draw_mask_is_any(&bg_coords);
|
||||
|
||||
/*
|
||||
* Most simple case: just a plain rectangle (no mask, no radius, no gradient)
|
||||
* shall fallback to lv_draw_sw_blend().
|
||||
*
|
||||
* Complex case: gradient or radius but no mask.
|
||||
*/
|
||||
if(!mask_any && ((dsc->radius != 0) || (grad_dir != LV_GRAD_DIR_NONE)) && !need_argb8565_support()) {
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
lv_res_t res = lv_gpu_nxp_vglite_draw_bg(draw_ctx, dsc, &bg_coords);
|
||||
if(res != LV_RES_OK)
|
||||
VG_LITE_LOG_TRACE("VG-Lite draw bg failed. Fallback.");
|
||||
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
static void lv_draw_nxp_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
||||
uint16_t radius, uint16_t start_angle, uint16_t end_angle)
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
#if LV_DRAW_COMPLEX
|
||||
if(dsc->opa <= LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(start_angle == end_angle)
|
||||
return;
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
if(!need_argb8565_support()) {
|
||||
done = (lv_gpu_nxp_vglite_draw_arc(draw_ctx, dsc, center, (int32_t)radius,
|
||||
(int32_t)start_angle, (int32_t)end_angle) == LV_RES_OK);
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite draw arc failed. Fallback.");
|
||||
}
|
||||
#endif
|
||||
#endif/*LV_DRAW_COMPLEX*/
|
||||
|
||||
if(!done)
|
||||
lv_draw_sw_arc(draw_ctx, dsc, center, radius, start_angle, end_angle);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE*/
|
||||
@@ -1,3 +1,4 @@
|
||||
CSRCS += lv_draw_pxp.c
|
||||
CSRCS += lv_draw_pxp_blend.c
|
||||
CSRCS += lv_gpu_nxp_pxp_osa.c
|
||||
CSRCS += lv_gpu_nxp_pxp.c
|
||||
|
||||
275
src/draw/nxp/pxp/lv_draw_pxp.c
Normal file
275
src/draw/nxp/pxp/lv_draw_pxp.c
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* @file lv_draw_pxp.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_pxp.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
#include "lv_draw_pxp_blend.h"
|
||||
|
||||
#if LV_COLOR_DEPTH != 32
|
||||
#include "../../../core/lv_refr.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* Minimum area (in pixels) for PXP blit/fill processing. */
|
||||
#ifndef LV_GPU_NXP_PXP_SIZE_LIMIT
|
||||
#define LV_GPU_NXP_PXP_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void lv_draw_pxp_wait_for_finish(lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
static void lv_draw_pxp_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
|
||||
|
||||
static void lv_draw_pxp_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf);
|
||||
|
||||
static void lv_draw_pxp_buffer_copy(lv_draw_ctx_t * draw_ctx,
|
||||
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
|
||||
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_pxp_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_draw_sw_init_ctx(drv, draw_ctx);
|
||||
|
||||
lv_draw_pxp_ctx_t * pxp_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx;
|
||||
pxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_pxp_img_decoded;
|
||||
pxp_draw_ctx->blend = lv_draw_pxp_blend;
|
||||
pxp_draw_ctx->base_draw.wait_for_finish = lv_draw_pxp_wait_for_finish;
|
||||
pxp_draw_ctx->base_draw.buffer_copy = lv_draw_pxp_buffer_copy;
|
||||
}
|
||||
|
||||
void lv_draw_pxp_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_draw_sw_deinit_ctx(drv, draw_ctx);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* During rendering, LVGL might initializes new draw_ctxs and start drawing into
|
||||
* a separate buffer (called layer). If the content to be rendered has "holes",
|
||||
* e.g. rounded corner, LVGL temporarily sets the disp_drv.screen_transp flag.
|
||||
* It means the renderers should draw into an ARGB buffer.
|
||||
* With 32 bit color depth it's not a big problem but with 16 bit color depth
|
||||
* the target pixel format is ARGB8565 which is not supported by the GPU.
|
||||
* In this case, the PXP callbacks should fallback to SW rendering.
|
||||
*/
|
||||
static inline bool need_argb8565_support()
|
||||
{
|
||||
#if LV_COLOR_DEPTH != 32
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
if(disp->driver->screen_transp == 1)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void lv_draw_pxp_wait_for_finish(lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_gpu_nxp_pxp_wait();
|
||||
|
||||
lv_draw_sw_wait_for_finish(draw_ctx);
|
||||
}
|
||||
|
||||
static void lv_draw_pxp_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
if(need_argb8565_support()) {
|
||||
lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t blend_area;
|
||||
/*Let's get the blend area which is the intersection of the area to draw and the clip area*/
|
||||
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
/*Make the blend area relative to the buffer*/
|
||||
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
if(dsc->mask_buf != NULL || dsc->blend_mode != LV_BLEND_MODE_NORMAL ||
|
||||
lv_area_get_size(&blend_area) < LV_GPU_NXP_PXP_SIZE_LIMIT) {
|
||||
lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||
return;
|
||||
}
|
||||
|
||||
/*Fill/Blend only non masked, normal blended*/
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
|
||||
const lv_color_t * src_buf = dsc->src_buf;
|
||||
|
||||
if(src_buf == NULL) {
|
||||
lv_gpu_nxp_pxp_fill(dest_buf, &blend_area, dest_stride, dsc->color, dsc->opa);
|
||||
}
|
||||
else {
|
||||
lv_area_t src_area;
|
||||
src_area.x1 = blend_area.x1 - (dsc->blend_area->x1 - draw_ctx->buf_area->x1);
|
||||
src_area.y1 = blend_area.y1 - (dsc->blend_area->y1 - draw_ctx->buf_area->y1);
|
||||
src_area.x2 = src_area.x1 + lv_area_get_width(dsc->blend_area) - 1;
|
||||
src_area.y2 = src_area.y1 + lv_area_get_height(dsc->blend_area) - 1;
|
||||
lv_coord_t src_stride = lv_area_get_width(dsc->blend_area);
|
||||
|
||||
lv_gpu_nxp_pxp_blit(dest_buf, &blend_area, dest_stride, src_buf, &src_area, src_stride,
|
||||
dsc->opa, LV_DISP_ROT_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
static void lv_draw_pxp_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
if(need_argb8565_support()) {
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
|
||||
return;
|
||||
}
|
||||
|
||||
const lv_color_t * src_buf = (const lv_color_t *)map_p;
|
||||
if(!src_buf) {
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t rel_coords;
|
||||
lv_area_copy(&rel_coords, coords);
|
||||
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
|
||||
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
bool has_scale = (dsc->zoom != LV_IMG_ZOOM_NONE);
|
||||
bool has_rotation = (dsc->angle != 0);
|
||||
bool unsup_rotation = false;
|
||||
|
||||
lv_area_t blend_area;
|
||||
if(has_rotation)
|
||||
lv_area_copy(&blend_area, &rel_coords);
|
||||
else if(!_lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
bool has_mask = lv_draw_mask_is_any(&blend_area);
|
||||
lv_coord_t src_width = lv_area_get_width(coords);
|
||||
lv_coord_t src_height = lv_area_get_height(coords);
|
||||
|
||||
if(has_rotation) {
|
||||
/*
|
||||
* PXP can only rotate at 90x angles.
|
||||
*/
|
||||
if(dsc->angle % 900) {
|
||||
PXP_LOG_TRACE("Rotation angle %d is not supported. PXP can rotate only 90x angle.", dsc->angle);
|
||||
unsup_rotation = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* PXP is set to process 16x16 blocks to optimize the system for memory
|
||||
* bandwidth and image processing time.
|
||||
* The output engine essentially truncates any output pixels after the
|
||||
* desired number of pixels has been written.
|
||||
* When rotating a source image and the output is not divisible by the block
|
||||
* size, the incorrect pixels could be truncated and the final output image
|
||||
* can look shifted.
|
||||
*/
|
||||
if(src_width % 16 || src_height % 16) {
|
||||
PXP_LOG_TRACE("Rotation is not supported for image w/o alignment to block size 16x16.");
|
||||
unsup_rotation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_mask || has_scale || unsup_rotation || lv_area_get_size(&blend_area) < LV_GPU_NXP_PXP_SIZE_LIMIT
|
||||
#if LV_COLOR_DEPTH != 32
|
||||
|| lv_img_cf_has_alpha(cf)
|
||||
#endif
|
||||
) {
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
|
||||
|
||||
lv_area_t src_area;
|
||||
src_area.x1 = blend_area.x1 - (coords->x1 - draw_ctx->buf_area->x1);
|
||||
src_area.y1 = blend_area.y1 - (coords->y1 - draw_ctx->buf_area->y1);
|
||||
src_area.x2 = src_area.x1 + src_width - 1;
|
||||
src_area.y2 = src_area.y1 + src_height - 1;
|
||||
lv_coord_t src_stride = lv_area_get_width(coords);
|
||||
|
||||
lv_gpu_nxp_pxp_blit_transform(dest_buf, &blend_area, dest_stride, src_buf, &src_area, src_stride,
|
||||
dsc, cf);
|
||||
}
|
||||
|
||||
static void lv_draw_pxp_buffer_copy(lv_draw_ctx_t * draw_ctx,
|
||||
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
|
||||
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area)
|
||||
{
|
||||
LV_UNUSED(draw_ctx);
|
||||
|
||||
if(lv_area_get_size(dest_area) < LV_GPU_NXP_PXP_SIZE_LIMIT) {
|
||||
lv_draw_sw_buffer_copy(draw_ctx, dest_buf, dest_stride, dest_area, src_buf, src_stride, src_area);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_gpu_nxp_pxp_buffer_copy(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_PXP*/
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* @file lv_gpu_nxp.h
|
||||
* @file lv_draw_pxp.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2022 NXP
|
||||
* Copyright 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -27,8 +27,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GPU_NXP_H
|
||||
#define LV_GPU_NXP_H
|
||||
#ifndef LV_DRAW_PXP_H
|
||||
#define LV_DRAW_PXP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -38,9 +38,10 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE
|
||||
#include "../sw/lv_draw_sw.h"
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
#include "../../sw/lv_draw_sw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -49,23 +50,23 @@ extern "C" {
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef lv_draw_sw_ctx_t lv_draw_nxp_ctx_t;
|
||||
typedef lv_draw_sw_ctx_t lv_draw_pxp_ctx_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_nxp_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||
void lv_draw_pxp_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
void lv_draw_nxp_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||
void lv_draw_pxp_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#endif /*LV_USE_GPU_NXP_PXP || LV_USE_GPU_NXP_VG_LITE*/
|
||||
#endif /*LV_USE_GPU_NXP_PXP*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_GPU_NXP_H*/
|
||||
#endif /*LV_DRAW_PXP_H*/
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020-2022 NXP
|
||||
* Copyright 2020-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "lv_draw_pxp_blend.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
#include "lvgl_support.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -43,25 +44,25 @@
|
||||
#error Color swap not implemented. Disable LV_COLOR_16_SWAP feature.
|
||||
#endif
|
||||
|
||||
#if LV_COLOR_DEPTH==16
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
#define PXP_OUT_PIXEL_FORMAT kPXP_OutputPixelFormatRGB565
|
||||
#define PXP_AS_PIXEL_FORMAT kPXP_AsPixelFormatRGB565
|
||||
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB565
|
||||
#elif LV_COLOR_DEPTH==32
|
||||
#define PXP_TEMP_BUF_SIZE LCD_WIDTH * LCD_HEIGHT * 2U
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define PXP_OUT_PIXEL_FORMAT kPXP_OutputPixelFormatARGB8888
|
||||
#define PXP_AS_PIXEL_FORMAT kPXP_AsPixelFormatARGB8888
|
||||
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB888
|
||||
#if (!(defined(FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT) && FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT)) && \
|
||||
(!(defined(FSL_FEATURE_PXP_V3) && FSL_FEATURE_PXP_V3))
|
||||
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatARGB8888
|
||||
#else
|
||||
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB888
|
||||
#endif
|
||||
#define PXP_TEMP_BUF_SIZE LCD_WIDTH * LCD_HEIGHT * 4U
|
||||
#elif
|
||||
#error Only 16bit and 32bit color depth are supported. Set LV_COLOR_DEPTH to 16 or 32.
|
||||
#endif
|
||||
|
||||
#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \
|
||||
|| defined (_WIN64) || defined (__LP64__) || defined (__LLP64__)
|
||||
#define ALIGN_SIZE 8
|
||||
#else
|
||||
#define ALIGN_SIZE 4
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -70,63 +71,60 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static LV_ATTRIBUTE_MEM_ALIGN uint8_t temp_buf[PXP_TEMP_BUF_SIZE];
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src buffer to dst buffer
|
||||
* with combination of transformation (rotation, scale, recolor) and opacity, alpha channel
|
||||
* or color keying. This requires two steps. First step is used for transformation into
|
||||
* a temporary buffer and the second one will handle the color format or opacity.
|
||||
*
|
||||
* @param[in/out] dest_buf destination buffer
|
||||
* @param[in] dest_area area to be copied from src_buf to dst_buf
|
||||
* @param[in] dest_stride width (stride) of destination buffer in pixels
|
||||
* @param[in] src_buf source buffer
|
||||
* @param[in] src_area source area with absolute coordinates to draw on destination buffer
|
||||
* @param[in] dsc image descriptor
|
||||
* @param[in] cf color format
|
||||
* @retval LV_RES_OK Fill completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS)
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] dsc Image descriptor
|
||||
* @param[in] cf Color format
|
||||
*/
|
||||
static lv_res_t lv_gpu_nxp_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
|
||||
static void lv_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src buffer to dst buffer
|
||||
* with transformation and full opacity.
|
||||
*
|
||||
* @param[in/out] dest_buf destination buffer
|
||||
* @param[in] dest_area area to be copied from src_buf to dst_buf
|
||||
* @param[in] dest_stride width (stride) of destination buffer in pixels
|
||||
* @param[in] src_buf source buffer
|
||||
* @param[in] src_area source area with absolute coordinates to draw on destination buffer
|
||||
* @param[in] dsc image descriptor
|
||||
* @param[in] cf color format
|
||||
* @retval LV_RES_OK Fill completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS)
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] dsc Image descriptor
|
||||
* @param[in] cf Color format
|
||||
*/
|
||||
static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area,
|
||||
lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
|
||||
static void lv_pxp_blit_cover(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src buffer to dst buffer
|
||||
* without transformation but handling color format or opacity.
|
||||
*
|
||||
* @param[in/out] dest_buf destination buffer
|
||||
* @param[in] dest_area area to be copied from src_buf to dst_buf
|
||||
* @param[in] dest_stride width (stride) of destination buffer in pixels
|
||||
* @param[in] src_buf source buffer
|
||||
* @param[in] src_area source area with absolute coordinates to draw on destination buffer
|
||||
* @param[in] dsc image descriptor
|
||||
* @param[in] cf color format
|
||||
* @retval LV_RES_OK Fill completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS)
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] dsc Image descriptor
|
||||
* @param[in] cf Color format
|
||||
*/
|
||||
static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * dest_area,
|
||||
lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
|
||||
static void lv_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -136,45 +134,27 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t *
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define ROUND_UP(x, align) ((x + (align - 1)) & ~(align - 1))
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
void lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
uint32_t area_size = lv_area_get_size(fill_area);
|
||||
lv_coord_t area_w = lv_area_get_width(fill_area);
|
||||
lv_coord_t area_h = lv_area_get_height(fill_area);
|
||||
lv_coord_t dest_w = lv_area_get_width(dest_area);
|
||||
lv_coord_t dest_h = lv_area_get_height(dest_area);
|
||||
|
||||
if(opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
if(area_size < LV_GPU_NXP_PXP_FILL_SIZE_LIMIT) {
|
||||
PXP_LOG_TRACE("Area size %d smaller than limit %d.", area_size, LV_GPU_NXP_PXP_FILL_SIZE_LIMIT);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(area_size < LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT) {
|
||||
PXP_LOG_TRACE("Area size %d smaller than limit %d.", area_size, LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
|
||||
PXP_Init(LV_GPU_NXP_PXP_ID);
|
||||
PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/
|
||||
PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*Block size 16x16 for higher performance*/
|
||||
lv_gpu_nxp_pxp_reset();
|
||||
|
||||
/*OUT buffer configure*/
|
||||
pxp_output_buffer_config_t outputConfig = {
|
||||
.pixelFormat = PXP_OUT_PIXEL_FORMAT,
|
||||
.interlacedMode = kPXP_OutputProgressive,
|
||||
.buffer0Addr = (uint32_t)(dest_buf + dest_stride * fill_area->y1 + fill_area->x1),
|
||||
.buffer0Addr = (uint32_t)(dest_buf + dest_stride * dest_area->y1 + dest_area->x1),
|
||||
.buffer1Addr = (uint32_t)NULL,
|
||||
.pitchBytes = dest_stride * sizeof(lv_color_t),
|
||||
.width = area_w,
|
||||
.height = area_h
|
||||
.width = dest_w,
|
||||
.height = dest_h
|
||||
};
|
||||
|
||||
PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputConfig);
|
||||
@@ -193,7 +173,7 @@ lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, cons
|
||||
};
|
||||
|
||||
PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, area_w, area_h);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
|
||||
}
|
||||
|
||||
/*Disable PS, use as color generator*/
|
||||
@@ -223,34 +203,19 @@ lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, cons
|
||||
|
||||
PXP_SetPorterDuffConfig(LV_GPU_NXP_PXP_ID, &pdConfig);
|
||||
|
||||
lv_gpu_nxp_pxp_run(); /*Start PXP task*/
|
||||
|
||||
return LV_RES_OK;
|
||||
lv_gpu_nxp_pxp_run();
|
||||
}
|
||||
|
||||
lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_opa_t opa, lv_disp_rot_t angle)
|
||||
void lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
lv_opa_t opa, lv_disp_rot_t angle)
|
||||
{
|
||||
uint32_t dest_size = lv_area_get_size(dest_area);
|
||||
lv_coord_t dest_w = lv_area_get_width(dest_area);
|
||||
lv_coord_t dest_h = lv_area_get_height(dest_area);
|
||||
lv_coord_t src_w = lv_area_get_width(src_area);
|
||||
lv_coord_t src_h = lv_area_get_height(src_area);
|
||||
|
||||
if(opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
if(dest_size < LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT) {
|
||||
PXP_LOG_TRACE("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(dest_size < LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT) {
|
||||
PXP_LOG_TRACE("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
|
||||
PXP_Init(LV_GPU_NXP_PXP_ID);
|
||||
PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/
|
||||
PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*block size 16x16 for higher performance*/
|
||||
lv_gpu_nxp_pxp_reset();
|
||||
|
||||
/* convert rotation angle */
|
||||
pxp_rotate_degree_t pxp_rot;
|
||||
@@ -297,19 +262,17 @@ lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area,
|
||||
asBlendConfig.alphaMode = kPXP_AlphaOverride;
|
||||
|
||||
PXP_SetProcessSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &psBufferConfig);
|
||||
PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1, dest_h - 1);
|
||||
PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
|
||||
}
|
||||
|
||||
lv_coord_t src_stride = lv_area_get_width(src_area);
|
||||
|
||||
/*AS buffer - source image*/
|
||||
pxp_as_buffer_config_t asBufferConfig = {
|
||||
.pixelFormat = PXP_AS_PIXEL_FORMAT,
|
||||
.bufferAddr = (uint32_t)src_buf,
|
||||
.bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_area->x1),
|
||||
.pitchBytes = src_stride * sizeof(lv_color_t)
|
||||
};
|
||||
PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, src_w - 1U, src_h - 1U);
|
||||
PXP_SetAlphaSurfaceBlendConfig(LV_GPU_NXP_PXP_ID, &asBlendConfig);
|
||||
PXP_EnableAlphaSurfaceOverlayColorKey(LV_GPU_NXP_PXP_ID, false);
|
||||
|
||||
@@ -325,162 +288,147 @@ lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area,
|
||||
};
|
||||
PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputBufferConfig);
|
||||
|
||||
lv_gpu_nxp_pxp_run(); /* Start PXP task */
|
||||
|
||||
return LV_RES_OK;
|
||||
lv_gpu_nxp_pxp_run();
|
||||
}
|
||||
|
||||
lv_res_t lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
|
||||
void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
|
||||
{
|
||||
uint32_t dest_size = lv_area_get_size(dest_area);
|
||||
bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
|
||||
bool has_rotation = (dsc->angle != 0);
|
||||
|
||||
if(dsc->opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
if(dest_size < LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT) {
|
||||
PXP_LOG_TRACE("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT);
|
||||
return LV_RES_INV;
|
||||
if(has_recolor || has_rotation) {
|
||||
if(dsc->opa >= (lv_opa_t)LV_OPA_MAX && !lv_img_cf_has_alpha(cf) && !lv_img_cf_is_chroma_keyed(cf)) {
|
||||
lv_pxp_blit_cover(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc, cf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(dest_size < LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT) {
|
||||
PXP_LOG_TRACE("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
|
||||
bool recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
|
||||
bool rotation = (dsc->angle != 0);
|
||||
|
||||
if(rotation) {
|
||||
if(dsc->angle != 0 && dsc->angle != 900 && dsc->angle != 1800 && dsc->angle != 2700) {
|
||||
PXP_LOG_TRACE("Rotation angle %d is not supported. PXP can rotate only 90x angle.", dsc->angle);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
|
||||
if(recolor || rotation) {
|
||||
if(dsc->opa >= (lv_opa_t)LV_OPA_MAX && !lv_img_cf_has_alpha(cf) && !lv_img_cf_is_chroma_keyed(cf))
|
||||
return lv_gpu_nxp_pxp_blit_cover(dest_buf, dest_area, dest_stride, src_buf, src_area, dsc, cf);
|
||||
else
|
||||
else {
|
||||
/*Recolor and/or rotation with alpha or opacity is done in two steps.*/
|
||||
return lv_gpu_nxp_pxp_blit_opa(dest_buf, dest_area, dest_stride, src_buf, src_area, dsc, cf);
|
||||
lv_pxp_blit_opa(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc, cf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return lv_gpu_nxp_pxp_blit_cf(dest_buf, dest_area, dest_stride, src_buf, src_area, dsc, cf);
|
||||
lv_pxp_blit_cf(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, dsc, cf);
|
||||
}
|
||||
|
||||
void lv_gpu_nxp_pxp_buffer_copy(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride)
|
||||
{
|
||||
lv_coord_t src_width = lv_area_get_width(src_area);
|
||||
lv_coord_t src_height = lv_area_get_height(src_area);
|
||||
|
||||
lv_gpu_nxp_pxp_reset();
|
||||
|
||||
const pxp_pic_copy_config_t picCopyConfig = {
|
||||
.srcPicBaseAddr = (uint32_t)src_buf,
|
||||
.srcPitchBytes = src_stride * sizeof(lv_color_t),
|
||||
.srcOffsetX = src_area->x1,
|
||||
.srcOffsetY = src_area->y1,
|
||||
.destPicBaseAddr = (uint32_t)dest_buf,
|
||||
.destPitchBytes = dest_stride * sizeof(lv_color_t),
|
||||
.destOffsetX = dest_area->x1,
|
||||
.destOffsetY = dest_area->y1,
|
||||
.width = src_width,
|
||||
.height = src_height,
|
||||
.pixelFormat = PXP_AS_PIXEL_FORMAT
|
||||
};
|
||||
|
||||
PXP_StartPictureCopy(LV_GPU_NXP_PXP_ID, &picCopyConfig);
|
||||
|
||||
lv_gpu_nxp_pxp_wait();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_res_t lv_gpu_nxp_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
|
||||
static void lv_pxp_blit_opa(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
|
||||
{
|
||||
lv_coord_t dest_w = lv_area_get_width(dest_area);
|
||||
lv_coord_t dest_h = lv_area_get_height(dest_area);
|
||||
lv_res_t res;
|
||||
uint32_t size = dest_w * dest_h * sizeof(lv_color_t);
|
||||
|
||||
if(ROUND_UP(size, ALIGN_SIZE) >= LV_MEM_SIZE)
|
||||
PXP_RETURN_INV("Insufficient memory for temporary buffer. Please increase LV_MEM_SIZE.");
|
||||
|
||||
lv_color_t * tmp_buf = (lv_color_t *)lv_mem_buf_get(size);
|
||||
if(!tmp_buf)
|
||||
PXP_RETURN_INV("Allocating temporary buffer failed.");
|
||||
|
||||
const lv_area_t tmp_area = {
|
||||
.x1 = 0,
|
||||
.y1 = 0,
|
||||
.x2 = dest_w - 1,
|
||||
.y2 = dest_h - 1
|
||||
};
|
||||
lv_area_t temp_area;
|
||||
lv_area_copy(&temp_area, dest_area);
|
||||
lv_coord_t temp_stride = dest_stride;
|
||||
lv_coord_t temp_w = lv_area_get_width(&temp_area);
|
||||
lv_coord_t temp_h = lv_area_get_height(&temp_area);
|
||||
|
||||
/*Step 1: Transform with full opacity to temporary buffer*/
|
||||
res = lv_gpu_nxp_pxp_blit_cover(tmp_buf, &tmp_area, dest_w, src_buf, src_area, dsc, cf);
|
||||
if(res != LV_RES_OK) {
|
||||
PXP_LOG_TRACE("Blit cover with full opacity failed.");
|
||||
lv_mem_buf_release(tmp_buf);
|
||||
lv_pxp_blit_cover((lv_color_t *)temp_buf, &temp_area, temp_stride, src_buf, src_area, src_stride, dsc, cf);
|
||||
|
||||
return res;
|
||||
/*Switch width and height if angle requires it*/
|
||||
if(dsc->angle == 900 || dsc->angle == 2700) {
|
||||
temp_area.x2 = temp_area.x1 + temp_h - 1;
|
||||
temp_area.y2 = temp_area.y1 + temp_w - 1;
|
||||
}
|
||||
|
||||
/*Step 2: Blit temporary results with required opacity to output*/
|
||||
res = lv_gpu_nxp_pxp_blit_cf(dest_buf, dest_area, dest_stride, tmp_buf, &tmp_area, dsc, cf);
|
||||
|
||||
/*Clean-up memory*/
|
||||
lv_mem_buf_release(tmp_buf);
|
||||
|
||||
return res;
|
||||
/*Step 2: Blit temporary result with required opacity to output*/
|
||||
lv_pxp_blit_cf(dest_buf, &temp_area, dest_stride, (lv_color_t *)temp_buf, &temp_area, temp_stride, dsc, cf);
|
||||
}
|
||||
|
||||
static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t * dest_area,
|
||||
lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
|
||||
static void lv_pxp_blit_cover(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
|
||||
{
|
||||
lv_coord_t dest_w = lv_area_get_width(dest_area);
|
||||
lv_coord_t dest_h = lv_area_get_height(dest_area);
|
||||
lv_coord_t src_w = lv_area_get_width(src_area);
|
||||
lv_coord_t src_h = lv_area_get_height(src_area);
|
||||
|
||||
bool recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
|
||||
bool rotation = (dsc->angle != 0);
|
||||
bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
|
||||
bool has_rotation = (dsc->angle != 0);
|
||||
|
||||
PXP_Init(LV_GPU_NXP_PXP_ID);
|
||||
PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/
|
||||
PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*block size 16x16 for higher performance*/
|
||||
lv_point_t pivot = dsc->pivot;
|
||||
lv_coord_t piv_offset_x;
|
||||
lv_coord_t piv_offset_y;
|
||||
|
||||
if(rotation) {
|
||||
/*
|
||||
* PXP is set to process 16x16 blocks to optimize the system for memory
|
||||
* bandwidth and image processing time.
|
||||
* The output engine essentially truncates any output pixels after the
|
||||
* desired number of pixels has been written.
|
||||
* When rotating a source image and the output is not divisible by the block
|
||||
* size, the incorrect pixels could be truncated and the final output image
|
||||
* can look shifted.
|
||||
*/
|
||||
if(lv_area_get_width(src_area) % 16 || lv_area_get_height(src_area) % 16) {
|
||||
PXP_LOG_TRACE("Rotation is not supported for image w/o alignment to block size 16x16.");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
lv_gpu_nxp_pxp_reset();
|
||||
|
||||
/*Convert rotation angle*/
|
||||
pxp_rotate_degree_t pxp_rot;
|
||||
if(has_rotation) {
|
||||
/*Convert rotation angle and calculate offsets caused by pivot*/
|
||||
pxp_rotate_degree_t pxp_angle;
|
||||
switch(dsc->angle) {
|
||||
case 0:
|
||||
pxp_rot = kPXP_Rotate0;
|
||||
pxp_angle = kPXP_Rotate0;
|
||||
piv_offset_x = 0;
|
||||
piv_offset_y = 0;
|
||||
break;
|
||||
case 900:
|
||||
pxp_rot = kPXP_Rotate90;
|
||||
piv_offset_x = pivot.x + pivot.y - dest_h;
|
||||
piv_offset_y = pivot.y - pivot.x;
|
||||
pxp_angle = kPXP_Rotate90;
|
||||
break;
|
||||
case 1800:
|
||||
pxp_rot = kPXP_Rotate180;
|
||||
piv_offset_x = 2 * pivot.x - dest_w;
|
||||
piv_offset_y = 2 * pivot.y - dest_h;
|
||||
pxp_angle = kPXP_Rotate180;
|
||||
break;
|
||||
case 2700:
|
||||
pxp_rot = kPXP_Rotate270;
|
||||
piv_offset_x = pivot.x - pivot.y;
|
||||
piv_offset_y = pivot.x + pivot.y - dest_w;
|
||||
pxp_angle = kPXP_Rotate270;
|
||||
break;
|
||||
default:
|
||||
PXP_LOG_TRACE("Rotation angle %d is not supported. PXP can rotate only 90x angle.", dsc->angle);
|
||||
return LV_RES_INV;
|
||||
piv_offset_x = 0;
|
||||
piv_offset_y = 0;
|
||||
pxp_angle = kPXP_Rotate0;
|
||||
}
|
||||
PXP_SetRotateConfig(LV_GPU_NXP_PXP_ID, kPXP_RotateOutputBuffer, pxp_rot, kPXP_FlipDisable);
|
||||
PXP_SetRotateConfig(LV_GPU_NXP_PXP_ID, kPXP_RotateOutputBuffer, pxp_angle, kPXP_FlipDisable);
|
||||
lv_area_move(dest_area, piv_offset_x, piv_offset_y);
|
||||
}
|
||||
|
||||
lv_coord_t src_stride = lv_area_get_width(src_area);
|
||||
|
||||
/*AS buffer - source image*/
|
||||
pxp_as_buffer_config_t asBufferConfig = {
|
||||
.pixelFormat = PXP_AS_PIXEL_FORMAT,
|
||||
.bufferAddr = (uint32_t)src_buf,
|
||||
.bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_area->x1),
|
||||
.pitchBytes = src_stride * sizeof(lv_color_t)
|
||||
};
|
||||
PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, src_w - 1U, src_h - 1U);
|
||||
|
||||
/*Disable PS buffer*/
|
||||
PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
|
||||
if(recolor)
|
||||
if(has_recolor)
|
||||
/*Use as color generator*/
|
||||
PXP_SetProcessSurfaceBackGroundColor(LV_GPU_NXP_PXP_ID, lv_color_to32(dsc->recolor));
|
||||
|
||||
@@ -496,7 +444,7 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t
|
||||
};
|
||||
PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputBufferConfig);
|
||||
|
||||
if(recolor || lv_img_cf_has_alpha(cf)) {
|
||||
if(has_recolor || lv_img_cf_has_alpha(cf)) {
|
||||
/**
|
||||
* Configure Porter-Duff blending.
|
||||
*
|
||||
@@ -512,7 +460,7 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t
|
||||
.srcGlobalAlphaMode = lv_img_cf_has_alpha(cf) ? kPXP_PorterDuffLocalAlpha : kPXP_PorterDuffGlobalAlpha,
|
||||
.dstFactorMode = kPXP_PorterDuffFactorStraight,
|
||||
.srcFactorMode = kPXP_PorterDuffFactorInversed,
|
||||
.dstGlobalAlpha = recolor ? dsc->recolor_opa : 0x00,
|
||||
.dstGlobalAlpha = has_recolor ? dsc->recolor_opa : 0x00,
|
||||
.srcGlobalAlpha = 0xff,
|
||||
.dstAlphaMode = kPXP_PorterDuffAlphaStraight, /*don't care*/
|
||||
.srcAlphaMode = kPXP_PorterDuffAlphaStraight
|
||||
@@ -520,22 +468,19 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cover(lv_color_t * dest_buf, const lv_area_t
|
||||
PXP_SetPorterDuffConfig(LV_GPU_NXP_PXP_ID, &pdConfig);
|
||||
}
|
||||
|
||||
lv_gpu_nxp_pxp_run(); /*Start PXP task*/
|
||||
|
||||
return LV_RES_OK;
|
||||
lv_gpu_nxp_pxp_run();
|
||||
}
|
||||
|
||||
static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * dest_area,
|
||||
lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
|
||||
static void lv_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf)
|
||||
{
|
||||
lv_coord_t dest_w = lv_area_get_width(dest_area);
|
||||
lv_coord_t dest_h = lv_area_get_height(dest_area);
|
||||
lv_coord_t src_w = lv_area_get_width(src_area);
|
||||
lv_coord_t src_h = lv_area_get_height(src_area);
|
||||
|
||||
PXP_Init(LV_GPU_NXP_PXP_ID);
|
||||
PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/
|
||||
PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*block size 16x16 for higher performance*/
|
||||
lv_gpu_nxp_pxp_reset();
|
||||
|
||||
pxp_as_blend_config_t asBlendConfig = {
|
||||
.alpha = dsc->opa,
|
||||
@@ -566,28 +511,26 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t *
|
||||
asBlendConfig.alphaMode = lv_img_cf_has_alpha(cf) ? kPXP_AlphaMultiply : kPXP_AlphaOverride;
|
||||
}
|
||||
PXP_SetProcessSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &psBufferConfig);
|
||||
PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1, dest_h - 1);
|
||||
PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
|
||||
}
|
||||
|
||||
lv_coord_t src_stride = lv_area_get_width(src_area);
|
||||
|
||||
/*AS buffer - source image*/
|
||||
pxp_as_buffer_config_t asBufferConfig = {
|
||||
.pixelFormat = PXP_AS_PIXEL_FORMAT,
|
||||
.bufferAddr = (uint32_t)src_buf,
|
||||
.bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_area->x1),
|
||||
.pitchBytes = src_stride * sizeof(lv_color_t)
|
||||
};
|
||||
PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, src_w - 1U, src_h - 1U);
|
||||
PXP_SetAlphaSurfaceBlendConfig(LV_GPU_NXP_PXP_ID, &asBlendConfig);
|
||||
|
||||
if(lv_img_cf_is_chroma_keyed(cf)) {
|
||||
lv_color_t colorKeyLow = LV_COLOR_CHROMA_KEY;
|
||||
lv_color_t colorKeyHigh = LV_COLOR_CHROMA_KEY;
|
||||
|
||||
bool recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
|
||||
bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
|
||||
|
||||
if(recolor) {
|
||||
if(has_recolor) {
|
||||
/* New color key after recoloring */
|
||||
lv_color_t colorKey = lv_color_mix(dsc->recolor, LV_COLOR_CHROMA_KEY, dsc->recolor_opa);
|
||||
|
||||
@@ -595,11 +538,11 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t *
|
||||
LV_COLOR_SET_G(colorKeyLow, colorKey.ch.green != 0 ? colorKey.ch.green - 1 : 0);
|
||||
LV_COLOR_SET_B(colorKeyLow, colorKey.ch.blue != 0 ? colorKey.ch.blue - 1 : 0);
|
||||
|
||||
#if LV_COLOR_DEPTH==16
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
LV_COLOR_SET_R(colorKeyHigh, colorKey.ch.red != 0x1f ? colorKey.ch.red + 1 : 0x1f);
|
||||
LV_COLOR_SET_G(colorKeyHigh, colorKey.ch.green != 0x3f ? colorKey.ch.green + 1 : 0x3f);
|
||||
LV_COLOR_SET_B(colorKeyHigh, colorKey.ch.blue != 0x1f ? colorKey.ch.blue + 1 : 0x1f);
|
||||
#else /*LV_COLOR_DEPTH==32*/
|
||||
#else /*LV_COLOR_DEPTH == 32*/
|
||||
LV_COLOR_SET_R(colorKeyHigh, colorKey.ch.red != 0xff ? colorKey.ch.red + 1 : 0xff);
|
||||
LV_COLOR_SET_G(colorKeyHigh, colorKey.ch.green != 0xff ? colorKey.ch.green + 1 : 0xff);
|
||||
LV_COLOR_SET_B(colorKeyHigh, colorKey.ch.blue != 0xff ? colorKey.ch.blue + 1 : 0xff);
|
||||
@@ -624,9 +567,7 @@ static lv_res_t lv_gpu_nxp_pxp_blit_cf(lv_color_t * dest_buf, const lv_area_t *
|
||||
};
|
||||
PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputBufferConfig);
|
||||
|
||||
lv_gpu_nxp_pxp_run(); /* Start PXP task */
|
||||
|
||||
return LV_RES_OK;
|
||||
lv_gpu_nxp_pxp_run();
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_PXP*/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020-2022 NXP
|
||||
* Copyright 2020-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -48,31 +48,6 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#ifndef LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) for image copy with 100% opacity to be handled by PXP*/
|
||||
#define LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) for image copy with transparency to be handled by PXP*/
|
||||
#define LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_PXP_BUFF_SYNC_BLIT_SIZE_LIMIT
|
||||
/** Minimum invalidated area (in pixels) to be synchronized by PXP during buffer sync */
|
||||
#define LV_GPU_NXP_PXP_BUFF_SYNC_BLIT_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_PXP_FILL_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) to be filled by PXP with 100% opacity*/
|
||||
#define LV_GPU_NXP_PXP_FILL_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) to be filled by PXP with transparency*/
|
||||
#define LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -84,51 +59,63 @@ extern "C" {
|
||||
/**
|
||||
* Fill area, with optional opacity.
|
||||
*
|
||||
* @param[in/out] dest_buf destination buffer
|
||||
* @param[in] dest_stride width (stride) of destination buffer in pixels
|
||||
* @param[in] fill_area area to fill
|
||||
* @param[in] color color
|
||||
* @param[in] opa transparency of the color
|
||||
* @retval LV_RES_OK Fill completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS)
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] color Color
|
||||
* @param[in] opa Opacity
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
void lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects.
|
||||
* By default, image is copied directly, with optional opacity. This function can also
|
||||
* rotate the display output buffer to a specified angle (90x step).
|
||||
*
|
||||
* @param[in/out] dest_buf destination buffer
|
||||
* @param[in] dest_area destination area
|
||||
* @param[in] dest_stride width (stride) of destination buffer in pixels
|
||||
* @param[in] src_buf source buffer
|
||||
* @param[in] src_area source area with absolute coordinates to draw on destination buffer
|
||||
* @param[in] opa opacity of the result
|
||||
* @param[in] angle display rotation angle (90x)
|
||||
* @retval LV_RES_OK Fill completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS)
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Source area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] opa Opacity
|
||||
* @param[in] angle Display rotation angle (90x)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_opa_t opa, lv_disp_rot_t angle);
|
||||
void lv_gpu_nxp_pxp_blit(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
lv_opa_t opa, lv_disp_rot_t angle);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with transformation.
|
||||
*
|
||||
*
|
||||
* @param[in/out] dest_buf destination buffer
|
||||
* @param[in] dest_area destination area
|
||||
* @param[in] dest_stride width (stride) of destination buffer in pixels
|
||||
* @param[in] src_buf source buffer
|
||||
* @param[in] src_area source area with absolute coordinates to draw on destination buffer
|
||||
* @param[in] dsc image descriptor
|
||||
* @param[in] cf color format
|
||||
* @retval LV_RES_OK Fill completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_PXP_LOG_ERRORS)
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] dsc Image descriptor
|
||||
* @param[in] cf Color format
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
|
||||
void lv_gpu_nxp_pxp_blit_transform(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc, lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf, no transformation or blending.
|
||||
*
|
||||
*
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
*/
|
||||
void lv_gpu_nxp_pxp_buffer_copy(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020-2022 NXP
|
||||
* Copyright 2020-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -50,9 +50,9 @@
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Clean & invalidate cache.
|
||||
* Clean and invalidate cache.
|
||||
*/
|
||||
static void invalidate_cache(void);
|
||||
static inline void invalidate_cache(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -70,16 +70,23 @@ static lv_nxp_pxp_cfg_t * pxp_cfg;
|
||||
|
||||
lv_res_t lv_gpu_nxp_pxp_init(void)
|
||||
{
|
||||
#if LV_USE_GPU_NXP_PXP_AUTO_INIT
|
||||
pxp_cfg = lv_gpu_nxp_pxp_get_cfg();
|
||||
#endif
|
||||
|
||||
if(!pxp_cfg || !pxp_cfg->pxp_interrupt_deinit || !pxp_cfg->pxp_interrupt_init || !pxp_cfg->pxp_run)
|
||||
if(!pxp_cfg || !pxp_cfg->pxp_interrupt_deinit || !pxp_cfg->pxp_interrupt_init ||
|
||||
!pxp_cfg->pxp_run || !pxp_cfg->pxp_wait)
|
||||
PXP_RETURN_INV("PXP configuration error.");
|
||||
|
||||
PXP_Init(LV_GPU_NXP_PXP_ID);
|
||||
|
||||
PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/
|
||||
PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*Block size 16x16 for higher performance*/
|
||||
|
||||
PXP_EnableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable);
|
||||
|
||||
if(pxp_cfg->pxp_interrupt_init() != LV_RES_OK) {
|
||||
PXP_DisableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable);
|
||||
PXP_Deinit(LV_GPU_NXP_PXP_ID);
|
||||
PXP_RETURN_INV("PXP interrupt init failed.");
|
||||
}
|
||||
@@ -90,23 +97,38 @@ lv_res_t lv_gpu_nxp_pxp_init(void)
|
||||
void lv_gpu_nxp_pxp_deinit(void)
|
||||
{
|
||||
pxp_cfg->pxp_interrupt_deinit();
|
||||
PXP_DisableInterrupts(PXP, kPXP_CompleteInterruptEnable);
|
||||
PXP_DisableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable);
|
||||
PXP_Deinit(LV_GPU_NXP_PXP_ID);
|
||||
}
|
||||
|
||||
void lv_gpu_nxp_pxp_reset(void)
|
||||
{
|
||||
/* Wait for previous command to complete before resetting the registers. */
|
||||
lv_gpu_nxp_pxp_wait();
|
||||
|
||||
PXP_ResetControl(LV_GPU_NXP_PXP_ID);
|
||||
|
||||
PXP_EnableCsc1(LV_GPU_NXP_PXP_ID, false); /*Disable CSC1, it is enabled by default.*/
|
||||
PXP_SetProcessBlockSize(LV_GPU_NXP_PXP_ID, kPXP_BlockSize16); /*Block size 16x16 for higher performance*/
|
||||
}
|
||||
|
||||
void lv_gpu_nxp_pxp_run(void)
|
||||
{
|
||||
/*Clean & invalidate cache*/
|
||||
invalidate_cache();
|
||||
|
||||
pxp_cfg->pxp_run();
|
||||
}
|
||||
|
||||
void lv_gpu_nxp_pxp_wait(void)
|
||||
{
|
||||
pxp_cfg->pxp_wait();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void invalidate_cache(void)
|
||||
static inline void invalidate_cache(void)
|
||||
{
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
if(disp->driver->clean_dcache_cb)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020-2022 NXP
|
||||
* Copyright 2020-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -81,8 +81,11 @@ typedef struct {
|
||||
/** Callback for PXP interrupt de-initialization*/
|
||||
void (*pxp_interrupt_deinit)(void);
|
||||
|
||||
/** Callback that should start PXP and wait for operation complete*/
|
||||
/** Callback for PXP start*/
|
||||
void (*pxp_run)(void);
|
||||
|
||||
/** Callback for waiting of PXP completion*/
|
||||
void (*pxp_wait)(void);
|
||||
} lv_nxp_pxp_cfg_t;
|
||||
|
||||
/**********************
|
||||
@@ -104,10 +107,20 @@ lv_res_t lv_gpu_nxp_pxp_init(void);
|
||||
void lv_gpu_nxp_pxp_deinit(void);
|
||||
|
||||
/**
|
||||
* Start PXP job and wait for completion.
|
||||
* Reset PXP device.
|
||||
*/
|
||||
void lv_gpu_nxp_pxp_reset(void);
|
||||
|
||||
/**
|
||||
* Clear cache and start PXP.
|
||||
*/
|
||||
void lv_gpu_nxp_pxp_run(void);
|
||||
|
||||
/**
|
||||
* Wait for PXP completion.
|
||||
*/
|
||||
void lv_gpu_nxp_pxp_wait(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@@ -136,7 +149,7 @@ void lv_gpu_nxp_pxp_run(void);
|
||||
#if LV_GPU_NXP_PXP_LOG_TRACES
|
||||
#define PXP_LOG_TRACE(fmt, ...) \
|
||||
do { \
|
||||
LV_LOG_ERROR(fmt, ##__VA_ARGS__); \
|
||||
LV_LOG(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define PXP_LOG_TRACE(fmt, ...) \
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020, 2022 NXP
|
||||
* Copyright 2020, 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -65,24 +65,29 @@ static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void);
|
||||
static void _lv_gpu_nxp_pxp_interrupt_deinit(void);
|
||||
|
||||
/**
|
||||
* Start the PXP job and wait for task completion.
|
||||
* Start the PXP job.
|
||||
*/
|
||||
static void _lv_gpu_nxp_pxp_run(void);
|
||||
|
||||
/**
|
||||
* Wait for PXP completion.
|
||||
*/
|
||||
static void _lv_gpu_nxp_pxp_wait(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
static SemaphoreHandle_t s_pxpIdle;
|
||||
#else
|
||||
static volatile bool s_pxpIdle;
|
||||
static SemaphoreHandle_t s_pxpIdleSem;
|
||||
#endif
|
||||
static volatile bool s_pxpIdle;
|
||||
|
||||
static lv_nxp_pxp_cfg_t pxp_default_cfg = {
|
||||
.pxp_interrupt_init = _lv_gpu_nxp_pxp_interrupt_init,
|
||||
.pxp_interrupt_deinit = _lv_gpu_nxp_pxp_interrupt_deinit,
|
||||
.pxp_run = _lv_gpu_nxp_pxp_run
|
||||
.pxp_run = _lv_gpu_nxp_pxp_run,
|
||||
.pxp_wait = _lv_gpu_nxp_pxp_wait,
|
||||
};
|
||||
|
||||
/**********************
|
||||
@@ -102,7 +107,7 @@ void PXP_IRQHandler(void)
|
||||
if(kPXP_CompleteFlag & PXP_GetStatusFlags(LV_GPU_NXP_PXP_ID)) {
|
||||
PXP_ClearStatusFlags(LV_GPU_NXP_PXP_ID, kPXP_CompleteFlag);
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
xSemaphoreGiveFromISR(s_pxpIdle, &taskAwake);
|
||||
xSemaphoreGiveFromISR(s_pxpIdleSem, &taskAwake);
|
||||
portYIELD_FROM_ISR(taskAwake);
|
||||
#else
|
||||
s_pxpIdle = true;
|
||||
@@ -122,14 +127,13 @@ lv_nxp_pxp_cfg_t * lv_gpu_nxp_pxp_get_cfg(void)
|
||||
static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void)
|
||||
{
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
s_pxpIdle = xSemaphoreCreateBinary();
|
||||
if(s_pxpIdle == NULL)
|
||||
s_pxpIdleSem = xSemaphoreCreateBinary();
|
||||
if(s_pxpIdleSem == NULL)
|
||||
return LV_RES_INV;
|
||||
|
||||
NVIC_SetPriority(LV_GPU_NXP_PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1);
|
||||
#else
|
||||
s_pxpIdle = true;
|
||||
#endif
|
||||
s_pxpIdle = true;
|
||||
|
||||
NVIC_EnableIRQ(LV_GPU_NXP_PXP_IRQ_ID);
|
||||
|
||||
@@ -140,21 +144,33 @@ static void _lv_gpu_nxp_pxp_interrupt_deinit(void)
|
||||
{
|
||||
NVIC_DisableIRQ(LV_GPU_NXP_PXP_IRQ_ID);
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
vSemaphoreDelete(s_pxpIdle);
|
||||
vSemaphoreDelete(s_pxpIdleSem);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to start PXP job.
|
||||
*/
|
||||
static void _lv_gpu_nxp_pxp_run(void)
|
||||
{
|
||||
#if !defined(SDK_OS_FREE_RTOS)
|
||||
s_pxpIdle = false;
|
||||
#endif
|
||||
|
||||
PXP_EnableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable);
|
||||
PXP_Start(LV_GPU_NXP_PXP_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to wait for PXP completion.
|
||||
*/
|
||||
static void _lv_gpu_nxp_pxp_wait(void)
|
||||
{
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
PXP_COND_STOP(!xSemaphoreTake(s_pxpIdle, portMAX_DELAY), "xSemaphoreTake failed.");
|
||||
/* Return if PXP was never started, otherwise the semaphore will lock forever. */
|
||||
if(s_pxpIdle == true)
|
||||
return;
|
||||
|
||||
if(xSemaphoreTake(s_pxpIdleSem, portMAX_DELAY) == pdTRUE)
|
||||
s_pxpIdle = true;
|
||||
#else
|
||||
while(s_pxpIdle == false) {
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
CSRCS += lv_draw_vglite.c
|
||||
CSRCS += lv_draw_vglite_arc.c
|
||||
CSRCS += lv_draw_vglite_blend.c
|
||||
CSRCS += lv_draw_vglite_line.c
|
||||
CSRCS += lv_draw_vglite_rect.c
|
||||
CSRCS += lv_gpu_nxp_vglite.c
|
||||
CSRCS += lv_vglite_buf.c
|
||||
CSRCS += lv_vglite_utils.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite
|
||||
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp/vglite
|
||||
|
||||
557
src/draw/nxp/vglite/lv_draw_vglite.c
Normal file
557
src/draw/nxp/vglite/lv_draw_vglite.c
Normal file
@@ -0,0 +1,557 @@
|
||||
/**
|
||||
* @file lv_draw_vglite.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include <math.h>
|
||||
#include "lv_draw_vglite_blend.h"
|
||||
#include "lv_draw_vglite_line.h"
|
||||
#include "lv_draw_vglite_rect.h"
|
||||
#include "lv_draw_vglite_arc.h"
|
||||
#include "lv_vglite_buf.h"
|
||||
|
||||
#if LV_COLOR_DEPTH != 32
|
||||
#include "../../../core/lv_refr.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* Minimum area (in pixels) for VG-Lite blit/fill processing. */
|
||||
#ifndef LV_GPU_NXP_VG_LITE_SIZE_LIMIT
|
||||
#define LV_GPU_NXP_VG_LITE_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void lv_draw_vglite_init_buf(lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
static void lv_draw_vglite_wait_for_finish(lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
static void lv_draw_vglite_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf);
|
||||
|
||||
static void lv_draw_vglite_buffer_copy(lv_draw_ctx_t * draw_ctx,
|
||||
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
|
||||
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
|
||||
|
||||
static void lv_draw_vglite_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
|
||||
|
||||
static void lv_draw_vglite_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1,
|
||||
const lv_point_t * point2);
|
||||
|
||||
static void lv_draw_vglite_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
static lv_res_t lv_draw_vglite_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
static lv_res_t lv_draw_vglite_border(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
static lv_res_t lv_draw_vglite_outline(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
static void lv_draw_vglite_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
||||
uint16_t radius, uint16_t start_angle, uint16_t end_angle);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_draw_sw_init_ctx(drv, draw_ctx);
|
||||
|
||||
lv_draw_vglite_ctx_t * vglite_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx;
|
||||
vglite_draw_ctx->base_draw.init_buf = lv_draw_vglite_init_buf;
|
||||
vglite_draw_ctx->base_draw.draw_line = lv_draw_vglite_line;
|
||||
vglite_draw_ctx->base_draw.draw_arc = lv_draw_vglite_arc;
|
||||
vglite_draw_ctx->base_draw.draw_rect = lv_draw_vglite_rect;
|
||||
vglite_draw_ctx->base_draw.draw_img_decoded = lv_draw_vglite_img_decoded;
|
||||
vglite_draw_ctx->blend = lv_draw_vglite_blend;
|
||||
vglite_draw_ctx->base_draw.wait_for_finish = lv_draw_vglite_wait_for_finish;
|
||||
vglite_draw_ctx->base_draw.buffer_copy = lv_draw_vglite_buffer_copy;
|
||||
}
|
||||
|
||||
void lv_draw_vglite_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_draw_sw_deinit_ctx(drv, draw_ctx);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* During rendering, LVGL might initializes new draw_ctxs and start drawing into
|
||||
* a separate buffer (called layer). If the content to be rendered has "holes",
|
||||
* e.g. rounded corner, LVGL temporarily sets the disp_drv.screen_transp flag.
|
||||
* It means the renderers should draw into an ARGB buffer.
|
||||
* With 32 bit color depth it's not a big problem but with 16 bit color depth
|
||||
* the target pixel format is ARGB8565 which is not supported by the GPU.
|
||||
* In this case, the VG-Lite callbacks should fallback to SW rendering.
|
||||
*/
|
||||
static inline bool need_argb8565_support()
|
||||
{
|
||||
#if LV_COLOR_DEPTH != 32
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
if(disp->driver->screen_transp == 1)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void lv_draw_vglite_init_buf(lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_gpu_nxp_vglite_init_buf(draw_ctx->buf, draw_ctx->buf_area, lv_area_get_width(draw_ctx->buf_area));
|
||||
}
|
||||
|
||||
static void lv_draw_vglite_wait_for_finish(lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
vg_lite_finish();
|
||||
|
||||
lv_draw_sw_wait_for_finish(draw_ctx);
|
||||
}
|
||||
|
||||
static void lv_draw_vglite_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
if(need_argb8565_support()) {
|
||||
lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t blend_area;
|
||||
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
bool done = false;
|
||||
/*Fill/Blend only non masked, normal blended*/
|
||||
if(dsc->mask_buf == NULL && dsc->blend_mode == LV_BLEND_MODE_NORMAL &&
|
||||
lv_area_get_size(&blend_area) >= LV_GPU_NXP_VG_LITE_SIZE_LIMIT) {
|
||||
const lv_color_t * src_buf = dsc->src_buf;
|
||||
|
||||
if(src_buf == NULL) {
|
||||
done = (lv_gpu_nxp_vglite_fill(&blend_area, dsc->color, dsc->opa) == LV_RES_OK);
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite fill failed. Fallback.");
|
||||
}
|
||||
else {
|
||||
lv_area_t src_area;
|
||||
src_area.x1 = blend_area.x1 - (dsc->blend_area->x1 - draw_ctx->buf_area->x1);
|
||||
src_area.y1 = blend_area.y1 - (dsc->blend_area->y1 - draw_ctx->buf_area->y1);
|
||||
src_area.x2 = src_area.x1 + lv_area_get_width(dsc->blend_area) - 1;
|
||||
src_area.y2 = src_area.y1 + lv_area_get_height(dsc->blend_area) - 1;
|
||||
lv_coord_t src_stride = lv_area_get_width(dsc->blend_area);
|
||||
|
||||
#if VG_LITE_BLIT_SPLIT_ENABLED
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
|
||||
|
||||
done = (lv_gpu_nxp_vglite_blit_split(dest_buf, &blend_area, dest_stride,
|
||||
src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
|
||||
#else
|
||||
done = (lv_gpu_nxp_vglite_blit(&blend_area, src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
|
||||
#endif
|
||||
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite blit failed. Fallback.");
|
||||
}
|
||||
}
|
||||
|
||||
if(!done)
|
||||
lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||
}
|
||||
|
||||
static void lv_draw_vglite_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t cf)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
if(need_argb8565_support()) {
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
|
||||
return;
|
||||
}
|
||||
|
||||
const lv_color_t * src_buf = (const lv_color_t *)map_p;
|
||||
if(!src_buf) {
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t rel_coords;
|
||||
lv_area_copy(&rel_coords, coords);
|
||||
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
|
||||
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t blend_area;
|
||||
bool has_transform = dsc->angle != 0 || dsc->zoom != LV_IMG_ZOOM_NONE;
|
||||
|
||||
if(has_transform)
|
||||
lv_area_copy(&blend_area, &rel_coords);
|
||||
else if(!_lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
bool has_mask = lv_draw_mask_is_any(&blend_area);
|
||||
bool has_recolor = (dsc->recolor_opa != LV_OPA_TRANSP);
|
||||
|
||||
bool done = false;
|
||||
if(!has_mask && !has_recolor && !lv_img_cf_is_chroma_keyed(cf) &&
|
||||
lv_area_get_size(&blend_area) >= LV_GPU_NXP_VG_LITE_SIZE_LIMIT
|
||||
#if LV_COLOR_DEPTH != 32
|
||||
&& !lv_img_cf_has_alpha(cf)
|
||||
#endif
|
||||
) {
|
||||
lv_area_t src_area;
|
||||
src_area.x1 = blend_area.x1 - (coords->x1 - draw_ctx->buf_area->x1);
|
||||
src_area.y1 = blend_area.y1 - (coords->y1 - draw_ctx->buf_area->y1);
|
||||
src_area.x2 = src_area.x1 + lv_area_get_width(coords) - 1;
|
||||
src_area.y2 = src_area.y1 + lv_area_get_height(coords) - 1;
|
||||
lv_coord_t src_stride = lv_area_get_width(coords);
|
||||
|
||||
#if VG_LITE_BLIT_SPLIT_ENABLED
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
|
||||
|
||||
if(has_transform)
|
||||
/* VG-Lite blit split with transformation is not supported! */
|
||||
done = false;
|
||||
else
|
||||
done = (lv_gpu_nxp_vglite_blit_split(dest_buf, &blend_area, dest_stride,
|
||||
src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
|
||||
#else
|
||||
if(has_transform)
|
||||
done = (lv_gpu_nxp_vglite_blit_transform(&blend_area, &rel_clip_area,
|
||||
src_buf, &src_area, src_stride, dsc) == LV_RES_OK);
|
||||
else
|
||||
done = (lv_gpu_nxp_vglite_blit(&blend_area, src_buf, &src_area, src_stride, dsc->opa) == LV_RES_OK);
|
||||
#endif
|
||||
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite blit %sfailed. Fallback.", has_transform ? "transform " : "");
|
||||
}
|
||||
|
||||
if(!done)
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, cf);
|
||||
}
|
||||
|
||||
static void lv_draw_vglite_buffer_copy(lv_draw_ctx_t * draw_ctx,
|
||||
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
|
||||
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area)
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
if(lv_area_get_size(dest_area) >= LV_GPU_NXP_VG_LITE_SIZE_LIMIT) {
|
||||
done = lv_gpu_nxp_vglite_buffer_copy(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride);
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite buffer copy failed. Fallback.");
|
||||
}
|
||||
|
||||
if(!done)
|
||||
lv_draw_sw_buffer_copy(draw_ctx, dest_buf, dest_stride, dest_area, src_buf, src_stride, src_area);
|
||||
}
|
||||
|
||||
static void lv_draw_vglite_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1,
|
||||
const lv_point_t * point2)
|
||||
{
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
if(point1->x == point2->x && point1->y == point2->y)
|
||||
return;
|
||||
|
||||
if(need_argb8565_support()) {
|
||||
lv_draw_sw_line(draw_ctx, dsc, point1, point2);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
rel_clip_area.x1 = LV_MIN(point1->x, point2->x) - dsc->width / 2;
|
||||
rel_clip_area.x2 = LV_MAX(point1->x, point2->x) + dsc->width / 2;
|
||||
rel_clip_area.y1 = LV_MIN(point1->y, point2->y) - dsc->width / 2;
|
||||
rel_clip_area.y2 = LV_MAX(point1->y, point2->y) + dsc->width / 2;
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!_lv_area_intersect(&clipped_coords, &rel_clip_area, draw_ctx->clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_point_t rel_point1 = { point1->x - draw_ctx->buf_area->x1, point1->y - draw_ctx->buf_area->y1 };
|
||||
lv_point_t rel_point2 = { point2->x - draw_ctx->buf_area->x1, point2->y - draw_ctx->buf_area->y1 };
|
||||
|
||||
bool done = false;
|
||||
bool has_mask = lv_draw_mask_is_any(&rel_clip_area);
|
||||
|
||||
if(!has_mask) {
|
||||
done = (lv_gpu_nxp_vglite_draw_line(&rel_point1, &rel_point2, &rel_clip_area, dsc) == LV_RES_OK);
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite draw line failed. Fallback.");
|
||||
}
|
||||
|
||||
if(!done)
|
||||
lv_draw_sw_line(draw_ctx, dsc, point1, point2);
|
||||
}
|
||||
|
||||
static void lv_draw_vglite_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(need_argb8565_support()) {
|
||||
lv_draw_sw_rect(draw_ctx, dsc, coords);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_rect_dsc_t vglite_dsc;
|
||||
|
||||
lv_memcpy(&vglite_dsc, dsc, sizeof(vglite_dsc));
|
||||
vglite_dsc.bg_opa = 0;
|
||||
vglite_dsc.bg_img_opa = 0;
|
||||
vglite_dsc.border_opa = 0;
|
||||
vglite_dsc.outline_opa = 0;
|
||||
#if LV_DRAW_COMPLEX
|
||||
/* Draw the shadow with CPU */
|
||||
lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords);
|
||||
vglite_dsc.shadow_opa = 0;
|
||||
#endif /*LV_DRAW_COMPLEX*/
|
||||
|
||||
/* Draw the background */
|
||||
vglite_dsc.bg_opa = dsc->bg_opa;
|
||||
if(lv_draw_vglite_bg(draw_ctx, &vglite_dsc, coords) != LV_RES_OK)
|
||||
lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords);
|
||||
vglite_dsc.bg_opa = 0;
|
||||
|
||||
/* Draw the background image
|
||||
* It will be done once draw_ctx->draw_img_decoded()
|
||||
* callback gets called from lv_draw_sw_rect().
|
||||
*/
|
||||
vglite_dsc.bg_img_opa = dsc->bg_img_opa;
|
||||
lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords);
|
||||
vglite_dsc.bg_img_opa = 0;
|
||||
|
||||
/* Draw the border */
|
||||
vglite_dsc.border_opa = dsc->border_opa;
|
||||
if(lv_draw_vglite_border(draw_ctx, &vglite_dsc, coords) != LV_RES_OK)
|
||||
lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords);
|
||||
vglite_dsc.border_opa = 0;
|
||||
|
||||
/* Draw the outline */
|
||||
vglite_dsc.outline_opa = dsc->outline_opa;
|
||||
if(lv_draw_vglite_outline(draw_ctx, &vglite_dsc, coords) != LV_RES_OK)
|
||||
lv_draw_sw_rect(draw_ctx, &vglite_dsc, coords);
|
||||
}
|
||||
|
||||
static lv_res_t lv_draw_vglite_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->bg_opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return LV_RES_INV;
|
||||
|
||||
lv_area_t rel_coords;
|
||||
lv_area_copy(&rel_coords, coords);
|
||||
|
||||
/*If the border fully covers make the bg area 1px smaller to avoid artifacts on the corners*/
|
||||
if(dsc->border_width > 1 && dsc->border_opa >= (lv_opa_t)LV_OPA_MAX && dsc->radius != 0) {
|
||||
rel_coords.x1 += (dsc->border_side & LV_BORDER_SIDE_LEFT) ? 1 : 0;
|
||||
rel_coords.y1 += (dsc->border_side & LV_BORDER_SIDE_TOP) ? 1 : 0;
|
||||
rel_coords.x2 -= (dsc->border_side & LV_BORDER_SIDE_RIGHT) ? 1 : 0;
|
||||
rel_coords.y2 -= (dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? 1 : 0;
|
||||
}
|
||||
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
|
||||
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!_lv_area_intersect(&clipped_coords, &rel_coords, &rel_clip_area))
|
||||
return LV_RES_OK; /*Fully clipped, nothing to do*/
|
||||
|
||||
bool has_mask = lv_draw_mask_is_any(&rel_coords);
|
||||
lv_grad_dir_t grad_dir = dsc->bg_grad.dir;
|
||||
lv_color_t bg_color = (grad_dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE) ?
|
||||
dsc->bg_color : dsc->bg_grad.stops[0].color;
|
||||
if(bg_color.full == dsc->bg_grad.stops[1].color.full)
|
||||
grad_dir = LV_GRAD_DIR_NONE;
|
||||
|
||||
/*
|
||||
* Most simple case: just a plain rectangle (no mask, no radius, no gradient)
|
||||
* shall be handled by draw_ctx->blend().
|
||||
*
|
||||
* Complex case: gradient or radius but no mask.
|
||||
*/
|
||||
if(!has_mask && ((dsc->radius != 0) || (grad_dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE))) {
|
||||
lv_res_t res = lv_gpu_nxp_vglite_draw_bg(&rel_coords, &rel_clip_area, dsc);
|
||||
if(res != LV_RES_OK)
|
||||
VG_LITE_LOG_TRACE("VG-Lite draw bg failed. Fallback.");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
static lv_res_t lv_draw_vglite_border(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->border_opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return LV_RES_INV;
|
||||
if(dsc->border_width == 0)
|
||||
return LV_RES_INV;
|
||||
if(dsc->border_post)
|
||||
return LV_RES_INV;
|
||||
if(dsc->border_side != (lv_border_side_t)LV_BORDER_SIDE_FULL)
|
||||
return LV_RES_INV;
|
||||
|
||||
lv_area_t rel_coords;
|
||||
lv_coord_t border_width = dsc->border_width;
|
||||
|
||||
/* Move border inwards to align with software rendered border */
|
||||
rel_coords.x1 = coords->x1 + ceil(border_width / 2.0f);
|
||||
rel_coords.x2 = coords->x2 - floor(border_width / 2.0f);
|
||||
rel_coords.y1 = coords->y1 + ceil(border_width / 2.0f);
|
||||
rel_coords.y2 = coords->y2 - floor(border_width / 2.0f);
|
||||
|
||||
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
|
||||
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!_lv_area_intersect(&clipped_coords, &rel_coords, &rel_clip_area))
|
||||
return LV_RES_OK; /*Fully clipped, nothing to do*/
|
||||
|
||||
lv_res_t res = lv_gpu_nxp_vglite_draw_border_generic(&rel_coords, &rel_clip_area, dsc, true);
|
||||
if(res != LV_RES_OK)
|
||||
VG_LITE_LOG_TRACE("VG-Lite draw border failed. Fallback.");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static lv_res_t lv_draw_vglite_outline(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->outline_opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return LV_RES_INV;
|
||||
if(dsc->outline_width == 0)
|
||||
return LV_RES_INV;
|
||||
|
||||
/* Move outline outwards to align with software rendered outline */
|
||||
lv_coord_t outline_pad = dsc->outline_pad - 1;
|
||||
lv_area_t rel_coords;
|
||||
rel_coords.x1 = coords->x1 - outline_pad - floor(dsc->outline_width / 2.0f);
|
||||
rel_coords.x2 = coords->x2 + outline_pad + ceil(dsc->outline_width / 2.0f);
|
||||
rel_coords.y1 = coords->y1 - outline_pad - floor(dsc->outline_width / 2.0f);
|
||||
rel_coords.y2 = coords->y2 + outline_pad + ceil(dsc->outline_width / 2.0f);
|
||||
|
||||
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
|
||||
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!_lv_area_intersect(&clipped_coords, &rel_coords, &rel_clip_area))
|
||||
return LV_RES_OK; /*Fully clipped, nothing to do*/
|
||||
|
||||
lv_res_t res = lv_gpu_nxp_vglite_draw_border_generic(&rel_coords, &rel_clip_area, dsc, false);
|
||||
if(res != LV_RES_OK)
|
||||
VG_LITE_LOG_TRACE("VG-Lite draw outline failed. Fallback.");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void lv_draw_vglite_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
||||
uint16_t radius, uint16_t start_angle, uint16_t end_angle)
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
#if LV_DRAW_COMPLEX
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(start_angle == end_angle)
|
||||
return;
|
||||
|
||||
if(need_argb8565_support()) {
|
||||
lv_draw_sw_arc(draw_ctx, dsc, center, radius, start_angle, end_angle);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_point_t rel_center = {center->x - draw_ctx->buf_area->x1, center->y - draw_ctx->buf_area->y1};
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
lv_area_copy(&rel_clip_area, draw_ctx->clip_area);
|
||||
lv_area_move(&rel_clip_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
bool has_mask = lv_draw_mask_is_any(&rel_clip_area);
|
||||
|
||||
if(!has_mask) {
|
||||
done = (lv_gpu_nxp_vglite_draw_arc(&rel_center, (int32_t)radius, (int32_t)start_angle, (int32_t)end_angle,
|
||||
&rel_clip_area, dsc) == LV_RES_OK);
|
||||
if(!done)
|
||||
VG_LITE_LOG_TRACE("VG-Lite draw arc failed. Fallback.");
|
||||
}
|
||||
|
||||
#endif/*LV_DRAW_COMPLEX*/
|
||||
|
||||
if(!done)
|
||||
lv_draw_sw_arc(draw_ctx, dsc, center, radius, start_angle, end_angle);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
72
src/draw/nxp/vglite/lv_draw_vglite.h
Normal file
72
src/draw/nxp/vglite/lv_draw_vglite.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file lv_draw_vglite.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_VGLITE_H
|
||||
#define LV_DRAW_VGLITE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "../../sw/lv_draw_sw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef lv_draw_sw_ctx_t lv_draw_vglite_ctx_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
void lv_draw_vglite_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_VGLITE_H*/
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2021, 2022 NXP
|
||||
* Copyright 2021-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -34,7 +34,8 @@
|
||||
#include "lv_draw_vglite_arc.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "math.h"
|
||||
#include "lv_vglite_buf.h"
|
||||
#include <math.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -88,7 +89,7 @@ typedef struct _cubic_cont_pt {
|
||||
|
||||
static void rotate_point(int32_t angle, int32_t * x, int32_t * y);
|
||||
static void add_arc_path(int32_t * arc_path, int * pidx, int32_t radius,
|
||||
int32_t start_angle, int32_t end_angle, lv_point_t center, bool cw);
|
||||
int32_t start_angle, int32_t end_angle, const lv_point_t * center, bool cw);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -102,31 +103,20 @@ static void add_arc_path(int32_t * arc_path, int * pidx, int32_t radius,
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
||||
int32_t radius, int32_t start_angle, int32_t end_angle)
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_arc(const lv_point_t * center, int32_t radius, int32_t start_angle, int32_t end_angle,
|
||||
const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc)
|
||||
{
|
||||
|
||||
vg_lite_buffer_t vgbuf;
|
||||
vg_lite_error_t err = VG_LITE_SUCCESS;
|
||||
lv_color32_t col32 = {.full = lv_color_to32(dsc->color)}; /*Convert color to RGBA8888*/
|
||||
lv_coord_t dest_width = lv_area_get_width(draw_ctx->buf_area);
|
||||
lv_coord_t dest_height = lv_area_get_height(draw_ctx->buf_area);
|
||||
vg_lite_path_t path;
|
||||
vg_lite_color_t vgcol; /* vglite takes ABGR */
|
||||
vg_lite_matrix_t matrix;
|
||||
lv_opa_t opa = dsc->opa;
|
||||
bool donut = ((end_angle - start_angle) % 360 == 0) ? true : false;
|
||||
lv_point_t clip_center = {center->x - draw_ctx->buf_area->x1, center->y - draw_ctx->buf_area->y1};
|
||||
vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf();
|
||||
|
||||
/* path: max size = 16 cubic bezier (7 words each) */
|
||||
int32_t arc_path[16 * 7];
|
||||
lv_memset_00(arc_path, sizeof(arc_path));
|
||||
|
||||
/*** Init destination buffer ***/
|
||||
if(lv_vglite_init_buf(&vgbuf, (uint32_t)dest_width, (uint32_t)dest_height, (uint32_t)dest_width * sizeof(lv_color_t),
|
||||
(const lv_color_t *)draw_ctx->buf, false) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Init buffer failed.");
|
||||
|
||||
/*** Init path ***/
|
||||
lv_coord_t width = dsc->width; /* inner arc radius = outer arc radius - width */
|
||||
if(width > (lv_coord_t)radius)
|
||||
@@ -140,11 +130,11 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_
|
||||
cp_y = 0;
|
||||
rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_MOVE;
|
||||
arc_path[pidx++] = clip_center.x + cp_x;
|
||||
arc_path[pidx++] = clip_center.y + cp_y;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
|
||||
/* draw 1-5 outer quarters */
|
||||
add_arc_path(arc_path, &pidx, radius, start_angle, end_angle, clip_center, true);
|
||||
add_arc_path(arc_path, &pidx, radius, start_angle, end_angle, center, true);
|
||||
|
||||
if(donut) {
|
||||
/* close outer circle */
|
||||
@@ -152,24 +142,24 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_
|
||||
cp_y = 0;
|
||||
rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_LINE;
|
||||
arc_path[pidx++] = clip_center.x + cp_x;
|
||||
arc_path[pidx++] = clip_center.y + cp_y;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
/* start inner circle */
|
||||
cp_x = radius - width;
|
||||
cp_y = 0;
|
||||
rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_MOVE;
|
||||
arc_path[pidx++] = clip_center.x + cp_x;
|
||||
arc_path[pidx++] = clip_center.y + cp_y;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
|
||||
}
|
||||
else if(dsc->rounded != 0U) { /* 1st rounded arc ending */
|
||||
cp_x = radius - width / 2;
|
||||
cp_y = 0;
|
||||
rotate_point(end_angle, &cp_x, &cp_y);
|
||||
lv_point_t round_center = {clip_center.x + cp_x, clip_center.y + cp_y};
|
||||
lv_point_t round_center = {center->x + cp_x, center->y + cp_y};
|
||||
add_arc_path(arc_path, &pidx, width / 2, end_angle, (end_angle + 180),
|
||||
round_center, true);
|
||||
&round_center, true);
|
||||
|
||||
}
|
||||
else { /* 1st flat ending */
|
||||
@@ -177,12 +167,12 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_
|
||||
cp_y = 0;
|
||||
rotate_point(end_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_LINE;
|
||||
arc_path[pidx++] = clip_center.x + cp_x;
|
||||
arc_path[pidx++] = clip_center.y + cp_y;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
}
|
||||
|
||||
/* draw 1-5 inner quarters */
|
||||
add_arc_path(arc_path, &pidx, radius - width, start_angle, end_angle, clip_center, false);
|
||||
add_arc_path(arc_path, &pidx, radius - width, start_angle, end_angle, center, false);
|
||||
|
||||
/* last control point of curve */
|
||||
if(donut) { /* close the loop */
|
||||
@@ -190,17 +180,17 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_
|
||||
cp_y = 0;
|
||||
rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_LINE;
|
||||
arc_path[pidx++] = clip_center.x + cp_x;
|
||||
arc_path[pidx++] = clip_center.y + cp_y;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
|
||||
}
|
||||
else if(dsc->rounded != 0U) { /* 2nd rounded arc ending */
|
||||
cp_x = radius - width / 2;
|
||||
cp_y = 0;
|
||||
rotate_point(start_angle, &cp_x, &cp_y);
|
||||
lv_point_t round_center = {clip_center.x + cp_x, clip_center.y + cp_y};
|
||||
lv_point_t round_center = {center->x + cp_x, center->y + cp_y};
|
||||
add_arc_path(arc_path, &pidx, width / 2, (start_angle + 180), (start_angle + 360),
|
||||
round_center, true);
|
||||
&round_center, true);
|
||||
|
||||
}
|
||||
else { /* 2nd flat ending */
|
||||
@@ -208,46 +198,34 @@ lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_
|
||||
cp_y = 0;
|
||||
rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_LINE;
|
||||
arc_path[pidx++] = clip_center.x + cp_x;
|
||||
arc_path[pidx++] = clip_center.y + cp_y;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
}
|
||||
|
||||
arc_path[pidx++] = VLC_OP_END;
|
||||
|
||||
err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, (uint32_t)pidx * sizeof(int32_t), arc_path,
|
||||
(vg_lite_float_t) draw_ctx->clip_area->x1, (vg_lite_float_t) draw_ctx->clip_area->y1,
|
||||
((vg_lite_float_t) draw_ctx->clip_area->x2) + 1.0f, ((vg_lite_float_t) draw_ctx->clip_area->y2) + 1.0f);
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Init path failed.");
|
||||
|
||||
/* set rotation angle */
|
||||
vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888;
|
||||
if(lv_vglite_premult_and_swizzle(&vgcol, col32, dsc->opa, color_format) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Premultiplication and swizzle failed.");
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
if(opa <= (lv_opa_t)LV_OPA_MAX) {
|
||||
/* Only pre-multiply color if hardware pre-multiplication is not present */
|
||||
if(!vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) {
|
||||
col32.ch.red = (uint8_t)(((uint16_t)col32.ch.red * opa) >> 8);
|
||||
col32.ch.green = (uint8_t)(((uint16_t)col32.ch.green * opa) >> 8);
|
||||
col32.ch.blue = (uint8_t)(((uint16_t)col32.ch.blue * opa) >> 8);
|
||||
}
|
||||
col32.ch.alpha = opa;
|
||||
}
|
||||
|
||||
#if LV_COLOR_DEPTH==16
|
||||
vgcol = col32.full;
|
||||
#else /*LV_COLOR_DEPTH==32*/
|
||||
vgcol = ((uint32_t)col32.ch.alpha << 24) | ((uint32_t)col32.ch.blue << 16) | ((uint32_t)col32.ch.green << 8) |
|
||||
(uint32_t)col32.ch.red;
|
||||
#endif
|
||||
|
||||
/*Clean & invalidate cache*/
|
||||
lv_vglite_invalidate_cache();
|
||||
lv_vglite_set_scissor(clip_area);
|
||||
|
||||
/*** Draw arc ***/
|
||||
err = vg_lite_draw(&vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol);
|
||||
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Draw arc failed.");
|
||||
|
||||
err = vg_lite_finish();
|
||||
VG_LITE_ERR_RETURN_INV(err, "Finish failed.");
|
||||
if(lv_vglite_run() != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Run failed.");
|
||||
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
err = vg_lite_clear_path(&path);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");
|
||||
@@ -564,50 +542,50 @@ static void get_arc_control_points(vg_arc * arc, bool start)
|
||||
* center: (in) the center of the circle in draw coordinates
|
||||
* cw: (in) true if arc is clockwise
|
||||
*/
|
||||
static void add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, lv_point_t center, bool cw)
|
||||
static void add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, const lv_point_t * center, bool cw)
|
||||
{
|
||||
/* assumes first control point already in array arc_path[] */
|
||||
int idx = *pidx;
|
||||
if(cw) {
|
||||
#if BEZIER_DBG_CONTROL_POINTS
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p1x + center.x;
|
||||
arc_path[idx++] = q_arc->p1y + center.y;
|
||||
arc_path[idx++] = q_arc->p1x + center->x;
|
||||
arc_path[idx++] = q_arc->p1y + center->y;
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p2x + center.x;
|
||||
arc_path[idx++] = q_arc->p2y + center.y;
|
||||
arc_path[idx++] = q_arc->p2x + center->x;
|
||||
arc_path[idx++] = q_arc->p2y + center->y;
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p3x + center.x;
|
||||
arc_path[idx++] = q_arc->p3y + center.y;
|
||||
arc_path[idx++] = q_arc->p3x + center->x;
|
||||
arc_path[idx++] = q_arc->p3y + center->y;
|
||||
#else
|
||||
arc_path[idx++] = VLC_OP_CUBIC;
|
||||
arc_path[idx++] = q_arc->p1x + center.x;
|
||||
arc_path[idx++] = q_arc->p1y + center.y;
|
||||
arc_path[idx++] = q_arc->p2x + center.x;
|
||||
arc_path[idx++] = q_arc->p2y + center.y;
|
||||
arc_path[idx++] = q_arc->p3x + center.x;
|
||||
arc_path[idx++] = q_arc->p3y + center.y;
|
||||
arc_path[idx++] = q_arc->p1x + center->x;
|
||||
arc_path[idx++] = q_arc->p1y + center->y;
|
||||
arc_path[idx++] = q_arc->p2x + center->x;
|
||||
arc_path[idx++] = q_arc->p2y + center->y;
|
||||
arc_path[idx++] = q_arc->p3x + center->x;
|
||||
arc_path[idx++] = q_arc->p3y + center->y;
|
||||
#endif
|
||||
}
|
||||
else { /* reverse points order when counter-clockwise */
|
||||
#if BEZIER_DBG_CONTROL_POINTS
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p2x + center.x;
|
||||
arc_path[idx++] = q_arc->p2y + center.y;
|
||||
arc_path[idx++] = q_arc->p2x + center->x;
|
||||
arc_path[idx++] = q_arc->p2y + center->y;
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p1x + center.x;
|
||||
arc_path[idx++] = q_arc->p1y + center.y;
|
||||
arc_path[idx++] = q_arc->p1x + center->x;
|
||||
arc_path[idx++] = q_arc->p1y + center->y;
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p0x + center.x;
|
||||
arc_path[idx++] = q_arc->p0y + center.y;
|
||||
arc_path[idx++] = q_arc->p0x + center->x;
|
||||
arc_path[idx++] = q_arc->p0y + center->y;
|
||||
#else
|
||||
arc_path[idx++] = VLC_OP_CUBIC;
|
||||
arc_path[idx++] = q_arc->p2x + center.x;
|
||||
arc_path[idx++] = q_arc->p2y + center.y;
|
||||
arc_path[idx++] = q_arc->p1x + center.x;
|
||||
arc_path[idx++] = q_arc->p1y + center.y;
|
||||
arc_path[idx++] = q_arc->p0x + center.x;
|
||||
arc_path[idx++] = q_arc->p0y + center.y;
|
||||
arc_path[idx++] = q_arc->p2x + center->x;
|
||||
arc_path[idx++] = q_arc->p2y + center->y;
|
||||
arc_path[idx++] = q_arc->p1x + center->x;
|
||||
arc_path[idx++] = q_arc->p1y + center->y;
|
||||
arc_path[idx++] = q_arc->p0x + center->x;
|
||||
arc_path[idx++] = q_arc->p0y + center->y;
|
||||
#endif
|
||||
}
|
||||
/* update index i n path array*/
|
||||
@@ -615,7 +593,7 @@ static void add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, l
|
||||
}
|
||||
|
||||
static void add_arc_path(int32_t * arc_path, int * pidx, int32_t radius,
|
||||
int32_t start_angle, int32_t end_angle, lv_point_t center, bool cw)
|
||||
int32_t start_angle, int32_t end_angle, const lv_point_t * center, bool cw)
|
||||
{
|
||||
/* set number of arcs to draw */
|
||||
vg_arc q_arc;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2021, 2022 NXP
|
||||
* Copyright 2021-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -40,7 +40,7 @@ extern "C" {
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "lv_gpu_nxp_vglite.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -54,17 +54,21 @@ extern "C" {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/***
|
||||
/**
|
||||
* Draw arc shape with effects
|
||||
* @param draw_ctx drawing context
|
||||
* @param dsc the arc description structure (width, rounded ending, opacity)
|
||||
* @param center the coordinates of the arc center
|
||||
* @param radius the radius of external arc
|
||||
* @param start_angle the starting angle in degrees
|
||||
* @param end_angle the ending angle in degrees
|
||||
*
|
||||
* @param[in] center Arc center with relative coordinates
|
||||
* @param[in] radius Radius of external arc
|
||||
* @param[in] start_angle Starting angle in degrees
|
||||
* @param[in] end_angle Ending angle in degrees
|
||||
* @param[in] clip_area Clipping area with relative coordinates to dest buff
|
||||
* @param[in] dsc Arc description structure (width, rounded ending, opacity)
|
||||
*
|
||||
* @retval LV_RES_OK Draw completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
||||
int32_t radius, int32_t start_angle, int32_t end_angle);
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_arc(const lv_point_t * center, int32_t radius, int32_t start_angle, int32_t end_angle,
|
||||
const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020-2022 NXP
|
||||
* Copyright 2020-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -34,30 +34,24 @@
|
||||
#include "lv_draw_vglite_blend.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* Enable BLIT quality degradation workaround for RT595, recommended for screen's dimension > 352 pixels */
|
||||
#define RT595_BLIT_WRKRND_ENABLED 1
|
||||
/** Stride in px required by VG-Lite HW*/
|
||||
#define LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX 16U
|
||||
|
||||
/* Internal compound symbol */
|
||||
#if (defined(CPU_MIMXRT595SFFOB) || defined(CPU_MIMXRT595SFFOB_cm33) || \
|
||||
defined(CPU_MIMXRT595SFFOC) || defined(CPU_MIMXRT595SFFOC_cm33)) && \
|
||||
RT595_BLIT_WRKRND_ENABLED
|
||||
#define VG_LITE_BLIT_SPLIT_ENABLED 1
|
||||
#else
|
||||
#define VG_LITE_BLIT_SPLIT_ENABLED 0
|
||||
#if VG_LITE_BLIT_SPLIT_ENABLED
|
||||
/**
|
||||
* BLIT split threshold - BLITs with width or height higher than this value will be done
|
||||
* in multiple steps. Value must be 16-aligned. Don't change.
|
||||
*/
|
||||
#define LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR 352
|
||||
#endif
|
||||
|
||||
/**
|
||||
* BLIT split threshold - BLITs with width or height higher than this value will be done
|
||||
* in multiple steps. Value must be 16-aligned. Don't change.
|
||||
*/
|
||||
#define LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR 352
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -67,63 +61,85 @@
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - single direct BLIT.
|
||||
* Blit image, with optional opacity.
|
||||
*
|
||||
* @param[in] src_area Source area with relative coordinates of source buffer
|
||||
* @param[in] opa Opacity
|
||||
*
|
||||
* @param[in] blit Description of the transfer
|
||||
* @retval LV_RES_OK Transfer complete
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
static lv_res_t lv_vglite_blit(const lv_area_t * src_area, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Check source memory and stride alignment.
|
||||
*
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
*
|
||||
* @retval LV_RES_OK Alignment OK
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
static lv_res_t check_src_alignment(const lv_color_t * src_buf, lv_coord_t src_stride);
|
||||
|
||||
/**
|
||||
* Creates matrix that translates to origin of given destination area.
|
||||
*
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
*/
|
||||
static inline void lv_vglite_set_translation_matrix(const lv_area_t * dest_area);
|
||||
|
||||
/**
|
||||
* Creates matrix that translates to origin of given destination area with transformation (scale or rotate).
|
||||
*
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dsc Image descriptor
|
||||
*/
|
||||
static inline void lv_vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_img_dsc_t * dsc);
|
||||
|
||||
#if VG_LITE_BLIT_SPLIT_ENABLED
|
||||
/**
|
||||
* Move buffer pointer as close as possible to area, but with respect to alignment requirements. X-axis only.
|
||||
*
|
||||
* @param[in/out] area Area to be updated
|
||||
* @param[in/out] buf Pointer to be updated
|
||||
*/
|
||||
static void align_x(lv_area_t * area, lv_color_t ** buf);
|
||||
|
||||
/**
|
||||
* Move buffer pointer as close as possible to area, but with respect to alignment requirements. X-axis only.
|
||||
*
|
||||
* @param[in,out] area Area to be updated
|
||||
* @param[in,out] buf Pointer to be updated
|
||||
*/
|
||||
static void _align_x(lv_area_t * area, lv_color_t ** buf);
|
||||
/**
|
||||
* Move buffer pointer to the area start and update variables, Y-axis only.
|
||||
*
|
||||
* @param[in/out] area Area to be updated
|
||||
* @param[in/out] buf Pointer to be updated
|
||||
* @param[in] stride Buffer stride in pixels
|
||||
*/
|
||||
static void align_y(lv_area_t * area, lv_color_t ** buf, lv_coord_t stride);
|
||||
|
||||
/**
|
||||
* Move buffer pointer to the area start and update variables, Y-axis only.
|
||||
*
|
||||
* @param[in,out] area Area to be updated
|
||||
* @param[in,out] buf Pointer to be updated
|
||||
* @param[in] stridePx Buffer stride in pixels
|
||||
*/
|
||||
static void _align_y(lv_area_t * area, lv_color_t ** buf, uint32_t stridePx);
|
||||
|
||||
/**
|
||||
* Software BLIT as a fall-back scenario.
|
||||
*
|
||||
* @param[in] blit BLIT configuration
|
||||
*/
|
||||
static void _sw_blit(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
|
||||
/**
|
||||
* Verify BLIT structure - widths, stride, pointer alignment
|
||||
*
|
||||
* @param[in] blit BLIT configuration
|
||||
* @retval LV_RES_OK
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
static lv_res_t _lv_gpu_nxp_vglite_check_blit(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - split BLIT.
|
||||
*
|
||||
* @param[in] blit BLIT configuration
|
||||
* @retval LV_RES_OK Transfer complete
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
static lv_res_t _lv_gpu_nxp_vglite_blit_split(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
#endif
|
||||
/**
|
||||
* Blit image split in tiles, with optional opacity.
|
||||
*
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Source area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] opa Opacity
|
||||
*
|
||||
* @retval LV_RES_OK Transfer complete
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
static lv_res_t lv_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
|
||||
lv_opa_t opa);
|
||||
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static vg_lite_matrix_t vgmatrix;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@@ -132,98 +148,57 @@ static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * b
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height,
|
||||
const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa)
|
||||
lv_res_t lv_gpu_nxp_vglite_fill(const lv_area_t * dest_area, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
uint32_t area_size = lv_area_get_size(fill_area);
|
||||
lv_coord_t area_w = lv_area_get_width(fill_area);
|
||||
lv_coord_t area_h = lv_area_get_height(fill_area);
|
||||
|
||||
if(opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
if(area_size < LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT)
|
||||
VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", area_size, LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT);
|
||||
}
|
||||
else {
|
||||
if(area_size < LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT)
|
||||
VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", area_size, LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT);
|
||||
}
|
||||
|
||||
vg_lite_buffer_t vgbuf;
|
||||
vg_lite_rectangle_t rect;
|
||||
vg_lite_error_t err = VG_LITE_SUCCESS;
|
||||
lv_color32_t col32 = {.full = lv_color_to32(color)}; /*Convert color to RGBA8888*/
|
||||
vg_lite_color_t vgcol; /* vglite takes ABGR */
|
||||
vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf();
|
||||
|
||||
if(lv_vglite_init_buf(&vgbuf, (uint32_t)dest_width, (uint32_t)dest_height, (uint32_t)dest_width * sizeof(lv_color_t),
|
||||
(const lv_color_t *)dest_buf, false) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Init buffer failed.");
|
||||
vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888;
|
||||
if(lv_vglite_premult_and_swizzle(&vgcol, col32, opa, color_format) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Premultiplication and swizzle failed.");
|
||||
|
||||
if(opa >= (lv_opa_t)LV_OPA_MAX) { /*Opaque fill*/
|
||||
rect.x = fill_area->x1;
|
||||
rect.y = fill_area->y1;
|
||||
rect.width = area_w;
|
||||
rect.height = area_h;
|
||||
vg_lite_rectangle_t rect = {
|
||||
.x = dest_area->x1,
|
||||
.y = dest_area->y1,
|
||||
.width = lv_area_get_width(dest_area),
|
||||
.height = lv_area_get_height(dest_area)
|
||||
};
|
||||
|
||||
/*Clean & invalidate cache*/
|
||||
lv_vglite_invalidate_cache();
|
||||
|
||||
#if LV_COLOR_DEPTH==16
|
||||
vgcol = col32.full;
|
||||
#else /*LV_COLOR_DEPTH==32*/
|
||||
vgcol = ((uint32_t)col32.ch.alpha << 24) | ((uint32_t)col32.ch.blue << 16) | ((uint32_t)col32.ch.green << 8) |
|
||||
(uint32_t)col32.ch.red;
|
||||
#endif
|
||||
|
||||
err = vg_lite_clear(&vgbuf, &rect, vgcol);
|
||||
err = vg_lite_clear(vgbuf, &rect, vgcol);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Clear failed.");
|
||||
|
||||
err = vg_lite_finish();
|
||||
VG_LITE_ERR_RETURN_INV(err, "Finish failed.");
|
||||
if(lv_vglite_run() != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Run failed.");
|
||||
}
|
||||
else { /*fill with transparency*/
|
||||
|
||||
vg_lite_path_t path;
|
||||
int32_t path_data[] = { /*VG rectangular path*/
|
||||
VLC_OP_MOVE, fill_area->x1, fill_area->y1,
|
||||
VLC_OP_LINE, fill_area->x2 + 1, fill_area->y1,
|
||||
VLC_OP_LINE, fill_area->x2 + 1, fill_area->y2 + 1,
|
||||
VLC_OP_LINE, fill_area->x1, fill_area->y2 + 1,
|
||||
VLC_OP_LINE, fill_area->x1, fill_area->y1,
|
||||
VLC_OP_MOVE, dest_area->x1, dest_area->y1,
|
||||
VLC_OP_LINE, dest_area->x2 + 1, dest_area->y1,
|
||||
VLC_OP_LINE, dest_area->x2 + 1, dest_area->y2 + 1,
|
||||
VLC_OP_LINE, dest_area->x1, dest_area->y2 + 1,
|
||||
VLC_OP_LINE, dest_area->x1, dest_area->y1,
|
||||
VLC_OP_END
|
||||
};
|
||||
|
||||
err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_LOW, sizeof(path_data), path_data,
|
||||
(vg_lite_float_t) fill_area->x1, (vg_lite_float_t) fill_area->y1,
|
||||
((vg_lite_float_t) fill_area->x2) + 1.0f, ((vg_lite_float_t) fill_area->y2) + 1.0f);
|
||||
(vg_lite_float_t) dest_area->x1, (vg_lite_float_t) dest_area->y1,
|
||||
((vg_lite_float_t) dest_area->x2) + 1.0f, ((vg_lite_float_t) dest_area->y2) + 1.0f);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Init path failed.");
|
||||
|
||||
/* Only pre-multiply color if hardware pre-multiplication is not present */
|
||||
if(!vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) {
|
||||
col32.ch.red = (uint8_t)(((uint16_t)col32.ch.red * opa) >> 8);
|
||||
col32.ch.green = (uint8_t)(((uint16_t)col32.ch.green * opa) >> 8);
|
||||
col32.ch.blue = (uint8_t)(((uint16_t)col32.ch.blue * opa) >> 8);
|
||||
}
|
||||
col32.ch.alpha = opa;
|
||||
|
||||
#if LV_COLOR_DEPTH==16
|
||||
vgcol = col32.full;
|
||||
#else /*LV_COLOR_DEPTH==32*/
|
||||
vgcol = ((uint32_t)col32.ch.alpha << 24) | ((uint32_t)col32.ch.blue << 16) | ((uint32_t)col32.ch.green << 8) |
|
||||
(uint32_t)col32.ch.red;
|
||||
#endif
|
||||
|
||||
/*Clean & invalidate cache*/
|
||||
lv_vglite_invalidate_cache();
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
/*Draw rectangle*/
|
||||
err = vg_lite_draw(&vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol);
|
||||
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Draw rectangle failed.");
|
||||
|
||||
err = vg_lite_finish();
|
||||
VG_LITE_ERR_RETURN_INV(err, "Finish failed.");
|
||||
if(lv_vglite_run() != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Run failed.");
|
||||
|
||||
err = vg_lite_clear_path(&path);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");
|
||||
@@ -232,41 +207,128 @@ lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_blit(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
{
|
||||
uint32_t dest_size = lv_area_get_size(&blit->dst_area);
|
||||
|
||||
if(blit->opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
if(dest_size < LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT)
|
||||
VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT);
|
||||
}
|
||||
else {
|
||||
if(dest_size < LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT)
|
||||
VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT);
|
||||
}
|
||||
|
||||
#if VG_LITE_BLIT_SPLIT_ENABLED
|
||||
return _lv_gpu_nxp_vglite_blit_split(blit);
|
||||
#endif /* non RT595 */
|
||||
lv_res_t lv_gpu_nxp_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
/* Set src_vgbuf structure. */
|
||||
lv_vglite_set_src_buf(src_buf, src_area, src_stride);
|
||||
|
||||
/* Just pass down */
|
||||
return _lv_gpu_nxp_vglite_blit_single(blit);
|
||||
lv_color_t * orig_dest_buf = dest_buf;
|
||||
|
||||
lv_res_t rv = lv_vglite_blit_split(dest_buf, dest_area, dest_stride, src_buf, src_area, src_stride, opa);
|
||||
|
||||
/* Restore the original dest_vgbuf memory address. */
|
||||
lv_vglite_set_dest_buf_ptr(orig_dest_buf);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#else
|
||||
lv_res_t lv_gpu_nxp_vglite_blit(const lv_area_t * dest_area,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
if(check_src_alignment(src_buf, src_stride) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Check src alignment failed.");
|
||||
|
||||
/* Set src_vgbuf structure. */
|
||||
lv_vglite_set_src_buf(src_buf, src_area, src_stride);
|
||||
|
||||
/* Set scissor. */
|
||||
lv_vglite_set_scissor(dest_area);
|
||||
|
||||
/* Set vgmatrix. */
|
||||
lv_vglite_set_translation_matrix(dest_area);
|
||||
|
||||
/* Start blit. */
|
||||
lv_res_t rv = lv_vglite_blit(src_area, opa);
|
||||
|
||||
/* Disable scissor. */
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
lv_res_t lv_gpu_nxp_vglite_blit_transform(const lv_area_t * dest_area, const lv_area_t * clip_area,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc)
|
||||
{
|
||||
uint32_t dest_size = lv_area_get_size(&blit->dst_area);
|
||||
lv_res_t rv = LV_RES_INV;
|
||||
|
||||
if(blit->opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
if(dest_size < LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT)
|
||||
VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT);
|
||||
}
|
||||
else {
|
||||
if(dest_size < LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT)
|
||||
VG_LITE_RETURN_INV("Area size %d smaller than limit %d.", dest_size, LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT);
|
||||
if(check_src_alignment(src_buf, src_stride) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Check src alignment failed.");
|
||||
|
||||
/* Set src_vgbuf structure. */
|
||||
lv_vglite_set_src_buf(src_buf, src_area, src_stride);
|
||||
|
||||
/* Set scissor */
|
||||
lv_vglite_set_scissor(clip_area);
|
||||
|
||||
/* Set vgmatrix. */
|
||||
lv_vglite_set_transformation_matrix(dest_area, dsc);
|
||||
|
||||
/* Start blit. */
|
||||
rv = lv_vglite_blit(src_area, dsc->opa);
|
||||
|
||||
/* Disable scissor. */
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_buffer_copy(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride)
|
||||
{
|
||||
vg_lite_error_t err = VG_LITE_SUCCESS;
|
||||
|
||||
if(check_src_alignment(src_buf, src_stride) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Check src alignment failed.");
|
||||
|
||||
vg_lite_buffer_t src_vgbuf;
|
||||
/* Set src_vgbuf structure. */
|
||||
lv_vglite_set_buf(&src_vgbuf, src_buf, src_area, src_stride);
|
||||
|
||||
vg_lite_buffer_t dest_vgbuf;
|
||||
/* Set dest_vgbuf structure. */
|
||||
lv_vglite_set_buf(&dest_vgbuf, dest_buf, dest_area, dest_stride);
|
||||
|
||||
uint32_t rect[] = {
|
||||
(uint32_t)src_area->x1, /* start x */
|
||||
(uint32_t)src_area->y1, /* start y */
|
||||
(uint32_t)lv_area_get_width(src_area), /* width */
|
||||
(uint32_t)lv_area_get_height(src_area) /* height */
|
||||
};
|
||||
|
||||
/* Set scissor. */
|
||||
lv_vglite_set_scissor(dest_area);
|
||||
|
||||
/* Set vgmatrix. */
|
||||
lv_vglite_set_translation_matrix(dest_area);
|
||||
|
||||
err = vg_lite_blit_rect(&dest_vgbuf, &src_vgbuf, rect, &vgmatrix,
|
||||
VG_LITE_BLEND_NONE, 0xFFFFFFFFU, VG_LITE_FILTER_POINT);
|
||||
if(err != VG_LITE_SUCCESS) {
|
||||
LV_LOG_ERROR("Blit rectangle failed.");
|
||||
/* Disable scissor. */
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
return _lv_gpu_nxp_vglite_blit_single(blit);
|
||||
if(lv_vglite_run() != LV_RES_OK) {
|
||||
LV_LOG_ERROR("Run failed.");
|
||||
/* Disable scissor. */
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/* Disable scissor. */
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/**********************
|
||||
@@ -274,223 +336,210 @@ lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
**********************/
|
||||
|
||||
#if VG_LITE_BLIT_SPLIT_ENABLED
|
||||
static lv_res_t _lv_gpu_nxp_vglite_blit_split(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
static lv_res_t lv_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
lv_res_t rv = LV_RES_INV;
|
||||
|
||||
if(_lv_gpu_nxp_vglite_check_blit(blit) != LV_RES_OK) {
|
||||
PRINT_BLT("Blit check failed\n");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
VG_LITE_LOG_TRACE("Blit "
|
||||
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
|
||||
"Size: ([%dx%d] -> [%dx%d]) | "
|
||||
"Addr: (0x%x -> 0x%x)",
|
||||
src_area->x1, src_area->y1, src_area->x2, src_area->y2,
|
||||
dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2,
|
||||
lv_area_get_width(src_area), lv_area_get_height(src_area),
|
||||
lv_area_get_width(dest_area), lv_area_get_height(dest_area),
|
||||
(uintptr_t)src_buf, (uintptr_t)dest_buf);
|
||||
|
||||
PRINT_BLT("BLIT from: "
|
||||
"Area: %03d,%03d - %03d,%03d "
|
||||
"Addr: %d\n\n",
|
||||
blit->src_area.x1, blit->src_area.y1,
|
||||
blit->src_area.x2, blit->src_area.y2,
|
||||
(uintptr_t) blit->src);
|
||||
|
||||
PRINT_BLT("BLIT to: "
|
||||
"Area: %03d,%03d - %03d,%03d "
|
||||
"Addr: %d\n\n",
|
||||
blit->dst_area.x1, blit->dst_area.y1,
|
||||
blit->dst_area.x2, blit->dst_area.y2,
|
||||
(uintptr_t) blit->src);
|
||||
|
||||
/* Stage 1: Move starting pointers as close as possible to [x1, y1], so coordinates are as small as possible. */
|
||||
_align_x(&blit->src_area, (lv_color_t **)&blit->src);
|
||||
_align_y(&blit->src_area, (lv_color_t **)&blit->src, blit->src_stride / sizeof(lv_color_t));
|
||||
_align_x(&blit->dst_area, (lv_color_t **)&blit->dst);
|
||||
_align_y(&blit->dst_area, (lv_color_t **)&blit->dst, blit->dst_stride / sizeof(lv_color_t));
|
||||
/* Stage 1: Move starting pointers as close as possible to [x1, y1], so coordinates are as small as possible. */
|
||||
align_x(src_area, (lv_color_t **)&src_buf);
|
||||
align_y(src_area, (lv_color_t **)&src_buf, src_stride);
|
||||
align_x(dest_area, (lv_color_t **)&dest_buf);
|
||||
align_y(dest_area, (lv_color_t **)&dest_buf, dest_stride);
|
||||
|
||||
/* Stage 2: If we're in limit, do a single BLIT */
|
||||
if((blit->src_area.x2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) &&
|
||||
(blit->src_area.y2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR)) {
|
||||
PRINT_BLT("Simple blit!\n");
|
||||
return _lv_gpu_nxp_vglite_blit_single(blit);
|
||||
if((src_area->x2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) &&
|
||||
(src_area->y2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR)) {
|
||||
if(check_src_alignment(src_buf, src_stride) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Check src alignment failed.");
|
||||
|
||||
/* Set new dest_vgbuf and src_vgbuf memory addresses. */
|
||||
lv_vglite_set_dest_buf_ptr(dest_buf);
|
||||
lv_vglite_set_src_buf_ptr(src_buf);
|
||||
|
||||
/* Set scissor */
|
||||
lv_vglite_set_scissor(dest_area);
|
||||
|
||||
/* Set vgmatrix. */
|
||||
lv_vglite_set_translation_matrix(dest_area);
|
||||
|
||||
/* Start blit. */
|
||||
rv = lv_vglite_blit(src_area, opa);
|
||||
|
||||
/* Disable scissor. */
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
VG_LITE_LOG_TRACE("Single "
|
||||
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
|
||||
"Size: ([%dx%d] -> [%dx%d]) | "
|
||||
"Addr: (0x%x -> 0x%x) %s",
|
||||
src_area->x1, src_area->y1, src_area->x2, src_area->y2,
|
||||
dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2,
|
||||
lv_area_get_width(src_area), lv_area_get_height(src_area),
|
||||
lv_area_get_width(dest_area), lv_area_get_height(dest_area),
|
||||
(uintptr_t)src_buf, (uintptr_t)dest_buf,
|
||||
rv == LV_RES_OK ? "OK!" : "FAILED!");
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
/* Stage 3: Split the BLIT into multiple tiles */
|
||||
PRINT_BLT("Split blit!\n");
|
||||
|
||||
PRINT_BLT("Blit "
|
||||
"([%03d,%03d], [%03d,%03d]) -> "
|
||||
"([%03d,%03d], [%03d,%03d]) | "
|
||||
"([%03dx%03d] -> [%03dx%03d]) | "
|
||||
"A:(%d -> %d)\n",
|
||||
blit->src_area.x1, blit->src_area.y1, blit->src_area.x2, blit->src_area.y2,
|
||||
blit->dst_area.x1, blit->dst_area.y1, blit->dst_area.x2, blit->dst_area.y2,
|
||||
lv_area_get_width(&blit->src_area), lv_area_get_height(&blit->src_area),
|
||||
lv_area_get_width(&blit->dst_area), lv_area_get_height(&blit->dst_area),
|
||||
(uintptr_t) blit->src, (uintptr_t) blit->dst);
|
||||
VG_LITE_LOG_TRACE("Split "
|
||||
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
|
||||
"Size: ([%dx%d] -> [%dx%d]) | "
|
||||
"Addr: (0x%x -> 0x%x)",
|
||||
src_area->x1, src_area->y1, src_area->x2, src_area->y2,
|
||||
dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2,
|
||||
lv_area_get_width(src_area), lv_area_get_height(src_area),
|
||||
lv_area_get_width(dest_area), lv_area_get_height(dest_area),
|
||||
(uintptr_t)src_buf, (uintptr_t)dest_buf);
|
||||
|
||||
|
||||
lv_coord_t totalWidth = lv_area_get_width(&blit->src_area);
|
||||
lv_coord_t totalHeight = lv_area_get_height(&blit->src_area);
|
||||
|
||||
lv_gpu_nxp_vglite_blit_info_t tileBlit;
|
||||
lv_coord_t width = lv_area_get_width(src_area);
|
||||
lv_coord_t height = lv_area_get_height(src_area);
|
||||
|
||||
/* Number of tiles needed */
|
||||
int totalTilesX = (blit->src_area.x1 + totalWidth + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) /
|
||||
LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
int totalTilesY = (blit->src_area.y1 + totalHeight + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) /
|
||||
LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
int total_tiles_x = (src_area->x1 + width + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) /
|
||||
LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
int total_tiles_y = (src_area->y1 + height + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) /
|
||||
LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
|
||||
/* src and dst buffer shift against each other. Src buffer real data [0,0] may start actually at [3,0] in buffer, as
|
||||
* the buffer pointer has to be aligned, while dst buffer real data [0,0] may start at [1,0] in buffer. alignment may be
|
||||
* different */
|
||||
int shiftSrcX = (blit->src_area.x1 > blit->dst_area.x1) ? (blit->src_area.x1 - blit->dst_area.x1) : 0;
|
||||
int shiftDstX = (blit->src_area.x1 < blit->dst_area.x1) ? (blit->dst_area.x1 - blit->src_area.x1) : 0;
|
||||
int shift_src_x = (src_area->x1 > dest_area->x1) ? (src_area->x1 - dest_area->x1) : 0;
|
||||
int shift_dest_x = (src_area->x1 < dest_area->x1) ? (dest_area->x1 - src_area->x1) : 0;
|
||||
|
||||
PRINT_BLT("\n");
|
||||
PRINT_BLT("Align shift: src: %d, dst: %d\n", shiftSrcX, shiftDstX);
|
||||
VG_LITE_LOG_TRACE("X shift: src: %d, dst: %d", shift_src_x, shift_dest_x);
|
||||
|
||||
tileBlit = *blit;
|
||||
lv_color_t * tile_dest_buf;
|
||||
lv_area_t tile_dest_area;
|
||||
const lv_color_t * tile_src_buf;
|
||||
lv_area_t tile_src_area;
|
||||
|
||||
for(int tileY = 0; tileY < totalTilesY; tileY++) {
|
||||
for(int y = 0; y < total_tiles_y; y++) {
|
||||
|
||||
tileBlit.src_area.y1 = 0; /* no vertical alignment, always start from 0 */
|
||||
tileBlit.src_area.y2 = totalHeight - tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tileBlit.src_area.y2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tileBlit.src_area.y2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; /* Should never happen */
|
||||
tile_src_area.y1 = 0; /* no vertical alignment, always start from 0 */
|
||||
tile_src_area.y2 = height - y * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tile_src_area.y2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tile_src_area.y2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; /* Should never happen */
|
||||
}
|
||||
tileBlit.src = blit->src + tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * blit->src_stride / sizeof(
|
||||
lv_color_t); /* stride in px! */
|
||||
tile_src_buf = src_buf + y * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * src_stride;
|
||||
|
||||
tileBlit.dst_area.y1 = tileBlit.src_area.y1; /* y has no alignment, always in sync with src */
|
||||
tileBlit.dst_area.y2 = tileBlit.src_area.y2;
|
||||
tile_dest_area.y1 = tile_src_area.y1; /* y has no alignment, always in sync with src */
|
||||
tile_dest_area.y2 = tile_src_area.y2;
|
||||
|
||||
tileBlit.dst = blit->dst + tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * blit->dst_stride / sizeof(
|
||||
lv_color_t); /* stride in px! */
|
||||
tile_dest_buf = dest_buf + y * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * dest_stride;
|
||||
|
||||
for(int tileX = 0; tileX < totalTilesX; tileX++) {
|
||||
for(int x = 0; x < total_tiles_x; x++) {
|
||||
|
||||
if(tileX == 0) {
|
||||
if(x == 0) {
|
||||
/* 1st tile is special - there may be a gap between buffer start pointer
|
||||
* and area.x1 value, as the pointer has to be aligned.
|
||||
* tileBlit.src pointer - keep init value from Y-loop.
|
||||
* tile_src_buf pointer - keep init value from Y-loop.
|
||||
* Also, 1st tile start is not shifted! shift is applied from 2nd tile */
|
||||
tileBlit.src_area.x1 = blit->src_area.x1;
|
||||
tileBlit.dst_area.x1 = blit->dst_area.x1;
|
||||
tile_src_area.x1 = src_area->x1;
|
||||
tile_dest_area.x1 = dest_area->x1;
|
||||
}
|
||||
else {
|
||||
/* subsequent tiles always starts from 0, but shifted*/
|
||||
tileBlit.src_area.x1 = 0 + shiftSrcX;
|
||||
tileBlit.dst_area.x1 = 0 + shiftDstX;
|
||||
tile_src_area.x1 = 0 + shift_src_x;
|
||||
tile_dest_area.x1 = 0 + shift_dest_x;
|
||||
/* and advance start pointer + 1 tile size */
|
||||
tileBlit.src += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
tileBlit.dst += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
tile_src_buf += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
tile_dest_buf += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
}
|
||||
|
||||
/* Clip tile end coordinates */
|
||||
tileBlit.src_area.x2 = totalWidth + blit->src_area.x1 - tileX * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tileBlit.src_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tileBlit.src_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
tile_src_area.x2 = width + src_area->x1 - x * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tile_src_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tile_src_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
}
|
||||
|
||||
tileBlit.dst_area.x2 = totalWidth + blit->dst_area.x1 - tileX * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tileBlit.dst_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tileBlit.dst_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
tile_dest_area.x2 = width + dest_area->x1 - x * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tile_dest_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tile_dest_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
}
|
||||
|
||||
if(tileX < (totalTilesX - 1)) {
|
||||
/* And adjust end coords if shifted, but not for last tile! */
|
||||
tileBlit.src_area.x2 += shiftSrcX;
|
||||
tileBlit.dst_area.x2 += shiftDstX;
|
||||
if(x < (total_tiles_x - 1)) {
|
||||
/* And adjust end coords if shifted, but not for last tile! */
|
||||
tile_src_area.x2 += shift_src_x;
|
||||
tile_dest_area.x2 += shift_dest_x;
|
||||
}
|
||||
|
||||
rv = _lv_gpu_nxp_vglite_blit_single(&tileBlit);
|
||||
if(check_src_alignment(tile_src_buf, src_stride) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Check src alignment failed.");
|
||||
|
||||
#if BLIT_DBG_AREAS
|
||||
lv_vglite_dbg_draw_rectangle((lv_color_t *) tileBlit.dst, tileBlit.dst_width, tileBlit.dst_height, &tileBlit.dst_area,
|
||||
LV_COLOR_RED);
|
||||
lv_vglite_dbg_draw_rectangle((lv_color_t *) tileBlit.src, tileBlit.src_width, tileBlit.src_height, &tileBlit.src_area,
|
||||
LV_COLOR_GREEN);
|
||||
#endif
|
||||
/* Set new dest_vgbuf and src_vgbuf memory addresses. */
|
||||
lv_vglite_set_dest_buf_ptr(tile_dest_buf);
|
||||
lv_vglite_set_src_buf_ptr(tile_src_buf);
|
||||
|
||||
PRINT_BLT("Tile [%d, %d]: "
|
||||
"([%d,%d], [%d,%d]) -> "
|
||||
"([%d,%d], [%d,%d]) | "
|
||||
"([%dx%d] -> [%dx%d]) | "
|
||||
"A:(0x%8X -> 0x%8X) %s\n",
|
||||
tileX, tileY,
|
||||
tileBlit.src_area.x1, tileBlit.src_area.y1, tileBlit.src_area.x2, tileBlit.src_area.y2,
|
||||
tileBlit.dst_area.x1, tileBlit.dst_area.y1, tileBlit.dst_area.x2, tileBlit.dst_area.y2,
|
||||
lv_area_get_width(&tileBlit.src_area), lv_area_get_height(&tileBlit.src_area),
|
||||
lv_area_get_width(&tileBlit.dst_area), lv_area_get_height(&tileBlit.dst_area),
|
||||
(uintptr_t) tileBlit.src, (uintptr_t) tileBlit.dst,
|
||||
rv == LV_RES_OK ? "OK!" : "!!! FAILED !!!");
|
||||
/* Set scissor */
|
||||
lv_vglite_set_scissor(&tile_dest_area);
|
||||
|
||||
if(rv != LV_RES_OK) { /* if anything goes wrong... */
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("Split blit failed. Trying SW blit instead.");
|
||||
#endif
|
||||
_sw_blit(&tileBlit);
|
||||
rv = LV_RES_OK; /* Don't report error, as SW BLIT was performed */
|
||||
/* Set vgmatrix. */
|
||||
lv_vglite_set_translation_matrix(&tile_dest_area);
|
||||
|
||||
/* Start blit. */
|
||||
rv = lv_vglite_blit(&tile_src_area, opa);
|
||||
|
||||
/* Disable scissor. */
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
VG_LITE_LOG_TRACE("Tile [%d, %d] "
|
||||
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
|
||||
"Size: ([%dx%d] -> [%dx%d]) | "
|
||||
"Addr: (0x%x -> 0x%x) %s",
|
||||
x, y,
|
||||
tile_src_area.x1, tile_src_area.y1, tile_src_area.x2, tile_src_area.y2,
|
||||
tile_dest_area.x1, tile_dest_area.y1, tile_dest_area.x2, tile_dest_area.y2,
|
||||
lv_area_get_width(&tile_src_area), lv_area_get_height(&tile_src_area),
|
||||
lv_area_get_width(&tile_dest_area), lv_area_get_height(&tile_dest_area),
|
||||
(uintptr_t)tile_src_buf, (uintptr_t)tile_dest_buf,
|
||||
rv == LV_RES_OK ? "OK!" : "FAILED!");
|
||||
|
||||
if(rv != LV_RES_OK) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
PRINT_BLT(" \n");
|
||||
}
|
||||
|
||||
return rv; /* should never fail */
|
||||
return rv;
|
||||
}
|
||||
#endif /* VG_LITE_BLIT_SPLIT_ENABLED */
|
||||
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
|
||||
|
||||
static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
static lv_res_t lv_vglite_blit(const lv_area_t * src_area, lv_opa_t opa)
|
||||
{
|
||||
vg_lite_buffer_t src_vgbuf, dst_vgbuf;
|
||||
vg_lite_error_t err = VG_LITE_SUCCESS;
|
||||
uint32_t rect[4];
|
||||
vg_lite_float_t scale = 1.0;
|
||||
vg_lite_buffer_t * dst_vgbuf = lv_vglite_get_dest_buf();
|
||||
vg_lite_buffer_t * src_vgbuf = lv_vglite_get_src_buf();
|
||||
|
||||
if(blit == NULL) {
|
||||
/*Wrong parameter*/
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(blit->opa < (lv_opa_t) LV_OPA_MIN) {
|
||||
return LV_RES_OK; /*Nothing to BLIT*/
|
||||
}
|
||||
|
||||
/*Wrap src/dst buffer into VG-Lite buffer*/
|
||||
if(lv_vglite_init_buf(&src_vgbuf, (uint32_t)blit->src_width, (uint32_t)blit->src_height, (uint32_t)blit->src_stride,
|
||||
blit->src, true) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Init buffer failed.");
|
||||
|
||||
if(lv_vglite_init_buf(&dst_vgbuf, (uint32_t)blit->dst_width, (uint32_t)blit->dst_height, (uint32_t)blit->dst_stride,
|
||||
blit->dst, false) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Init buffer failed.");
|
||||
|
||||
rect[0] = (uint32_t)blit->src_area.x1; /* start x */
|
||||
rect[1] = (uint32_t)blit->src_area.y1; /* start y */
|
||||
rect[2] = (uint32_t)blit->src_area.x2 - (uint32_t)blit->src_area.x1 + 1U; /* width */
|
||||
rect[3] = (uint32_t)blit->src_area.y2 - (uint32_t)blit->src_area.y1 + 1U; /* height */
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
vg_lite_translate((vg_lite_float_t)blit->dst_area.x1, (vg_lite_float_t)blit->dst_area.y1, &matrix);
|
||||
|
||||
if((blit->angle != 0) || (blit->zoom != LV_IMG_ZOOM_NONE)) {
|
||||
vg_lite_translate(blit->pivot.x, blit->pivot.y, &matrix);
|
||||
vg_lite_rotate(blit->angle / 10.0f, &matrix); /* angle is 1/10 degree */
|
||||
scale = 1.0f * blit->zoom / LV_IMG_ZOOM_NONE;
|
||||
vg_lite_scale(scale, scale, &matrix);
|
||||
vg_lite_translate(0.0f - blit->pivot.x, 0.0f - blit->pivot.y, &matrix);
|
||||
}
|
||||
|
||||
/*Clean & invalidate cache*/
|
||||
lv_vglite_invalidate_cache();
|
||||
uint32_t rect[] = {
|
||||
(uint32_t)src_area->x1, /* start x */
|
||||
(uint32_t)src_area->y1, /* start y */
|
||||
(uint32_t)lv_area_get_width(src_area), /* width */
|
||||
(uint32_t)lv_area_get_height(src_area) /* height */
|
||||
};
|
||||
|
||||
uint32_t color;
|
||||
vg_lite_blend_t blend;
|
||||
if(blit->opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
if(opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
color = 0xFFFFFFFFU;
|
||||
blend = VG_LITE_BLEND_SRC_OVER;
|
||||
src_vgbuf.transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
|
||||
src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
|
||||
}
|
||||
else {
|
||||
uint32_t opa = (uint32_t)blit->opa;
|
||||
if(vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) {
|
||||
color = (opa << 24) | 0x00FFFFFFU;
|
||||
}
|
||||
@@ -498,94 +547,62 @@ static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * b
|
||||
color = (opa << 24) | (opa << 16) | (opa << 8) | opa;
|
||||
}
|
||||
blend = VG_LITE_BLEND_SRC_OVER;
|
||||
src_vgbuf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
|
||||
src_vgbuf.transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
|
||||
src_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
|
||||
src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
|
||||
}
|
||||
|
||||
err = vg_lite_blit_rect(&dst_vgbuf, &src_vgbuf, rect, &matrix, blend, color, VG_LITE_FILTER_POINT);
|
||||
err = vg_lite_blit_rect(dst_vgbuf, src_vgbuf, rect, &vgmatrix, blend, color, VG_LITE_FILTER_POINT);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Blit rectangle failed.");
|
||||
|
||||
err = vg_lite_finish();
|
||||
VG_LITE_ERR_RETURN_INV(err, "Finish failed.");
|
||||
if(lv_vglite_run() != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Run failed.");
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
static lv_res_t check_src_alignment(const lv_color_t * src_buf, lv_coord_t src_stride)
|
||||
{
|
||||
/* No alignment requirement for destination pixel buffer when using mode VG_LITE_LINEAR */
|
||||
|
||||
/* Test for pointer alignment */
|
||||
if((((uintptr_t)src_buf) % (uintptr_t)LV_ATTRIBUTE_MEM_ALIGN_SIZE) != (uintptr_t)0x0U)
|
||||
VG_LITE_RETURN_INV("Src buffer ptr (0x%x) not aligned to 0x%x bytes.",
|
||||
(size_t)src_buf, LV_ATTRIBUTE_MEM_ALIGN_SIZE);
|
||||
|
||||
/* Test for stride alignment */
|
||||
if((src_stride % (lv_coord_t)LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX) != 0x0U)
|
||||
VG_LITE_RETURN_INV("Src buffer stride (%d px) not aligned to %d px.",
|
||||
src_stride, LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
static inline void lv_vglite_set_translation_matrix(const lv_area_t * dest_area)
|
||||
{
|
||||
vg_lite_identity(&vgmatrix);
|
||||
vg_lite_translate((vg_lite_float_t)dest_area->x1, (vg_lite_float_t)dest_area->y1, &vgmatrix);
|
||||
}
|
||||
|
||||
static inline void lv_vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_img_dsc_t * dsc)
|
||||
{
|
||||
lv_vglite_set_translation_matrix(dest_area);
|
||||
|
||||
bool has_scale = (dsc->zoom != LV_IMG_ZOOM_NONE);
|
||||
bool has_rotation = (dsc->angle != 0);
|
||||
|
||||
vg_lite_translate(dsc->pivot.x, dsc->pivot.y, &vgmatrix);
|
||||
if(has_rotation)
|
||||
vg_lite_rotate(dsc->angle / 10.0f, &vgmatrix); /* angle is 1/10 degree */
|
||||
if(has_scale) {
|
||||
vg_lite_float_t scale = 1.0f * dsc->zoom / LV_IMG_ZOOM_NONE;
|
||||
vg_lite_scale(scale, scale, &vgmatrix);
|
||||
}
|
||||
vg_lite_translate(0.0f - dsc->pivot.x, 0.0f - dsc->pivot.y, &vgmatrix);
|
||||
}
|
||||
|
||||
#if VG_LITE_BLIT_SPLIT_ENABLED
|
||||
|
||||
static void _sw_blit(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
static void align_x(lv_area_t * area, lv_color_t ** buf)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
lv_coord_t w = lv_area_get_width(&blit->src_area);
|
||||
lv_coord_t h = lv_area_get_height(&blit->src_area);
|
||||
|
||||
int32_t srcStridePx = blit->src_stride / (int32_t)sizeof(lv_color_t);
|
||||
int32_t dstStridePx = blit->dst_stride / (int32_t)sizeof(lv_color_t);
|
||||
|
||||
lv_color_t * src = (lv_color_t *)blit->src + blit->src_area.y1 * srcStridePx + blit->src_area.x1;
|
||||
lv_color_t * dst = (lv_color_t *)blit->dst + blit->dst_area.y1 * dstStridePx + blit->dst_area.x1;
|
||||
|
||||
if(blit->opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
/* simple copy */
|
||||
for(y = 0; y < h; y++) {
|
||||
lv_memcpy(dst, src, (uint32_t)w * sizeof(lv_color_t));
|
||||
src += srcStridePx;
|
||||
dst += dstStridePx;
|
||||
}
|
||||
}
|
||||
else if(blit->opa >= LV_OPA_MIN) {
|
||||
/* alpha blending */
|
||||
for(y = 0; y < h; y++) {
|
||||
for(x = 0; x < w; x++) {
|
||||
dst[x] = lv_color_mix(src[x], dst[x], blit->opa);
|
||||
}
|
||||
src += srcStridePx;
|
||||
dst += dstStridePx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static lv_res_t _lv_gpu_nxp_vglite_check_blit(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
{
|
||||
|
||||
/* Test for minimal width */
|
||||
if(lv_area_get_width(&blit->src_area) < (lv_coord_t)LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX)
|
||||
VG_LITE_RETURN_INV("Src area width (%d) is smaller than required (%d).", lv_area_get_width(&blit->src_area),
|
||||
LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
|
||||
/* Test for minimal width */
|
||||
if(lv_area_get_width(&blit->dst_area) < (lv_coord_t)LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX)
|
||||
VG_LITE_RETURN_INV("Dest area width (%d) is smaller than required (%d).", lv_area_get_width(&blit->dst_area),
|
||||
LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
|
||||
/* Test for pointer alignment */
|
||||
if((((uintptr_t) blit->src) % LV_ATTRIBUTE_MEM_ALIGN_SIZE) != 0x0)
|
||||
VG_LITE_RETURN_INV("Src buffer ptr (0x%X) not aligned to %d.", (size_t) blit->src, LV_ATTRIBUTE_MEM_ALIGN_SIZE);
|
||||
|
||||
/* No alignment requirement for destination pixel buffer when using mode VG_LITE_LINEAR */
|
||||
|
||||
/* Test for stride alignment */
|
||||
if((blit->src_stride % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * LV_COLOR_DEPTH / 8)) != 0x0)
|
||||
VG_LITE_RETURN_INV("Src buffer stride (%d px) not aligned to %d px.", blit->src_stride,
|
||||
LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
|
||||
/* Test for stride alignment */
|
||||
if((blit->dst_stride % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * LV_COLOR_DEPTH / 8)) != 0x0)
|
||||
VG_LITE_RETURN_INV("Dest buffer stride (%d px) not aligned to %d px.", blit->dst_stride,
|
||||
LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
|
||||
if((lv_area_get_width(&blit->src_area) != lv_area_get_width(&blit->dst_area)) ||
|
||||
(lv_area_get_height(&blit->src_area) != lv_area_get_height(&blit->dst_area)))
|
||||
VG_LITE_RETURN_INV("Src and dest buffer areas are not equal.");
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
static void _align_x(lv_area_t * area, lv_color_t ** buf)
|
||||
{
|
||||
|
||||
int alignedAreaStartPx = area->x1 - (area->x1 % (LV_ATTRIBUTE_MEM_ALIGN_SIZE * 8 / LV_COLOR_DEPTH));
|
||||
int alignedAreaStartPx = area->x1 - (area->x1 % (LV_ATTRIBUTE_MEM_ALIGN_SIZE / sizeof(lv_color_t)));
|
||||
VG_LITE_COND_STOP(alignedAreaStartPx < 0, "Negative X alignment.");
|
||||
|
||||
area->x1 -= alignedAreaStartPx;
|
||||
@@ -593,17 +610,17 @@ static void _align_x(lv_area_t * area, lv_color_t ** buf)
|
||||
*buf += alignedAreaStartPx;
|
||||
}
|
||||
|
||||
static void _align_y(lv_area_t * area, lv_color_t ** buf, uint32_t stridePx)
|
||||
static void align_y(lv_area_t * area, lv_color_t ** buf, lv_coord_t stride)
|
||||
{
|
||||
int LineToAlignMem;
|
||||
int alignedAreaStartPy;
|
||||
/* find how many lines of pixels will respect memory alignment requirement */
|
||||
if(stridePx % (uint32_t)LV_ATTRIBUTE_MEM_ALIGN_SIZE == 0U) {
|
||||
if((stride % (lv_coord_t)LV_ATTRIBUTE_MEM_ALIGN_SIZE) == 0x0U) {
|
||||
alignedAreaStartPy = area->y1;
|
||||
}
|
||||
else {
|
||||
LineToAlignMem = LV_ATTRIBUTE_MEM_ALIGN_SIZE / (sizeof(lv_color_t) * LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
VG_LITE_COND_STOP(LV_ATTRIBUTE_MEM_ALIGN_SIZE % (sizeof(lv_color_t) * LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX),
|
||||
LineToAlignMem = LV_ATTRIBUTE_MEM_ALIGN_SIZE / (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * sizeof(lv_color_t));
|
||||
VG_LITE_COND_STOP(LV_ATTRIBUTE_MEM_ALIGN_SIZE % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * sizeof(lv_color_t)),
|
||||
"Complex case: need gcd function.");
|
||||
alignedAreaStartPy = area->y1 - (area->y1 % LineToAlignMem);
|
||||
VG_LITE_COND_STOP(alignedAreaStartPy < 0, "Negative Y alignment.");
|
||||
@@ -611,7 +628,7 @@ static void _align_y(lv_area_t * area, lv_color_t ** buf, uint32_t stridePx)
|
||||
|
||||
area->y1 -= alignedAreaStartPy;
|
||||
area->y2 -= alignedAreaStartPy;
|
||||
*buf += (uint32_t)alignedAreaStartPy * stridePx;
|
||||
*buf += (uint32_t)(alignedAreaStartPy * stride);
|
||||
}
|
||||
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020-2022 NXP
|
||||
* Copyright 2020-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -41,64 +41,31 @@ extern "C" {
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "lv_gpu_nxp_vglite.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) to be filled by VG-Lite with 100% opacity*/
|
||||
#define LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT 5000
|
||||
#endif
|
||||
/**
|
||||
* Enable BLIT quality degradation workaround for RT595,
|
||||
* recommended for screen's dimension > 352 pixels.
|
||||
*/
|
||||
#define RT595_BLIT_WRKRND_ENABLED 1
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) to be filled by VG-Lite with transparency*/
|
||||
#define LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) for image copy with 100% opacity to be handled by VG-Lite*/
|
||||
#define LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_BUFF_SYNC_BLIT_SIZE_LIMIT
|
||||
/** Minimum invalidated area (in pixels) to be synchronized by VG-Lite during buffer sync */
|
||||
#define LV_GPU_NXP_VG_LITE_BUFF_SYNC_BLIT_SIZE_LIMIT 5000
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) for image copy with transparency to be handled by VG-Lite*/
|
||||
#define LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT 5000
|
||||
/* Internal compound symbol */
|
||||
#if (defined(CPU_MIMXRT595SFFOB) || defined(CPU_MIMXRT595SFFOB_cm33) || \
|
||||
defined(CPU_MIMXRT595SFFOC) || defined(CPU_MIMXRT595SFFOC_cm33)) && \
|
||||
RT595_BLIT_WRKRND_ENABLED
|
||||
#define VG_LITE_BLIT_SPLIT_ENABLED 1
|
||||
#else
|
||||
#define VG_LITE_BLIT_SPLIT_ENABLED 0
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* BLock Image Transfer descriptor structure
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
const lv_color_t * src; /**< Source buffer pointer (must be aligned on 32 bytes)*/
|
||||
lv_area_t src_area; /**< Area to be copied from source*/
|
||||
lv_coord_t src_width; /**< Source buffer width*/
|
||||
lv_coord_t src_height; /**< Source buffer height*/
|
||||
int32_t src_stride; /**< Source buffer stride in bytes (must be aligned on 16 px)*/
|
||||
|
||||
const lv_color_t * dst; /**< Destination buffer pointer (must be aligned on 32 bytes)*/
|
||||
lv_area_t dst_area; /**< Target area in destination buffer (must be the same as src_area)*/
|
||||
lv_coord_t dst_width; /**< Destination buffer width*/
|
||||
lv_coord_t dst_height; /**< Destination buffer height*/
|
||||
int32_t dst_stride; /**< Destination buffer stride in bytes (must be aligned on 16 px)*/
|
||||
|
||||
lv_opa_t opa; /**< Opacity - alpha mix (0 = source not copied, 255 = 100% opaque)*/
|
||||
uint32_t angle; /**< Rotation angle (1/10 of degree)*/
|
||||
uint32_t zoom; /**< 256 = no zoom (1:1 scale ratio)*/
|
||||
lv_point_t pivot; /**< The coordinates of rotation pivot in source image buffer*/
|
||||
} lv_gpu_nxp_vglite_blit_info_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@@ -106,35 +73,87 @@ typedef struct {
|
||||
/**
|
||||
* Fill area, with optional opacity.
|
||||
*
|
||||
* @param[in/out] dest_buf Destination buffer pointer (must be aligned on 32 bytes)
|
||||
* @param[in] dest_width Destination buffer width in pixels (must be aligned on 16 px)
|
||||
* @param[in] dest_height Destination buffer height in pixels
|
||||
* @param[in] fill_area Area to be filled
|
||||
* @param[in] color Fill color
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] color Color
|
||||
* @param[in] opa Opacity (255 = full, 128 = 50% background/50% color, 0 = no fill)
|
||||
*
|
||||
* @retval LV_RES_OK Fill completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height,
|
||||
const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa);
|
||||
lv_res_t lv_gpu_nxp_vglite_fill(const lv_area_t * dest_area, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
#if VG_LITE_BLIT_SPLIT_ENABLED
|
||||
/**
|
||||
* BLock Image Transfer.
|
||||
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects.
|
||||
* By default, image is copied directly, with optional opacity.
|
||||
*
|
||||
* @param[in/out] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Source area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] opa Opacity
|
||||
*
|
||||
* @param[in] blit Description of the transfer
|
||||
* @retval LV_RES_OK Transfer complete
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_blit(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_blit_split(lv_color_t * dest_buf, lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, lv_area_t * src_area, lv_coord_t src_stride,
|
||||
lv_opa_t opa);
|
||||
#else
|
||||
/**
|
||||
* BLock Image Transfer with transformation.
|
||||
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects.
|
||||
* By default, image is copied directly, with optional opacity.
|
||||
*
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Source area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] opa Opacity
|
||||
*
|
||||
* @param[in] blit Description of the transfer
|
||||
* @retval LV_RES_OK Transfer complete
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_blit_transform(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
lv_res_t lv_gpu_nxp_vglite_blit(const lv_area_t * dest_area,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with transformation.
|
||||
* By default, image is copied directly, with optional opacity.
|
||||
*
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] clip_area Clip area with relative coordinates of destination buffer
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Source area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
* @param[in] dsc Image descriptor
|
||||
*
|
||||
* @retval LV_RES_OK Transfer complete
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_blit_transform(const lv_area_t * dest_area, const lv_area_t * clip_area,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride,
|
||||
const lv_draw_img_dsc_t * dsc);
|
||||
|
||||
#endif /*VG_LITE_BLIT_SPLIT_ENABLED*/
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - simple copy of rectangular image from source to destination.
|
||||
*
|
||||
* @param[in] dest_buf Destination buffer
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in pixels
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Source area with relative coordinates of source buffer
|
||||
* @param[in] src_stride Stride of source buffer in pixels
|
||||
*
|
||||
* @retval LV_RES_OK Transfer complete
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_buffer_copy(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src_buf, const lv_area_t * src_area, lv_coord_t src_stride);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
142
src/draw/nxp/vglite/lv_draw_vglite_line.c
Normal file
142
src/draw/nxp/vglite/lv_draw_vglite_line.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_line.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite_line.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include <math.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
vg_lite_error_t err = VG_LITE_SUCCESS;
|
||||
vg_lite_path_t path;
|
||||
vg_lite_color_t vgcol; /* vglite takes ABGR */
|
||||
vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf();
|
||||
vg_lite_cap_style_t cap_style = (dsc->round_start || dsc->round_end) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT;
|
||||
vg_lite_join_style_t join_style = (dsc->round_start || dsc->round_end) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER;
|
||||
|
||||
bool is_dashed = (dsc->dash_width && dsc->dash_gap);
|
||||
|
||||
vg_lite_float_t stroke_dash_pattern[2] = {0, 0};
|
||||
uint32_t stroke_dash_count = 0;
|
||||
vg_lite_float_t stroke_dash_phase = 0;
|
||||
if(is_dashed) {
|
||||
stroke_dash_pattern[0] = (vg_lite_float_t)dsc->dash_width;
|
||||
stroke_dash_pattern[1] = (vg_lite_float_t)dsc->dash_gap;
|
||||
stroke_dash_count = sizeof(stroke_dash_pattern) / sizeof(vg_lite_float_t);
|
||||
stroke_dash_phase = (vg_lite_float_t)dsc->dash_width / 2;
|
||||
}
|
||||
|
||||
/* Choose vglite blend mode based on given lvgl blend mode */
|
||||
vg_lite_blend_t vglite_blend_mode = lv_vglite_get_blend_mode(dsc->blend_mode);
|
||||
|
||||
/*** Init path ***/
|
||||
lv_coord_t width = dsc->width;
|
||||
|
||||
int32_t line_path[] = { /*VG line path*/
|
||||
VLC_OP_MOVE, point1->x, point1->y,
|
||||
VLC_OP_LINE, point2->x, point2->y,
|
||||
VLC_OP_END
|
||||
};
|
||||
|
||||
err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(line_path), line_path,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Init path failed.");
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
lv_color32_t col32 = { .full = lv_color_to32(dsc->color) }; /*Convert color to RGBA8888*/
|
||||
vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888;
|
||||
if(lv_vglite_premult_and_swizzle(&vgcol, col32, dsc->opa, color_format) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Premultiplication and swizzle failed.");
|
||||
|
||||
/*** Draw line ***/
|
||||
err = vg_lite_set_draw_path_type(&path, VG_LITE_DRAW_STROKE_PATH);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Set draw path type failed.");
|
||||
|
||||
err = vg_lite_set_stroke(&path, cap_style, join_style, width, 8, stroke_dash_pattern, stroke_dash_count,
|
||||
stroke_dash_phase, vgcol);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Set stroke failed.");
|
||||
|
||||
err = vg_lite_update_stroke(&path);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Update stroke failed.");
|
||||
|
||||
lv_vglite_set_scissor(clip_area);
|
||||
|
||||
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, vglite_blend_mode, vgcol);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Draw line failed.");
|
||||
|
||||
if(lv_vglite_run() != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Run failed.");
|
||||
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
err = vg_lite_clear_path(&path);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
83
src/draw/nxp/vglite/lv_draw_vglite_line.h
Normal file
83
src/draw/nxp/vglite/lv_draw_vglite_line.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_line.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_VGLITE_LINE_H
|
||||
#define LV_DRAW_VGLITE_LINE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "lv_vglite_utils.h"
|
||||
#include "../../lv_draw_line.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw line shape with effects
|
||||
*
|
||||
* @param[in] point1 Starting point with relative coordinates
|
||||
* @param[in] point2 Ending point with relative coordinates
|
||||
* @param[in] clip_area Clipping area with relative coordinates to dest buff
|
||||
* @param[in] dsc Line description structure (width, rounded ending, opacity, ...)
|
||||
*
|
||||
* @retval LV_RES_OK Draw completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_VGLITE_RECT_H*/
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2021, 2022 NXP
|
||||
* Copyright 2021-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -34,10 +34,28 @@
|
||||
#include "lv_draw_vglite_rect.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include <math.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* Path data sizes for different elements */
|
||||
#define CUBIC_PATH_DATA_SIZE 7 /* 1 opcode, 6 arguments */
|
||||
#define LINE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */
|
||||
#define MOVE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */
|
||||
#define END_PATH_DATA_SIZE 1 /* 1 opcode, 0 arguments */
|
||||
/* Maximum possible rectangle path size
|
||||
* is in the rounded rectangle case:
|
||||
* - 1 move for the path start
|
||||
* - 4 cubics for the corners
|
||||
* - 4 lines for the sides
|
||||
* - 1 end for the path end */
|
||||
#define RECT_PATH_DATA_MAX_SIZE 1 * MOVE_PATH_DATA_SIZE + 4 * CUBIC_PATH_DATA_SIZE + 4 * LINE_PATH_DATA_SIZE + 1 * END_PATH_DATA_SIZE
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -47,6 +65,18 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Generates path data for rectangle drawing.
|
||||
*
|
||||
* @param[in/out] path The path data to initialize
|
||||
* @param[in/out] path_size The resulting size of the created path data
|
||||
* @param[in] dsc The style descriptor for the rectangle to be drawn
|
||||
* @param[in] coords The coordinates of the rectangle to be drawn
|
||||
*/
|
||||
static void lv_vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size,
|
||||
lv_coord_t radius,
|
||||
const lv_area_t * coords);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -59,94 +89,37 @@
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_bg(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_rect_dsc_t * dsc)
|
||||
{
|
||||
vg_lite_buffer_t vgbuf;
|
||||
vg_lite_error_t err = VG_LITE_SUCCESS;
|
||||
lv_coord_t dest_width = lv_area_get_width(draw_ctx->buf_area);
|
||||
lv_coord_t dest_height = lv_area_get_height(draw_ctx->buf_area);
|
||||
vg_lite_path_t path;
|
||||
vg_lite_color_t vgcol; /* vglite takes ABGR */
|
||||
vg_lite_matrix_t matrix;
|
||||
lv_coord_t width = lv_area_get_width(coords);
|
||||
lv_coord_t height = lv_area_get_height(coords);
|
||||
vg_lite_linear_gradient_t gradient;
|
||||
vg_lite_matrix_t * grad_matrix;
|
||||
vg_lite_color_t vgcol;
|
||||
lv_coord_t radius = dsc->radius;
|
||||
vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf();
|
||||
|
||||
if(dsc->radius < 0)
|
||||
return LV_RES_INV;
|
||||
|
||||
/* Make areas relative to draw buffer */
|
||||
lv_area_t rel_coords;
|
||||
lv_area_copy(&rel_coords, coords);
|
||||
lv_area_move(&rel_coords, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
lv_area_t rel_clip;
|
||||
lv_area_copy(&rel_clip, draw_ctx->clip_area);
|
||||
lv_area_move(&rel_clip, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
|
||||
/*** Init destination buffer ***/
|
||||
if(lv_vglite_init_buf(&vgbuf, (uint32_t)dest_width, (uint32_t)dest_height, (uint32_t)dest_width * sizeof(lv_color_t),
|
||||
(const lv_color_t *)draw_ctx->buf, false) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Init buffer failed.");
|
||||
|
||||
/*** Init path ***/
|
||||
int32_t rad = dsc->radius;
|
||||
if(dsc->radius == LV_RADIUS_CIRCLE) {
|
||||
rad = (width > height) ? height / 2 : width / 2;
|
||||
}
|
||||
|
||||
if((dsc->radius == LV_RADIUS_CIRCLE) && (width == height)) {
|
||||
float tang = ((float)rad * BEZIER_OPTIM_CIRCLE);
|
||||
int32_t cpoff = (int32_t)tang;
|
||||
int32_t circle_path[] = { /*VG circle path*/
|
||||
VLC_OP_MOVE, rel_coords.x1 + rad, rel_coords.y1,
|
||||
VLC_OP_CUBIC_REL, cpoff, 0, rad, rad - cpoff, rad, rad, /* top-right */
|
||||
VLC_OP_CUBIC_REL, 0, cpoff, cpoff - rad, rad, 0 - rad, rad, /* bottom-right */
|
||||
VLC_OP_CUBIC_REL, 0 - cpoff, 0, 0 - rad, cpoff - rad, 0 - rad, 0 - rad, /* bottom-left */
|
||||
VLC_OP_CUBIC_REL, 0, 0 - cpoff, rad - cpoff, 0 - rad, rad, 0 - rad, /* top-left */
|
||||
VLC_OP_END
|
||||
};
|
||||
err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(circle_path), circle_path,
|
||||
(vg_lite_float_t) rel_clip.x1, (vg_lite_float_t) rel_clip.y1,
|
||||
((vg_lite_float_t) rel_clip.x2) + 1.0f, ((vg_lite_float_t) rel_clip.y2) + 1.0f);
|
||||
}
|
||||
else if(dsc->radius > 0) {
|
||||
float tang = ((float)rad * BEZIER_OPTIM_CIRCLE);
|
||||
int32_t cpoff = (int32_t)tang;
|
||||
int32_t rounded_path[] = { /*VG rounded rectangular path*/
|
||||
VLC_OP_MOVE, rel_coords.x1 + rad, rel_coords.y1,
|
||||
VLC_OP_LINE, rel_coords.x2 - rad + 1, rel_coords.y1, /* top */
|
||||
VLC_OP_CUBIC_REL, cpoff, 0, rad, rad - cpoff, rad, rad, /* top-right */
|
||||
VLC_OP_LINE, rel_coords.x2 + 1, rel_coords.y2 - rad + 1, /* right */
|
||||
VLC_OP_CUBIC_REL, 0, cpoff, cpoff - rad, rad, 0 - rad, rad, /* bottom-right */
|
||||
VLC_OP_LINE, rel_coords.x1 + rad, rel_coords.y2 + 1, /* bottom */
|
||||
VLC_OP_CUBIC_REL, 0 - cpoff, 0, 0 - rad, cpoff - rad, 0 - rad, 0 - rad, /* bottom-left */
|
||||
VLC_OP_LINE, rel_coords.x1, rel_coords.y1 + rad, /* left */
|
||||
VLC_OP_CUBIC_REL, 0, 0 - cpoff, rad - cpoff, 0 - rad, rad, 0 - rad, /* top-left */
|
||||
VLC_OP_END
|
||||
};
|
||||
err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(rounded_path), rounded_path,
|
||||
(vg_lite_float_t) rel_clip.x1, (vg_lite_float_t) rel_clip.y1,
|
||||
((vg_lite_float_t) rel_clip.x2) + 1.0f, ((vg_lite_float_t) rel_clip.y2) + 1.0f);
|
||||
}
|
||||
else {
|
||||
int32_t rect_path[] = { /*VG rectangular path*/
|
||||
VLC_OP_MOVE, rel_coords.x1, rel_coords.y1,
|
||||
VLC_OP_LINE, rel_coords.x2 + 1, rel_coords.y1,
|
||||
VLC_OP_LINE, rel_coords.x2 + 1, rel_coords.y2 + 1,
|
||||
VLC_OP_LINE, rel_coords.x1, rel_coords.y2 + 1,
|
||||
VLC_OP_LINE, rel_coords.x1, rel_coords.y1,
|
||||
VLC_OP_END
|
||||
};
|
||||
err = vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_LOW, sizeof(rect_path), rect_path,
|
||||
(vg_lite_float_t) rel_clip.x1, (vg_lite_float_t) rel_clip.y1,
|
||||
((vg_lite_float_t) rel_clip.x2) + 1.0f, ((vg_lite_float_t) rel_clip.y2) + 1.0f);
|
||||
}
|
||||
int32_t path_data[RECT_PATH_DATA_MAX_SIZE];
|
||||
uint32_t path_data_size;
|
||||
lv_vglite_create_rect_path_data(path_data, &path_data_size, radius, coords);
|
||||
vg_lite_quality_t path_quality = dsc->radius > 0 ? VG_LITE_HIGH : VG_LITE_LOW;
|
||||
|
||||
vg_lite_path_t path;
|
||||
err = vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Init path failed.");
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
vg_lite_matrix_t * grad_matrix;
|
||||
vg_lite_linear_gradient_t gradient;
|
||||
|
||||
/*** Init Color/Gradient ***/
|
||||
if(dsc->bg_grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE) {
|
||||
uint32_t colors[2];
|
||||
@@ -154,18 +127,14 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_
|
||||
lv_color32_t col32[2];
|
||||
|
||||
/* Gradient setup */
|
||||
uint8_t cnt = MAX(dsc->bg_grad.stops_count, 2);
|
||||
uint8_t cnt = LV_MAX(dsc->bg_grad.stops_count, 2);
|
||||
for(uint8_t i = 0; i < cnt; i++) {
|
||||
col32[i].full = lv_color_to32(dsc->bg_grad.stops[i].color); /*Convert color to RGBA8888*/
|
||||
stops[i] = dsc->bg_grad.stops[i].frac;
|
||||
#if LV_COLOR_DEPTH==16
|
||||
colors[i] = ((uint32_t)col32[i].ch.alpha << 24) | ((uint32_t)col32[i].ch.blue << 16) |
|
||||
((uint32_t)col32[i].ch.green << 8) | (uint32_t)col32[i].ch.red;
|
||||
#else /*LV_COLOR_DEPTH==32*/
|
||||
/* watchout: red and blue color components are inverted versus vg_lite_color_t order */
|
||||
colors[i] = ((uint32_t)col32[i].ch.alpha << 24) | ((uint32_t)col32[i].ch.red << 16) |
|
||||
((uint32_t)col32[i].ch.green << 8) | (uint32_t)col32[i].ch.blue;
|
||||
#endif
|
||||
|
||||
vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_ABGR8888 : VG_LITE_ARGB8888;
|
||||
if(lv_vglite_premult_and_swizzle(&colors[i], col32[i], dsc->bg_opa, color_format) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Premultiplication and swizzle failed.");
|
||||
}
|
||||
|
||||
lv_memset_00(&gradient, sizeof(vg_lite_linear_gradient_t));
|
||||
@@ -181,7 +150,7 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_
|
||||
|
||||
grad_matrix = vg_lite_get_grad_matrix(&gradient);
|
||||
vg_lite_identity(grad_matrix);
|
||||
vg_lite_translate((float)rel_coords.x1, (float)rel_coords.y1, grad_matrix);
|
||||
vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix);
|
||||
|
||||
if(dsc->bg_grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_VER) {
|
||||
vg_lite_scale(1.0f, (float)height / 256.0f, grad_matrix);
|
||||
@@ -192,39 +161,26 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_
|
||||
}
|
||||
}
|
||||
|
||||
lv_opa_t bg_opa = dsc->bg_opa;
|
||||
lv_color32_t bg_col32 = {.full = lv_color_to32(dsc->bg_color)}; /*Convert color to RGBA8888*/
|
||||
if(bg_opa <= (lv_opa_t)LV_OPA_MAX) {
|
||||
/* Only pre-multiply color if hardware pre-multiplication is not present */
|
||||
if(!vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) {
|
||||
bg_col32.ch.red = (uint8_t)(((uint16_t)bg_col32.ch.red * bg_opa) >> 8);
|
||||
bg_col32.ch.green = (uint8_t)(((uint16_t)bg_col32.ch.green * bg_opa) >> 8);
|
||||
bg_col32.ch.blue = (uint8_t)(((uint16_t)bg_col32.ch.blue * bg_opa) >> 8);
|
||||
}
|
||||
bg_col32.ch.alpha = bg_opa;
|
||||
}
|
||||
vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888;
|
||||
if(lv_vglite_premult_and_swizzle(&vgcol, bg_col32, dsc->bg_opa, color_format) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Premultiplication and swizzle failed.");
|
||||
|
||||
#if LV_COLOR_DEPTH==16
|
||||
vgcol = bg_col32.full;
|
||||
#else /*LV_COLOR_DEPTH==32*/
|
||||
vgcol = ((uint32_t)bg_col32.ch.alpha << 24) | ((uint32_t)bg_col32.ch.blue << 16) |
|
||||
((uint32_t)bg_col32.ch.green << 8) | (uint32_t)bg_col32.ch.red;
|
||||
#endif
|
||||
|
||||
/*Clean & invalidate cache*/
|
||||
lv_vglite_invalidate_cache();
|
||||
lv_vglite_set_scissor(clip_area);
|
||||
|
||||
/*** Draw rectangle ***/
|
||||
if(dsc->bg_grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE) {
|
||||
err = vg_lite_draw(&vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol);
|
||||
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol);
|
||||
}
|
||||
else {
|
||||
err = vg_lite_draw_gradient(&vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, &gradient, VG_LITE_BLEND_SRC_OVER);
|
||||
err = vg_lite_draw_gradient(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, &gradient, VG_LITE_BLEND_SRC_OVER);
|
||||
}
|
||||
VG_LITE_ERR_RETURN_INV(err, "Draw gradient failed.");
|
||||
|
||||
err = vg_lite_finish();
|
||||
VG_LITE_ERR_RETURN_INV(err, "Finish failed.");
|
||||
if(lv_vglite_run() != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Run failed.");
|
||||
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
err = vg_lite_clear_path(&path);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");
|
||||
@@ -237,8 +193,267 @@ lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_border_generic(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_rect_dsc_t * dsc, bool border)
|
||||
{
|
||||
vg_lite_error_t err = VG_LITE_SUCCESS;
|
||||
vg_lite_color_t vgcol; /* vglite takes ABGR */
|
||||
lv_coord_t radius = dsc->radius;
|
||||
vg_lite_buffer_t * vgbuf = lv_vglite_get_dest_buf();
|
||||
|
||||
if(radius < 0)
|
||||
return LV_RES_INV;
|
||||
|
||||
if(border) {
|
||||
/* Draw border - only has radius if object has radius*/
|
||||
lv_coord_t border_half = (lv_coord_t)floor(dsc->border_width / 2.0f);
|
||||
if(radius > border_half)
|
||||
radius = radius - border_half;
|
||||
}
|
||||
else {
|
||||
/* Draw outline - always has radius, leave the same radius in the circle case */
|
||||
lv_coord_t outline_half = (lv_coord_t)ceil(dsc->outline_width / 2.0f);
|
||||
if(radius < (lv_coord_t)LV_RADIUS_CIRCLE - outline_half)
|
||||
radius = radius + outline_half;
|
||||
}
|
||||
|
||||
vg_lite_cap_style_t cap_style = (radius) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT;
|
||||
vg_lite_join_style_t join_style = (radius) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER;
|
||||
|
||||
/* Choose vglite blend mode based on given lvgl blend mode */
|
||||
vg_lite_blend_t vglite_blend_mode = lv_vglite_get_blend_mode(dsc->blend_mode);
|
||||
|
||||
/*** Init path ***/
|
||||
int32_t path_data[RECT_PATH_DATA_MAX_SIZE];
|
||||
uint32_t path_data_size;
|
||||
lv_vglite_create_rect_path_data(path_data, &path_data_size, radius, coords);
|
||||
vg_lite_quality_t path_quality = dsc->radius > 0 ? VG_LITE_HIGH : VG_LITE_LOW;
|
||||
|
||||
vg_lite_path_t path;
|
||||
err = vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Init path failed.");
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
lv_opa_t opa;
|
||||
lv_color32_t col32;
|
||||
lv_coord_t line_width;
|
||||
|
||||
if(border) {
|
||||
opa = dsc->border_opa;
|
||||
col32.full = lv_color_to32(dsc->border_color); /*Convert color to RGBA8888*/
|
||||
line_width = dsc->border_width;
|
||||
}
|
||||
else {
|
||||
opa = dsc->outline_opa;
|
||||
col32.full = lv_color_to32(dsc->outline_color); /*Convert color to RGBA8888*/
|
||||
line_width = dsc->outline_width;
|
||||
}
|
||||
|
||||
vg_lite_buffer_format_t color_format = LV_COLOR_DEPTH == 16 ? VG_LITE_BGRA8888 : VG_LITE_ABGR8888;
|
||||
if(lv_vglite_premult_and_swizzle(&vgcol, col32, opa, color_format) != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Premultiplication and swizzle failed.");
|
||||
|
||||
/*** Draw border ***/
|
||||
err = vg_lite_set_draw_path_type(&path, VG_LITE_DRAW_STROKE_PATH);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Set draw path type failed.");
|
||||
|
||||
err = vg_lite_set_stroke(&path, cap_style, join_style, line_width, 8, NULL, 0, 0, vgcol);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Set stroke failed.");
|
||||
|
||||
err = vg_lite_update_stroke(&path);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Update stroke failed.");
|
||||
|
||||
lv_vglite_set_scissor(clip_area);
|
||||
|
||||
err = vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, vglite_blend_mode, vgcol);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Draw border failed.");
|
||||
|
||||
if(lv_vglite_run() != LV_RES_OK)
|
||||
VG_LITE_RETURN_INV("Run failed.");
|
||||
|
||||
lv_vglite_disable_scissor();
|
||||
|
||||
err = vg_lite_clear_path(&path);
|
||||
VG_LITE_ERR_RETURN_INV(err, "Clear path failed.");
|
||||
|
||||
return LV_RES_OK;
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size,
|
||||
lv_coord_t radius,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
lv_coord_t rect_width = lv_area_get_width(coords);
|
||||
lv_coord_t rect_height = lv_area_get_height(coords);
|
||||
|
||||
/* Get the final radius. Can't be larger than the half of the shortest side */
|
||||
int32_t shortest_side = LV_MIN(rect_width, rect_height);
|
||||
int32_t final_radius = LV_MIN(radius, shortest_side / 2);
|
||||
|
||||
/* Path data element index */
|
||||
uint8_t pidx = 0;
|
||||
|
||||
if((radius == (lv_coord_t)LV_RADIUS_CIRCLE) && (rect_width == rect_height)) {
|
||||
|
||||
/* Get the control point offset for rounded cases */
|
||||
int32_t cpoff = (int32_t)((float)final_radius * BEZIER_OPTIM_CIRCLE);
|
||||
|
||||
/* Circle case */
|
||||
/* Starting point */
|
||||
path_data[pidx++] = VLC_OP_MOVE;
|
||||
path_data[pidx++] = coords->x1 + final_radius;
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Top-right arc */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = cpoff;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = final_radius - cpoff;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
|
||||
/* Bottom-right arc*/
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = cpoff;
|
||||
path_data[pidx++] = cpoff - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
|
||||
/* Bottom-left arc */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0 - cpoff;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = cpoff - final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
|
||||
/* Top-left arc*/
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = 0 - cpoff;
|
||||
path_data[pidx++] = final_radius - cpoff;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
|
||||
/* Ending point */
|
||||
path_data[pidx++] = VLC_OP_END;
|
||||
}
|
||||
else if(radius > 0) {
|
||||
/* Get the control point offset for rounded cases */
|
||||
int32_t cpoff = (int32_t)((float)final_radius * BEZIER_OPTIM_CIRCLE);
|
||||
|
||||
/* Rounded rectangle case */
|
||||
/* Starting point */
|
||||
path_data[pidx++] = VLC_OP_MOVE;
|
||||
path_data[pidx++] = coords->x1 + final_radius;
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Top side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x2 - final_radius + 1; // Extended for VGLite
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Top-right corner */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = cpoff;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = final_radius - cpoff;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
|
||||
/* Right side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x2 + 1; // Extended for VGLite
|
||||
path_data[pidx++] = coords->y2 - final_radius + 1; // Extended for VGLite
|
||||
|
||||
/* Bottom-right corner*/
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = cpoff;
|
||||
path_data[pidx++] = cpoff - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
|
||||
/* Bottom side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x1 + final_radius;
|
||||
path_data[pidx++] = coords->y2 + 1; // Extended for VGLite
|
||||
|
||||
/* Bottom-left corner */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0 - cpoff;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = cpoff - final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
|
||||
/* Left side*/
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x1;
|
||||
path_data[pidx++] = coords->y1 + final_radius;
|
||||
|
||||
/* Top-left corner */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = 0 - cpoff;
|
||||
path_data[pidx++] = final_radius - cpoff;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
|
||||
/* Ending point */
|
||||
path_data[pidx++] = VLC_OP_END;
|
||||
}
|
||||
else {
|
||||
/* Non-rounded rectangle case */
|
||||
/* Starting point */
|
||||
path_data[pidx++] = VLC_OP_MOVE;
|
||||
path_data[pidx++] = coords->x1;
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Top side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x2 + 1; // Extended for VGLite
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Right side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x2 + 1; // Extended for VGLite
|
||||
path_data[pidx++] = coords->y2 + 1; // Extended for VGLite
|
||||
|
||||
/* Bottom side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x1;
|
||||
path_data[pidx++] = coords->y2 + 1; // Extended for VGLite
|
||||
|
||||
/* Left side*/
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x1;
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Ending point */
|
||||
path_data[pidx++] = VLC_OP_END;
|
||||
}
|
||||
|
||||
/* Resulting path size */
|
||||
*path_data_size = pidx * sizeof(int32_t);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2021, 2022 NXP
|
||||
* Copyright 2021-2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -40,7 +40,7 @@ extern "C" {
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "lv_gpu_nxp_vglite.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
#include "../../lv_draw_rect.h"
|
||||
|
||||
/*********************
|
||||
@@ -56,13 +56,33 @@ extern "C" {
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw rectangle shape with effects (rounded corners, gradient)
|
||||
* Draw rectangle background with effects (rounded corners, gradient)
|
||||
*
|
||||
* @param[in] coords Coordinates of the rectangle background (relative to dest buff)
|
||||
* @param[in] clip_area Clipping area with relative coordinates to dest buff
|
||||
* @param[in] dsc Description of the rectangle background
|
||||
*
|
||||
* @retval LV_RES_OK Draw completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*
|
||||
* @param draw_ctx drawing context
|
||||
* @param dsc description of the rectangle
|
||||
* @param coords the area where rectangle is clipped
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_bg(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_rect_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Draw rectangle border/outline shape with effects (rounded corners, opacity)
|
||||
*
|
||||
* @param[in] coords Coordinates of the rectangle border/outline (relative to dest buff)
|
||||
* @param[in] clip_area Clipping area with relative coordinates to dest buff
|
||||
* @param[in] dsc Description of the rectangle border/outline
|
||||
* @param[in] border True for border, False for outline
|
||||
*
|
||||
* @retval LV_RES_OK Draw completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_draw_border_generic(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_rect_dsc_t * dsc, bool border);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* @file lv_gpu_nxp_vglite.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020-2022 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_gpu_nxp_vglite.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "../../../core/lv_refr.h"
|
||||
#if BLIT_DBG_AREAS
|
||||
#include "lv_draw_vglite_blend.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_COLOR_DEPTH==16
|
||||
#define VG_LITE_PX_FMT VG_LITE_RGB565
|
||||
#elif LV_COLOR_DEPTH==32
|
||||
#define VG_LITE_PX_FMT VG_LITE_BGRA8888
|
||||
#else
|
||||
#error Only 16bit and 32bit color depth are supported. Set LV_COLOR_DEPTH to 16 or 32.
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_res_t lv_vglite_init_buf(vg_lite_buffer_t * vgbuf, uint32_t width, uint32_t height, uint32_t stride,
|
||||
const lv_color_t * ptr, bool source)
|
||||
{
|
||||
/*Test for memory alignment*/
|
||||
if((((uintptr_t)ptr) % (uintptr_t)LV_ATTRIBUTE_MEM_ALIGN_SIZE) != (uintptr_t)0x0U)
|
||||
VG_LITE_RETURN_INV("%s buffer (0x%x) not aligned to %d.", source ? "Src" : "Dest",
|
||||
(size_t) ptr, LV_ATTRIBUTE_MEM_ALIGN_SIZE);
|
||||
|
||||
/*Test for stride alignment*/
|
||||
if(source && (stride % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * sizeof(lv_color_t))) != 0x0U)
|
||||
VG_LITE_RETURN_INV("Src buffer stride (%d bytes) not aligned to %d bytes.", stride,
|
||||
LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * sizeof(lv_color_t));
|
||||
|
||||
vgbuf->format = VG_LITE_PX_FMT;
|
||||
vgbuf->tiled = VG_LITE_LINEAR;
|
||||
vgbuf->image_mode = VG_LITE_NORMAL_IMAGE_MODE;
|
||||
vgbuf->transparency_mode = VG_LITE_IMAGE_OPAQUE;
|
||||
|
||||
vgbuf->width = (int32_t)width;
|
||||
vgbuf->height = (int32_t)height;
|
||||
vgbuf->stride = (int32_t)stride;
|
||||
|
||||
lv_memset_00(&vgbuf->yuv, sizeof(vgbuf->yuv));
|
||||
|
||||
vgbuf->memory = (void *)ptr;
|
||||
vgbuf->address = (uint32_t)vgbuf->memory;
|
||||
vgbuf->handle = NULL;
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
#if BLIT_DBG_AREAS
|
||||
void lv_vglite_dbg_draw_rectangle(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height,
|
||||
lv_area_t * fill_area, lv_color_t color)
|
||||
{
|
||||
lv_area_t a;
|
||||
|
||||
/* top line */
|
||||
a.x1 = fill_area->x1;
|
||||
a.x2 = fill_area->x2;
|
||||
a.y1 = fill_area->y1;
|
||||
a.y2 = fill_area->y1;
|
||||
lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &a, color, LV_OPA_COVER);
|
||||
|
||||
|
||||
/* bottom line */
|
||||
a.x1 = fill_area->x1;
|
||||
a.x2 = fill_area->x2;
|
||||
a.y1 = fill_area->y2;
|
||||
a.y2 = fill_area->y2;
|
||||
lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &a, color, LV_OPA_COVER);
|
||||
|
||||
/* left line */
|
||||
a.x1 = fill_area->x1;
|
||||
a.x2 = fill_area->x1;
|
||||
a.y1 = fill_area->y1;
|
||||
a.y2 = fill_area->y2;
|
||||
lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &a, color, LV_OPA_COVER);
|
||||
|
||||
/* right line */
|
||||
a.x1 = fill_area->x2;
|
||||
a.x2 = fill_area->x2;
|
||||
a.y1 = fill_area->y1;
|
||||
a.y2 = fill_area->y2;
|
||||
lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &a, color, LV_OPA_COVER);
|
||||
}
|
||||
#endif /* BLIT_DBG_AREAS */
|
||||
|
||||
void lv_vglite_invalidate_cache(void)
|
||||
{
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
if(disp->driver->clean_dcache_cb)
|
||||
disp->driver->clean_dcache_cb(disp->driver);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
141
src/draw/nxp/vglite/lv_vglite_buf.c
Normal file
141
src/draw/nxp/vglite/lv_vglite_buf.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* @file lv_vglite_buf.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_vglite_buf.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_COLOR_DEPTH == 16
|
||||
#define VG_LITE_PX_FMT VG_LITE_RGB565
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define VG_LITE_PX_FMT VG_LITE_BGRA8888
|
||||
#else
|
||||
#error Only 16bit and 32bit color depth are supported. Set LV_COLOR_DEPTH to 16 or 32.
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static inline void lv_vglite_set_dest_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride);
|
||||
static inline void lv_vglite_set_buf_ptr(vg_lite_buffer_t * vgbuf, const lv_color_t * buf);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static vg_lite_buffer_t dest_vgbuf;
|
||||
static vg_lite_buffer_t src_vgbuf;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_gpu_nxp_vglite_init_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride)
|
||||
{
|
||||
lv_vglite_set_dest_buf(buf, area, stride);
|
||||
}
|
||||
|
||||
vg_lite_buffer_t * lv_vglite_get_dest_buf(void)
|
||||
{
|
||||
return &dest_vgbuf;
|
||||
}
|
||||
|
||||
vg_lite_buffer_t * lv_vglite_get_src_buf(void)
|
||||
{
|
||||
return &src_vgbuf;
|
||||
}
|
||||
|
||||
void lv_vglite_set_dest_buf_ptr(const lv_color_t * buf)
|
||||
{
|
||||
lv_vglite_set_buf_ptr(&dest_vgbuf, buf);
|
||||
}
|
||||
|
||||
void lv_vglite_set_src_buf_ptr(const lv_color_t * buf)
|
||||
{
|
||||
lv_vglite_set_buf_ptr(&src_vgbuf, buf);
|
||||
}
|
||||
|
||||
void lv_vglite_set_src_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride)
|
||||
{
|
||||
if(src_vgbuf.memory != (void *)buf)
|
||||
lv_vglite_set_buf(&src_vgbuf, buf, area, stride);
|
||||
}
|
||||
|
||||
void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t * buf,
|
||||
const lv_area_t * area, lv_coord_t stride)
|
||||
{
|
||||
vgbuf->format = VG_LITE_PX_FMT;
|
||||
vgbuf->tiled = VG_LITE_LINEAR;
|
||||
vgbuf->image_mode = VG_LITE_NORMAL_IMAGE_MODE;
|
||||
vgbuf->transparency_mode = VG_LITE_IMAGE_OPAQUE;
|
||||
|
||||
vgbuf->width = (int32_t)lv_area_get_width(area);
|
||||
vgbuf->height = (int32_t)lv_area_get_height(area);
|
||||
vgbuf->stride = (int32_t)(stride) * sizeof(lv_color_t);
|
||||
|
||||
lv_memset_00(&vgbuf->yuv, sizeof(vgbuf->yuv));
|
||||
|
||||
vgbuf->memory = (void *)buf;
|
||||
vgbuf->address = (uint32_t)vgbuf->memory;
|
||||
vgbuf->handle = NULL;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static inline void lv_vglite_set_dest_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride)
|
||||
{
|
||||
lv_vglite_set_buf(&dest_vgbuf, buf, area, stride);
|
||||
}
|
||||
|
||||
static inline void lv_vglite_set_buf_ptr(vg_lite_buffer_t * vgbuf, const lv_color_t * buf)
|
||||
{
|
||||
vgbuf->memory = (void *)buf;
|
||||
vgbuf->address = (uint32_t)vgbuf->memory;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
124
src/draw/nxp/vglite/lv_vglite_buf.h
Normal file
124
src/draw/nxp/vglite/lv_vglite_buf.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @file lv_vglite_buf.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_VGLITE_BUF_H
|
||||
#define LV_VGLITE_BUF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "vg_lite.h"
|
||||
#include "../../sw/lv_draw_sw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
/**
|
||||
* Init vglite destination buffer. It will be done once per frame.
|
||||
*
|
||||
* @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode)
|
||||
* @param[in] area Destination buffer area (for width and height)
|
||||
* @param[in] stride Stride of destination buffer
|
||||
*/
|
||||
void lv_gpu_nxp_vglite_init_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride);
|
||||
|
||||
/**
|
||||
* Get vglite destination buffer pointer.
|
||||
*
|
||||
* @retval The vglite destination buffer
|
||||
*/
|
||||
vg_lite_buffer_t * lv_vglite_get_dest_buf(void);
|
||||
|
||||
/**
|
||||
* Get vglite source buffer pointer.
|
||||
*
|
||||
* @retval The vglite source buffer
|
||||
*/
|
||||
vg_lite_buffer_t * lv_vglite_get_src_buf(void);
|
||||
|
||||
/**
|
||||
* Set vglite destination buffer address only.
|
||||
*
|
||||
* @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode)
|
||||
*/
|
||||
void lv_vglite_set_dest_buf_ptr(const lv_color_t * buf);
|
||||
|
||||
/**
|
||||
* Set vglite source buffer address only.
|
||||
*
|
||||
* @param[in] buf Source buffer address
|
||||
*/
|
||||
void lv_vglite_set_src_buf_ptr(const lv_color_t * buf);
|
||||
|
||||
/**
|
||||
* Set vglite source buffer. It will be done only if buffer addreess is different.
|
||||
*
|
||||
* @param[in] buf Source buffer address
|
||||
* @param[in] area Source buffer area (for width and height)
|
||||
* @param[in] stride Stride of source buffer
|
||||
*/
|
||||
void lv_vglite_set_src_buf(const lv_color_t * buf, const lv_area_t * area, lv_coord_t stride);
|
||||
|
||||
/**
|
||||
* Set vglite buffer.
|
||||
*
|
||||
* @param[in] vgbuf Address of the VGLite buffer object
|
||||
* @param[in] buf Address of the memory for the VGLite buffer
|
||||
* @param[in] area buffer area (for width and height)
|
||||
* @param[in] stride buffer stride
|
||||
*/
|
||||
void lv_vglite_set_buf(vg_lite_buffer_t * vgbuf, const lv_color_t * buf,
|
||||
const lv_area_t * area, lv_coord_t stride);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VGLITE_BUF_H*/
|
||||
149
src/draw/nxp/vglite/lv_vglite_utils.c
Normal file
149
src/draw/nxp/vglite/lv_vglite_utils.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* @file lv_vglite_utils.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next paragraph)
|
||||
* shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "../../../core/lv_refr.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Clean and invalidate cache.
|
||||
*/
|
||||
static inline void invalidate_cache(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_res_t lv_vglite_run(void)
|
||||
{
|
||||
invalidate_cache();
|
||||
|
||||
VG_LITE_ERR_RETURN_INV(vg_lite_flush(), "Flush failed.");
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
lv_res_t lv_vglite_premult_and_swizzle(vg_lite_color_t * vg_col32, lv_color32_t lv_col32, lv_opa_t opa,
|
||||
vg_lite_buffer_format_t vg_col_format)
|
||||
{
|
||||
|
||||
lv_color32_t lv_col32_premul = lv_col32;
|
||||
if(opa <= (lv_opa_t)LV_OPA_MAX) {
|
||||
/* Only pre-multiply color if hardware pre-multiplication is not present */
|
||||
if(!vg_lite_query_feature(gcFEATURE_BIT_VG_PE_PREMULTIPLY)) {
|
||||
lv_col32_premul.ch.red = (uint8_t)(((uint16_t)lv_col32.ch.red * opa) >> 8);
|
||||
lv_col32_premul.ch.green = (uint8_t)(((uint16_t)lv_col32.ch.green * opa) >> 8);
|
||||
lv_col32_premul.ch.blue = (uint8_t)(((uint16_t)lv_col32.ch.blue * opa) >> 8);
|
||||
}
|
||||
lv_col32_premul.ch.alpha = opa;
|
||||
}
|
||||
|
||||
switch(vg_col_format) {
|
||||
case VG_LITE_BGRA8888:
|
||||
*vg_col32 = lv_col32_premul.full;
|
||||
break;
|
||||
case VG_LITE_RGBA8888:
|
||||
*vg_col32 = ((uint32_t)lv_col32_premul.ch.red << 24) | ((uint32_t)lv_col32_premul.ch.green << 16) |
|
||||
((uint32_t)lv_col32_premul.ch.blue << 8) | (uint32_t)lv_col32_premul.ch.alpha;
|
||||
break;
|
||||
case VG_LITE_ABGR8888:
|
||||
*vg_col32 = ((uint32_t)lv_col32_premul.ch.alpha << 24) | ((uint32_t)lv_col32_premul.ch.blue << 16) |
|
||||
((uint32_t)lv_col32_premul.ch.green << 8) | (uint32_t)lv_col32_premul.ch.red;
|
||||
break;
|
||||
case VG_LITE_ARGB8888:
|
||||
*vg_col32 = ((uint32_t)lv_col32_premul.ch.alpha << 24) | ((uint32_t)lv_col32_premul.ch.red << 16) |
|
||||
((uint32_t)lv_col32_premul.ch.green << 8) | (uint32_t)lv_col32_premul.ch.blue;
|
||||
break;
|
||||
default:
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
vg_lite_blend_t lv_vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode)
|
||||
{
|
||||
vg_lite_blend_t vg_blend_mode;
|
||||
switch(lv_blend_mode) {
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
vg_blend_mode = VG_LITE_BLEND_ADDITIVE;
|
||||
break;
|
||||
case LV_BLEND_MODE_SUBTRACTIVE:
|
||||
vg_blend_mode = VG_LITE_BLEND_SUBTRACT;
|
||||
break;
|
||||
case LV_BLEND_MODE_MULTIPLY:
|
||||
vg_blend_mode = VG_LITE_BLEND_MULTIPLY;
|
||||
break;
|
||||
case LV_BLEND_MODE_REPLACE:
|
||||
vg_blend_mode = VG_LITE_BLEND_NONE;
|
||||
break;
|
||||
default:
|
||||
vg_blend_mode = VG_LITE_BLEND_SRC_OVER;
|
||||
break;
|
||||
}
|
||||
return vg_blend_mode;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static inline void invalidate_cache(void)
|
||||
{
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
if(disp->driver->clean_dcache_cb)
|
||||
disp->driver->clean_dcache_cb(disp->driver);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* @file lv_gpu_nxp_vglite.h
|
||||
* @file lv_vglite_utils.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright 2020-2022 NXP
|
||||
* Copyright 2022, 2023 NXP
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -27,8 +27,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GPU_NXP_VGLITE_H
|
||||
#define LV_GPU_NXP_VGLITE_H
|
||||
#ifndef LV_VGLITE_UTILS_H
|
||||
#define LV_VGLITE_UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -43,40 +43,21 @@ extern "C" {
|
||||
#include "vg_lite.h"
|
||||
#include "../../sw/lv_draw_sw.h"
|
||||
#include "../../../misc/lv_log.h"
|
||||
#include "fsl_debug_console.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/** Use this symbol as limit to disable feature (value has to be larger than supported resolution) */
|
||||
#define LV_GPU_NXP_VG_LITE_FEATURE_DISABLED (1920*1080+1)
|
||||
|
||||
/** Stride in px required by VG-Lite HW. Don't change this. */
|
||||
#define LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX 16U
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
/** Enable logging of VG-Lite errors (\see LV_LOG_ERROR)*/
|
||||
#define LV_GPU_NXP_VG_LITE_LOG_ERRORS 1
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_LOG_TRACES
|
||||
/** Enable logging of VG-Lite errors (\see LV_LOG_ERROR)*/
|
||||
/** Enable logging of VG-Lite traces (\see LV_LOG_ERROR)*/
|
||||
#define LV_GPU_NXP_VG_LITE_LOG_TRACES 0
|
||||
#endif
|
||||
|
||||
/* Draw rectangles around BLIT tiles */
|
||||
#define BLIT_DBG_AREAS 0
|
||||
|
||||
/* Print detailed info to SDK console (NOT to LVGL log system) */
|
||||
#define BLIT_DBG_VERBOSE 0
|
||||
|
||||
/* Verbose debug print */
|
||||
#if BLIT_DBG_VERBOSE
|
||||
#define PRINT_BLT PRINTF
|
||||
#else
|
||||
#define PRINT_BLT(...)
|
||||
#endif
|
||||
|
||||
/* The optimal Bezier control point offset for radial unit
|
||||
* see: https://spencermortensen.com/articles/bezier-circle/
|
||||
@@ -90,41 +71,57 @@ extern "C" {
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Enable scissor and set the clipping box.
|
||||
*
|
||||
* @param[in] clip_area Clip area with relative coordinates of destination buffer
|
||||
*/
|
||||
static inline void lv_vglite_set_scissor(const lv_area_t * clip_area);
|
||||
|
||||
/**
|
||||
* Disable scissor.
|
||||
*/
|
||||
static inline void lv_vglite_disable_scissor(void);
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Fills vg_lite_buffer_t structure according given parameters.
|
||||
* Premultiplies and swizzles given LVGL 32bit color to obtain vglite color.
|
||||
*
|
||||
* @param[in/out] vgbuf Buffer structure to be filled
|
||||
* @param[in] width Width of buffer in pixels
|
||||
* @param[in] height Height of buffer in pixels
|
||||
* @param[in] stride Stride of the buffer in bytes
|
||||
* @param[in] ptr Pointer to the buffer (must be aligned according VG-Lite requirements)
|
||||
* @param[in] source Boolean to check if this is a source buffer
|
||||
*/
|
||||
lv_res_t lv_vglite_init_buf(vg_lite_buffer_t * vgbuf, uint32_t width, uint32_t height, uint32_t stride,
|
||||
const lv_color_t * ptr, bool source);
|
||||
|
||||
#if BLIT_DBG_AREAS
|
||||
/**
|
||||
* Draw a simple rectangle, 1 px line width.
|
||||
* @param[in/out] vg_col32 The obtained vglite color
|
||||
* @param[in] lv_col32 The initial LVGL 32bit color
|
||||
* @param[in] opa The opacity to premultiply with
|
||||
* @param[in] vg_col_format The format of the resulting vglite color
|
||||
*
|
||||
* @param dest_buf Destination buffer
|
||||
* @param dest_width Destination buffer width (must be aligned on 16px)
|
||||
* @param dest_height Destination buffer height
|
||||
* @param fill_area Rectangle coordinates
|
||||
* @param color Rectangle color
|
||||
* @retval LV_RES_OK Operation completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
void lv_vglite_dbg_draw_rectangle(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height,
|
||||
lv_area_t * fill_area, lv_color_t color);
|
||||
#endif
|
||||
lv_res_t lv_vglite_premult_and_swizzle(vg_lite_color_t * vg_col32, lv_color32_t lv_col32, lv_opa_t opa,
|
||||
vg_lite_buffer_format_t vg_col_format);
|
||||
|
||||
/**
|
||||
* Clean & invalidate cache.
|
||||
* Get vglite blend mode.
|
||||
*
|
||||
* @param[in] lv_blend_mode The LVGL blend mode
|
||||
*
|
||||
* @retval The vglite blend mode
|
||||
*/
|
||||
void lv_vglite_invalidate_cache(void);
|
||||
vg_lite_blend_t lv_vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode);
|
||||
|
||||
/**
|
||||
* Clear cache and flush command to VG-Lite.
|
||||
*
|
||||
* @retval LV_RES_OK Run completed
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_vglite_run(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -142,7 +139,8 @@ void lv_vglite_invalidate_cache(void);
|
||||
#define VG_LITE_ERR_RETURN_INV(err, fmt, ...) \
|
||||
do { \
|
||||
if(err != VG_LITE_SUCCESS) { \
|
||||
LV_LOG_ERROR(fmt, ##__VA_ARGS__); \
|
||||
LV_LOG_ERROR(fmt" (err = %d)", \
|
||||
err, ##__VA_ARGS__); \
|
||||
return LV_RES_INV; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -158,7 +156,7 @@ void lv_vglite_invalidate_cache(void);
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_TRACES
|
||||
#define VG_LITE_LOG_TRACE(fmt, ...) \
|
||||
do { \
|
||||
LV_LOG_ERROR(fmt, ##__VA_ARGS__); \
|
||||
LV_LOG(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define VG_LITE_RETURN_INV(fmt, ...) \
|
||||
@@ -176,10 +174,27 @@ void lv_vglite_invalidate_cache(void);
|
||||
}while(0)
|
||||
#endif /*LV_GPU_NXP_VG_LITE_LOG_TRACES*/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static inline void lv_vglite_set_scissor(const lv_area_t * clip_area)
|
||||
{
|
||||
vg_lite_enable_scissor();
|
||||
vg_lite_set_scissor((int32_t)clip_area->x1, (int32_t)clip_area->y1,
|
||||
(int32_t)lv_area_get_width(clip_area),
|
||||
(int32_t)lv_area_get_height(clip_area));
|
||||
}
|
||||
|
||||
static inline void lv_vglite_disable_scissor(void)
|
||||
{
|
||||
vg_lite_disable_scissor();
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_GPU_NXP_VGLITE_H*/
|
||||
#endif /*LV_VGLITE_UTILS_H*/
|
||||
7
src/draw/renesas/lv_draw_renesas.mk
Normal file
7
src/draw/renesas/lv_draw_renesas.mk
Normal file
@@ -0,0 +1,7 @@
|
||||
CSRCS += lv_gpu_d2_ra6m3.c
|
||||
CSRCS += lv_gpu_d2_draw_label.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/renesas
|
||||
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/renesas
|
||||
|
||||
CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/renesas"
|
||||
292
src/draw/renesas/lv_gpu_d2_draw_label.c
Normal file
292
src/draw/renesas/lv_gpu_d2_draw_label.c
Normal file
@@ -0,0 +1,292 @@
|
||||
/**
|
||||
* @file lv_gpu_d2_draw_label.c
|
||||
*
|
||||
* @description HAL layer for display driver
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../draw/lv_draw_label.h"
|
||||
#include "../../misc/lv_assert.h"
|
||||
#include "../../core/lv_refr.h"
|
||||
#include "lv_gpu_d2_ra6m3.h"
|
||||
|
||||
#if LV_USE_GPU_RA6M3_G2D
|
||||
#include LV_GPU_RA6M3_G2D_INCLUDE
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
extern const uint8_t _lv_bpp1_opa_table[2];
|
||||
extern const uint8_t _lv_bpp2_opa_table[4];
|
||||
extern const uint8_t _lv_bpp4_opa_table[16];
|
||||
extern const uint8_t _lv_bpp8_opa_table[256];
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_point_t * pos, lv_font_glyph_dsc_t * g, const uint8_t * map_p)
|
||||
{
|
||||
|
||||
const uint8_t * bpp_opa_table_p;
|
||||
uint32_t bitmask_init;
|
||||
uint32_t bitmask;
|
||||
uint32_t bpp = g->bpp;
|
||||
lv_opa_t opa = dsc->opa;
|
||||
uint32_t shades;
|
||||
if(bpp == 3) bpp = 4;
|
||||
|
||||
#if LV_USE_IMGFONT
|
||||
if(bpp == LV_IMGFONT_BPP) { //is imgfont
|
||||
lv_area_t fill_area;
|
||||
fill_area.x1 = pos->x;
|
||||
fill_area.y1 = pos->y;
|
||||
fill_area.x2 = pos->x + g->box_w - 1;
|
||||
fill_area.y2 = pos->y + g->box_h - 1;
|
||||
lv_draw_img_dsc_t img_dsc;
|
||||
lv_draw_img_dsc_init(&img_dsc);
|
||||
img_dsc.angle = 0;
|
||||
img_dsc.zoom = LV_IMG_ZOOM_NONE;
|
||||
img_dsc.opa = dsc->opa;
|
||||
img_dsc.blend_mode = dsc->blend_mode;
|
||||
lv_draw_img(draw_ctx, &img_dsc, &fill_area, map_p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
bpp_opa_table_p = _lv_bpp1_opa_table;
|
||||
bitmask_init = 0x80;
|
||||
shades = 2;
|
||||
break;
|
||||
case 2:
|
||||
bpp_opa_table_p = _lv_bpp2_opa_table;
|
||||
bitmask_init = 0xC0;
|
||||
shades = 4;
|
||||
break;
|
||||
case 4:
|
||||
bpp_opa_table_p = _lv_bpp4_opa_table;
|
||||
bitmask_init = 0xF0;
|
||||
shades = 16;
|
||||
break;
|
||||
case 8:
|
||||
bpp_opa_table_p = _lv_bpp8_opa_table;
|
||||
bitmask_init = 0xFF;
|
||||
shades = 256;
|
||||
break; /*No opa table, pixel value will be used directly*/
|
||||
default:
|
||||
LV_LOG_WARN("lv_draw_letter: invalid bpp");
|
||||
return; /*Invalid bpp. Can't render the letter*/
|
||||
}
|
||||
|
||||
static lv_opa_t opa_table[256];
|
||||
static lv_opa_t prev_opa = LV_OPA_TRANSP;
|
||||
static uint32_t prev_bpp = 0;
|
||||
if(opa < LV_OPA_MAX) {
|
||||
if(prev_opa != opa || prev_bpp != bpp) {
|
||||
uint32_t i;
|
||||
for(i = 0; i < shades; i++) {
|
||||
opa_table[i] = bpp_opa_table_p[i] == LV_OPA_COVER ? opa : ((bpp_opa_table_p[i] * opa) >> 8);
|
||||
}
|
||||
}
|
||||
bpp_opa_table_p = opa_table;
|
||||
prev_opa = opa;
|
||||
prev_bpp = bpp;
|
||||
}
|
||||
|
||||
int32_t col, row;
|
||||
int32_t box_w = g->box_w;
|
||||
int32_t box_h = g->box_h;
|
||||
int32_t width_bit = box_w * bpp; /*Letter width in bits*/
|
||||
|
||||
/*Calculate the col/row start/end on the map*/
|
||||
int32_t col_start = pos->x >= draw_ctx->clip_area->x1 ? 0 : draw_ctx->clip_area->x1 - pos->x;
|
||||
int32_t col_end = pos->x + box_w <= draw_ctx->clip_area->x2 ? box_w : draw_ctx->clip_area->x2 - pos->x + 1;
|
||||
int32_t row_start = pos->y >= draw_ctx->clip_area->y1 ? 0 : draw_ctx->clip_area->y1 - pos->y;
|
||||
int32_t row_end = pos->y + box_h <= draw_ctx->clip_area->y2 ? box_h : draw_ctx->clip_area->y2 - pos->y + 1;
|
||||
|
||||
/*Move on the map too*/
|
||||
uint32_t bit_ofs = (row_start * width_bit) + (col_start * bpp);
|
||||
map_p += bit_ofs >> 3;
|
||||
|
||||
uint8_t letter_px;
|
||||
uint32_t col_bit;
|
||||
col_bit = bit_ofs & 0x7; /*"& 0x7" equals to "% 8" just faster*/
|
||||
|
||||
lv_draw_sw_blend_dsc_t blend_dsc;
|
||||
lv_memset_00(&blend_dsc, sizeof(blend_dsc));
|
||||
blend_dsc.color = dsc->color;
|
||||
blend_dsc.opa = LV_OPA_COVER;
|
||||
blend_dsc.blend_mode = dsc->blend_mode;
|
||||
|
||||
lv_coord_t hor_res = lv_disp_get_hor_res(_lv_refr_get_disp_refreshing());
|
||||
uint32_t mask_buf_size = box_w * box_h > hor_res ? hor_res : box_w * box_h;
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
|
||||
blend_dsc.mask_buf = mask_buf;
|
||||
int32_t mask_p = 0;
|
||||
|
||||
lv_area_t fill_area;
|
||||
fill_area.x1 = col_start + pos->x;
|
||||
fill_area.x2 = col_end + pos->x - 1;
|
||||
fill_area.y1 = row_start + pos->y;
|
||||
fill_area.y2 = fill_area.y1;
|
||||
#if LV_DRAW_COMPLEX
|
||||
lv_coord_t fill_w = lv_area_get_width(&fill_area);
|
||||
lv_area_t mask_area;
|
||||
lv_area_copy(&mask_area, &fill_area);
|
||||
mask_area.y2 = mask_area.y1 + row_end;
|
||||
bool mask_any = lv_draw_mask_is_any(&mask_area);
|
||||
#endif
|
||||
blend_dsc.blend_area = &fill_area;
|
||||
blend_dsc.mask_area = &fill_area;
|
||||
|
||||
uint32_t col_bit_max = 8 - bpp;
|
||||
uint32_t col_bit_row_ofs = (box_w + col_start - col_end) * bpp;
|
||||
|
||||
for(row = row_start ; row < row_end; row++) {
|
||||
#if LV_DRAW_COMPLEX
|
||||
int32_t mask_p_start = mask_p;
|
||||
#endif
|
||||
bitmask = bitmask_init >> col_bit;
|
||||
for(col = col_start; col < col_end; col++) {
|
||||
/*Load the pixel's opacity into the mask*/
|
||||
letter_px = (*map_p & bitmask) >> (col_bit_max - col_bit);
|
||||
if(letter_px) {
|
||||
mask_buf[mask_p] = bpp_opa_table_p[letter_px];
|
||||
}
|
||||
else {
|
||||
mask_buf[mask_p] = 0;
|
||||
}
|
||||
|
||||
/*Go to the next column*/
|
||||
if(col_bit < col_bit_max) {
|
||||
col_bit += bpp;
|
||||
bitmask = bitmask >> bpp;
|
||||
}
|
||||
else {
|
||||
col_bit = 0;
|
||||
bitmask = bitmask_init;
|
||||
map_p++;
|
||||
}
|
||||
|
||||
/*Next mask byte*/
|
||||
mask_p++;
|
||||
}
|
||||
|
||||
#if LV_DRAW_COMPLEX
|
||||
/*Apply masks if any*/
|
||||
if(mask_any) {
|
||||
blend_dsc.mask_res = lv_draw_mask_apply(mask_buf + mask_p_start, fill_area.x1, fill_area.y2,
|
||||
fill_w);
|
||||
if(blend_dsc.mask_res == LV_DRAW_MASK_RES_TRANSP) {
|
||||
lv_memset_00(mask_buf + mask_p_start, fill_w);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if((uint32_t) mask_p + (col_end - col_start) < mask_buf_size) {
|
||||
fill_area.y2 ++;
|
||||
}
|
||||
else {
|
||||
blend_dsc.mask_res = LV_DRAW_MASK_RES_CHANGED;
|
||||
lv_draw_ra6m3_2d_blend(draw_ctx, &blend_dsc);
|
||||
|
||||
fill_area.y1 = fill_area.y2 + 1;
|
||||
fill_area.y2 = fill_area.y1;
|
||||
mask_p = 0;
|
||||
}
|
||||
|
||||
col_bit += col_bit_row_ofs;
|
||||
map_p += (col_bit >> 3);
|
||||
col_bit = col_bit & 0x7;
|
||||
}
|
||||
|
||||
/*Flush the last part*/
|
||||
if(fill_area.y1 != fill_area.y2) {
|
||||
fill_area.y2--;
|
||||
blend_dsc.mask_res = LV_DRAW_MASK_RES_CHANGED;
|
||||
lv_draw_ra6m3_2d_blend(draw_ctx, &blend_dsc);
|
||||
mask_p = 0;
|
||||
}
|
||||
|
||||
lv_mem_buf_release(mask_buf);
|
||||
}
|
||||
|
||||
void lv_draw_gpu_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p,
|
||||
uint32_t letter)
|
||||
{
|
||||
const lv_font_t * font_p = dsc->font;
|
||||
|
||||
lv_opa_t opa = dsc->opa;
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
if(font_p == NULL) {
|
||||
LV_LOG_WARN("lv_draw_letter: font is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_font_glyph_dsc_t g;
|
||||
bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0');
|
||||
if(g_ret == false) {
|
||||
/*Add warning if the dsc is not found
|
||||
*but do not print warning for non printable ASCII chars (e.g. '\n')*/
|
||||
if(letter >= 0x20 &&
|
||||
letter != 0xf8ff && /*LV_SYMBOL_DUMMY*/
|
||||
letter != 0x200c) { /*ZERO WIDTH NON-JOINER*/
|
||||
LV_LOG_WARN("lv_draw_letter: glyph dsc. not found for U+%X", letter);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*Don't draw anything if the character is empty. E.g. space*/
|
||||
if((g.box_h == 0) || (g.box_w == 0)) return;
|
||||
|
||||
lv_point_t gpos;
|
||||
gpos.x = pos_p->x + g.ofs_x;
|
||||
gpos.y = pos_p->y + (dsc->font->line_height - dsc->font->base_line) - g.box_h - g.ofs_y;
|
||||
|
||||
/*If the letter is completely out of mask don't draw it*/
|
||||
if(gpos.x + g.box_w < draw_ctx->clip_area->x1 ||
|
||||
gpos.x > draw_ctx->clip_area->x2 ||
|
||||
gpos.y + g.box_h < draw_ctx->clip_area->y1 ||
|
||||
gpos.y > draw_ctx->clip_area->y2) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t * map_p = lv_font_get_glyph_bitmap(font_p, letter);
|
||||
if(map_p == NULL) {
|
||||
LV_LOG_WARN("lv_draw_letter: character's bitmap not found");
|
||||
return;
|
||||
}
|
||||
|
||||
if(font_p->subpx) {
|
||||
#if LV_DRAW_COMPLEX && LV_USE_FONT_SUBPX
|
||||
draw_letter_subpx(pos_x, pos_y, &g, clip_area, map_p, color, opa, blend_mode);
|
||||
#else
|
||||
LV_LOG_WARN("Can't draw sub-pixel rendered letter because LV_USE_FONT_SUBPX == 0 in lv_conf.h");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
draw_letter_normal(draw_ctx, dsc, &gpos, &g, map_p);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
742
src/draw/renesas/lv_gpu_d2_ra6m3.c
Normal file
742
src/draw/renesas/lv_gpu_d2_ra6m3.c
Normal file
@@ -0,0 +1,742 @@
|
||||
/**
|
||||
* @file lv_gpu_d2_ra6m3.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_gpu_d2_ra6m3.h"
|
||||
#include "../../core/lv_refr.h"
|
||||
#include <math.h>
|
||||
|
||||
#if LV_USE_GPU_RA6M3_G2D
|
||||
|
||||
#include LV_GPU_RA6M3_G2D_INCLUDE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LOG_ERRORS
|
||||
#ifdef LOG_ERRORS
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
#define ERROR_LIST_SIZE (4)
|
||||
#define D2_EXEC(a) lv_port_gpu_log_error(a, __func__, __LINE__)
|
||||
#else
|
||||
/* here is error logging not enabled */
|
||||
#define D2_EXEC(a) a;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
d2_s32 error;
|
||||
const char * func;
|
||||
int line;
|
||||
} log_error_entry;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
#ifdef LOG_ERRORS
|
||||
static void lv_port_gpu_log_error(d2_s32 status, const char * func, int line);
|
||||
#endif
|
||||
static void invalidate_cache(void);
|
||||
|
||||
void lv_draw_gpu_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p,
|
||||
uint32_t letter);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
#ifdef LOG_ERRORS
|
||||
static log_error_entry log_error_list[ERROR_LIST_SIZE];
|
||||
static int error_list_index;
|
||||
static int error_count;
|
||||
#endif
|
||||
|
||||
static d2_device * _d2_handle;
|
||||
static d2_renderbuffer * renderbuffer;
|
||||
|
||||
static d2_s32 src_cf_val, dst_cf_val;
|
||||
static lv_draw_img_dsc_t img_dsc;
|
||||
static bool color_key_enabled, alpha_enabled, blend_enabled, colorize_enabled;
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static d2_s32 lv_port_gpu_cf_lv_to_d2(lv_img_cf_t cf)
|
||||
{
|
||||
d2_s32 d2_cf;
|
||||
|
||||
#if (DLG_LVGL_CF == 1)
|
||||
switch(cf & ~(1 << 5)) {
|
||||
#else
|
||||
switch(cf) {
|
||||
#endif /* (DLG_LVGL_CF == 1) */
|
||||
case LV_IMG_CF_TRUE_COLOR:
|
||||
d2_cf = d2_mode_rgb565;
|
||||
break;
|
||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:
|
||||
d2_cf = d2_mode_rgb565;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
d2_cf = d2_mode_alpha1;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
d2_cf = d2_mode_alpha2;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
d2_cf = d2_mode_alpha4;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
d2_cf = d2_mode_alpha8;
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
d2_cf = d2_mode_i1 | d2_mode_clut;
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
d2_cf = d2_mode_i2 | d2_mode_clut;
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
d2_cf = d2_mode_i4 | d2_mode_clut;
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
d2_cf = d2_mode_i8 | d2_mode_clut;
|
||||
break;
|
||||
#if (DLG_LVGL_CF == 1)
|
||||
case LV_IMG_CF_RGB565:
|
||||
d2_cf = d2_mode_rgb565;
|
||||
break;
|
||||
case LV_IMG_CF_RGB888:
|
||||
d2_cf = d2_mode_rgb888;
|
||||
break;
|
||||
case LV_IMG_CF_RGBA8888:
|
||||
d2_cf = d2_mode_rgba8888;
|
||||
break;
|
||||
#endif /* DLG_LVGL_CF */
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if (DLG_LVGL_CF == 1)
|
||||
return d2_cf | (cf & (1 << 5) ? d2_mode_rle : 0);
|
||||
#else
|
||||
return d2_cf;
|
||||
#endif /* (DLG_LVGL_CF == 1) */
|
||||
}
|
||||
|
||||
static bool lv_port_gpu_cf_fb_valid(d2_s32 cf)
|
||||
{
|
||||
if((cf & (d2_mode_rle | d2_mode_clut)) || cf < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(cf) {
|
||||
case d2_mode_alpha8:
|
||||
case d2_mode_rgb565:
|
||||
case d2_mode_argb8888:
|
||||
case d2_mode_argb4444:
|
||||
case d2_mode_rgba8888:
|
||||
case d2_mode_rgba4444:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool lv_port_gpu_cf_has_alpha(d2_s32 cf)
|
||||
{
|
||||
switch(cf & ~(d2_mode_clut | d2_mode_rle)) {
|
||||
case d2_mode_argb8888:
|
||||
case d2_mode_rgba8888:
|
||||
case d2_mode_argb4444:
|
||||
case d2_mode_rgba4444:
|
||||
case d2_mode_argb1555:
|
||||
case d2_mode_rgba5551:
|
||||
case d2_mode_ai44:
|
||||
case d2_mode_i8:
|
||||
case d2_mode_i4:
|
||||
case d2_mode_i2:
|
||||
case d2_mode_i1:
|
||||
case d2_mode_alpha8:
|
||||
case d2_mode_alpha4:
|
||||
case d2_mode_alpha2:
|
||||
case d2_mode_alpha1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool lv_port_gpu_cf_is_alpha(d2_s32 cf)
|
||||
{
|
||||
switch(cf & ~d2_mode_rle) {
|
||||
case d2_mode_alpha8:
|
||||
case d2_mode_alpha4:
|
||||
case d2_mode_alpha2:
|
||||
case d2_mode_alpha1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static d2_color lv_port_gpu_color_lv_to_d2(lv_color_t color)
|
||||
{
|
||||
uint8_t alpha, red, green, blue;
|
||||
|
||||
alpha = 0xFF;
|
||||
red = color.ch.red << 3 | color.ch.red >> 2;
|
||||
green = color.ch.green << 2 | color.ch.green >> 4;
|
||||
blue = color.ch.blue << 3 | color.ch.blue >> 2;
|
||||
|
||||
return (alpha) << 24UL
|
||||
| (red) << 16UL
|
||||
| (green) << 8UL
|
||||
| (blue) << 0UL;
|
||||
}
|
||||
|
||||
static void lv_port_gpu_get_recolor_consts(d2_color * cl, d2_color * ch)
|
||||
{
|
||||
d2_color c = lv_port_gpu_color_lv_to_d2(img_dsc.recolor);
|
||||
d2_alpha r, g, b, opa = img_dsc.recolor_opa > LV_OPA_MAX ? LV_OPA_COVER : img_dsc.recolor_opa;
|
||||
|
||||
r = ((uint32_t)((uint8_t)(c >> 16UL)) * opa) / 255;
|
||||
g = ((uint32_t)((uint8_t)(c >> 8UL)) * opa) / 255;
|
||||
b = ((uint32_t)((uint8_t)(c >> 0UL)) * opa) / 255;
|
||||
*cl = r << 16UL | g << 8UL | b << 0UL;
|
||||
|
||||
r += 255 - opa;
|
||||
g += 255 - opa;
|
||||
b += 255 - opa;
|
||||
*ch = r << 16UL | g << 8UL | b << 0UL;
|
||||
}
|
||||
|
||||
static int lv_port_gpu_handle_indexed_color(const lv_color_t ** src, const d2_color ** clut, d2_s32 cf)
|
||||
{
|
||||
int clut_len = 0;
|
||||
|
||||
if(cf & d2_mode_clut) {
|
||||
/* Calculate CLUT length in entries */
|
||||
switch(cf & ~(d2_mode_clut | d2_mode_rle)) {
|
||||
case d2_mode_i1:
|
||||
clut_len = 2;
|
||||
break;
|
||||
case d2_mode_i2:
|
||||
clut_len = 4;
|
||||
break;
|
||||
case d2_mode_i4:
|
||||
clut_len = 16;
|
||||
break;
|
||||
case d2_mode_i8:
|
||||
clut_len = 256;
|
||||
break;
|
||||
case d2_mode_ai44:
|
||||
clut_len = 16;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
*clut = (const d2_color *)*src;
|
||||
*src = (const lv_color_t *)((const uint32_t *)*src + clut_len);
|
||||
}
|
||||
return clut_len;
|
||||
}
|
||||
|
||||
static int lv_port_gpu_cf_bpp(d2_s32 cf)
|
||||
{
|
||||
switch(cf & ~(d2_mode_clut | d2_mode_rle)) {
|
||||
case d2_mode_argb8888:
|
||||
return 32;
|
||||
case d2_mode_rgba8888:
|
||||
return 32;
|
||||
case d2_mode_rgb888:
|
||||
return 32;
|
||||
case d2_mode_argb4444:
|
||||
return 16;
|
||||
case d2_mode_rgba4444:
|
||||
return 16;
|
||||
case d2_mode_argb1555:
|
||||
return 16;
|
||||
case d2_mode_rgba5551:
|
||||
return 16;
|
||||
case d2_mode_rgb565:
|
||||
return 16;
|
||||
case d2_mode_ai44:
|
||||
return 8;
|
||||
case d2_mode_i8:
|
||||
return 8;
|
||||
case d2_mode_i4:
|
||||
return 4;
|
||||
case d2_mode_i2:
|
||||
return 2;
|
||||
case d2_mode_i1:
|
||||
return 1;
|
||||
case d2_mode_alpha8:
|
||||
return 8;
|
||||
case d2_mode_alpha4:
|
||||
return 4;
|
||||
case d2_mode_alpha2:
|
||||
return 2;
|
||||
case d2_mode_alpha1:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static d2_s32 lv_port_gpu_cf_get_default(void)
|
||||
{
|
||||
return d2_mode_rgb565;
|
||||
}
|
||||
|
||||
static void lv_port_gpu_config_blit_clear(void)
|
||||
{
|
||||
alpha_enabled = false;
|
||||
color_key_enabled = false;
|
||||
blend_enabled = true;
|
||||
colorize_enabled = false;
|
||||
|
||||
lv_draw_img_dsc_init(&img_dsc);
|
||||
|
||||
src_cf_val = lv_port_gpu_cf_get_default();
|
||||
dst_cf_val = lv_port_gpu_cf_get_default();
|
||||
}
|
||||
|
||||
void lv_port_gpu_init(void)
|
||||
{
|
||||
lv_port_gpu_config_blit_clear();
|
||||
}
|
||||
|
||||
static void lv_port_gpu_rotate_point(int * x, int * y, float cos_angle, float sin_angle, int pivot_x, int pivot_y)
|
||||
{
|
||||
float fx, fy;
|
||||
|
||||
*x -= pivot_x;
|
||||
*y -= pivot_y;
|
||||
|
||||
fx = ((float) * x) / 16.0f;
|
||||
fy = ((float) * y) / 16.0f;
|
||||
|
||||
*x = (int)(((fx * cos_angle) - (fy * sin_angle)) * 16.0f);
|
||||
*y = (int)(((fx * sin_angle) + (fy * cos_angle)) * 16.0f);
|
||||
|
||||
*x += pivot_x;
|
||||
*y += pivot_y;
|
||||
}
|
||||
|
||||
void lv_draw_ra6m3_g2d_init(void)
|
||||
{
|
||||
if(_d2_handle != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_d2_handle = d2_opendevice(0);
|
||||
|
||||
if(_d2_handle == NULL)
|
||||
return;
|
||||
|
||||
/* set blocksize for default displaylist */
|
||||
if(d2_setdlistblocksize(_d2_handle, 25) != D2_OK) {
|
||||
LV_LOG_ERROR("Could NOT d2_setdlistblocksize\n");
|
||||
d2_closedevice(_d2_handle);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* bind the hardware */
|
||||
if(d2_inithw(_d2_handle, 0) != D2_OK) {
|
||||
LV_LOG_ERROR("Could NOT d2_inithw\n");
|
||||
d2_closedevice(_d2_handle);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
renderbuffer = d2_newrenderbuffer(_d2_handle, 20, 20);
|
||||
if(!renderbuffer) {
|
||||
LV_LOG_ERROR("NO renderbuffer\n");
|
||||
d2_closedevice(_d2_handle);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void lv_port_gpu_hw_deinit(void)
|
||||
{
|
||||
if(_d2_handle == NULL)
|
||||
return;
|
||||
|
||||
D2_EXEC(d2_freerenderbuffer(_d2_handle, renderbuffer));
|
||||
D2_EXEC(d2_closedevice(_d2_handle));
|
||||
|
||||
renderbuffer = NULL;
|
||||
_d2_handle = NULL;
|
||||
}
|
||||
|
||||
void lv_port_gpu_flush(void)
|
||||
{
|
||||
lv_port_gpu_hw_deinit();
|
||||
}
|
||||
|
||||
static void lv_port_gpu_start_render(void)
|
||||
{
|
||||
D2_EXEC(d2_selectrenderbuffer(_d2_handle, renderbuffer));
|
||||
}
|
||||
|
||||
static void lv_port_gpu_complete_render(void)
|
||||
{
|
||||
D2_EXEC(d2_flushframe(_d2_handle));
|
||||
}
|
||||
|
||||
void lv_port_gpu_wait(lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_port_gpu_complete_render();
|
||||
|
||||
lv_draw_sw_wait_for_finish(draw_ctx);
|
||||
}
|
||||
|
||||
static void lv_port_gpu_execute_render(void)
|
||||
{
|
||||
if(_d2_handle) {
|
||||
D2_EXEC(d2_executerenderbuffer(_d2_handle, renderbuffer, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void lv_port_gpu_blit(int32_t x, int32_t y, lv_color_t * dst, const lv_area_t * fill_area)
|
||||
{
|
||||
uint32_t ModeSrc;
|
||||
|
||||
ModeSrc = d2_mode_rgb565;
|
||||
|
||||
lv_coord_t dst_width, dst_hight;
|
||||
dst_width = lv_area_get_width(fill_area);
|
||||
dst_hight = lv_area_get_height(fill_area);
|
||||
|
||||
d2_selectrenderbuffer(_d2_handle, renderbuffer);
|
||||
|
||||
// Generate render operations
|
||||
d2_framebuffer(_d2_handle, (uint16_t *)&fb_background[0], LV_HOR_RES_MAX, LV_HOR_RES_MAX,
|
||||
MAX(fill_area->y2 + 1, 2), lv_port_gpu_cf_get_default());
|
||||
|
||||
d2_cliprect(_d2_handle, 0, 0, LV_HOR_RES_MAX - 1, fill_area->y2);
|
||||
d2_setblitsrc(_d2_handle, (void *) dst, dst_width, dst_width, dst_hight, ModeSrc);
|
||||
d2_blitcopy(_d2_handle, dst_width, dst_hight, 0, 0, D2_FIX4(dst_width), D2_FIX4(dst_hight),
|
||||
D2_FIX4(fill_area->x1), D2_FIX4(fill_area->y1), 0);
|
||||
|
||||
// Execute render operations
|
||||
d2_executerenderbuffer(_d2_handle, renderbuffer, 0);
|
||||
}
|
||||
|
||||
void lv_port_gpu_fill(lv_color_t * dest_buf, const lv_area_t * fill_area, lv_coord_t dst_width,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
invalidate_cache();
|
||||
|
||||
lv_port_gpu_start_render();
|
||||
|
||||
D2_EXEC(d2_framebuffer(_d2_handle, d1_maptovidmem(_d2_handle, dest_buf), MAX(dst_width, 2), MAX(dst_width, 2),
|
||||
MAX(fill_area->y2 + 1, 2), lv_port_gpu_cf_get_default()));
|
||||
|
||||
D2_EXEC(d2_cliprect(_d2_handle, 0, 0, dst_width - 1, fill_area->y2));
|
||||
D2_EXEC(d2_setalpha(_d2_handle, opa > LV_OPA_MAX ? 0xFF : opa));
|
||||
D2_EXEC(d2_setcolor(_d2_handle, 0, lv_port_gpu_color_lv_to_d2(color)));
|
||||
D2_EXEC(d2_renderbox(_d2_handle, D2_FIX4(fill_area->x1), D2_FIX4(fill_area->y1),
|
||||
D2_FIX4(lv_area_get_width(fill_area)), D2_FIX4(lv_area_get_height(fill_area))));
|
||||
|
||||
lv_port_gpu_execute_render();
|
||||
}
|
||||
|
||||
bool lv_port_gpu_config_blit(const lv_draw_img_dsc_t * draw_dsc, lv_img_cf_t dst_cf,
|
||||
lv_img_cf_t src_cf, bool alpha_en, bool color_key_en, bool blend_en, bool colorize_en)
|
||||
{
|
||||
d2_s32 d2_src_cf, d2_dst_cf;
|
||||
|
||||
if(blend_en && draw_dsc->blend_mode != LV_BLEND_MODE_NORMAL
|
||||
&& draw_dsc->blend_mode != LV_BLEND_MODE_ADDITIVE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
d2_src_cf = lv_port_gpu_cf_lv_to_d2(src_cf);
|
||||
d2_dst_cf = lv_port_gpu_cf_lv_to_d2(dst_cf);
|
||||
if(d2_src_cf < 0 || !lv_port_gpu_cf_fb_valid(d2_dst_cf)) {
|
||||
return false;
|
||||
}
|
||||
src_cf_val = d2_src_cf;
|
||||
dst_cf_val = d2_dst_cf;
|
||||
|
||||
img_dsc = *draw_dsc;
|
||||
|
||||
/* Disable alpha if alpha channel does not exist */
|
||||
alpha_enabled = lv_port_gpu_cf_has_alpha(src_cf_val) ? alpha_en : 0;
|
||||
color_key_enabled = color_key_en;
|
||||
blend_enabled = blend_en;
|
||||
colorize_enabled = colorize_en | lv_port_gpu_cf_is_alpha(src_cf_val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void lv_port_gpu_blit_internal(const lv_area_t * dest_area, const lv_color_t * src_buf,
|
||||
const lv_area_t * src_area, d2_u32 flags)
|
||||
{
|
||||
const lv_area_t * img_area = src_area;
|
||||
lv_area_t img_area_scaled;
|
||||
lv_coord_t w, h, img_w, img_h;
|
||||
d2_s32 pitch;
|
||||
int bpp = lv_port_gpu_cf_bpp(src_cf_val);
|
||||
|
||||
D2_EXEC(d2_cliprect(_d2_handle, dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2));
|
||||
|
||||
pitch = w = lv_area_get_width(src_area);
|
||||
h = lv_area_get_height(src_area);
|
||||
|
||||
if(img_dsc.zoom != LV_IMG_ZOOM_NONE) {
|
||||
img_area_scaled.x1 = src_area->x1 + ((((int32_t)0 - img_dsc.pivot.x) * img_dsc.zoom) >> 8) + img_dsc.pivot.x;
|
||||
img_area_scaled.x2 = src_area->x1 + ((((int32_t)w - img_dsc.pivot.x) * img_dsc.zoom) >> 8) + img_dsc.pivot.x;
|
||||
img_area_scaled.y1 = src_area->y1 + ((((int32_t)0 - img_dsc.pivot.y) * img_dsc.zoom) >> 8) + img_dsc.pivot.y;
|
||||
img_area_scaled.y2 = src_area->y1 + ((((int32_t)h - img_dsc.pivot.y) * img_dsc.zoom) >> 8) + img_dsc.pivot.y;
|
||||
img_area = &img_area_scaled;
|
||||
}
|
||||
|
||||
img_w = lv_area_get_width(img_area);
|
||||
img_h = lv_area_get_height(img_area);
|
||||
|
||||
if(0 < bpp && bpp < 8) {
|
||||
pitch = (w + (8 - bpp)) & (~(8 - bpp));
|
||||
}
|
||||
|
||||
if(img_dsc.angle == 0) {
|
||||
D2_EXEC(d2_setblitsrc(_d2_handle, (void *) src_buf, pitch, w, h, src_cf_val));
|
||||
|
||||
D2_EXEC(d2_blitcopy(_d2_handle, w, h, 0, 0,
|
||||
D2_FIX4(img_w), D2_FIX4(img_h), D2_FIX4(img_area->x1), D2_FIX4(img_area->y1), flags));
|
||||
}
|
||||
else {
|
||||
int x, y, x1, y1, x2, y2, x3, y3, x4, y4, dxu, dxv, dyu, dyv, xx, xy, yx, yy;
|
||||
int pivot_scaled_x, pivot_scaled_y;
|
||||
int tex_offset = (flags & d2_bf_filter) ? -32767 : 0;
|
||||
d2_u8 amode, cmode = d2_to_copy;
|
||||
float angle = ((float)img_dsc.angle / 10) * M_PI / 180;
|
||||
float cos_angle = cosf(angle);
|
||||
float sin_angle = sinf(angle);
|
||||
d2_u8 fillmode_backup;
|
||||
|
||||
/* setup texture params */
|
||||
fillmode_backup = d2_getfillmode(_d2_handle);
|
||||
D2_EXEC(d2_setfillmode(_d2_handle, d2_fm_texture));
|
||||
D2_EXEC(d2_settexture(_d2_handle, (void *) src_buf, pitch, w, h, src_cf_val));
|
||||
D2_EXEC(d2_settexturemode(_d2_handle, flags & (d2_bf_filter | d2_bf_wrap)));
|
||||
amode = flags & d2_bf_usealpha ? d2_to_copy : d2_to_one;
|
||||
cmode = flags & d2_bf_colorize2 ? d2_to_blend : d2_to_copy;
|
||||
D2_EXEC(d2_settextureoperation(_d2_handle, amode, cmode, cmode, cmode));
|
||||
if(flags & d2_bf_colorize2) {
|
||||
d2_color cl = d2_getcolor(_d2_handle, 0), ch = d2_getcolor(_d2_handle, 1);
|
||||
D2_EXEC(d2_settexopparam(_d2_handle, d2_cc_red, (uint8_t)(cl >> 16UL),
|
||||
(uint8_t)(ch >> 16UL)));
|
||||
D2_EXEC(d2_settexopparam(_d2_handle, d2_cc_green, (uint8_t)(cl >> 8UL),
|
||||
(uint8_t)(ch >> 8UL)));
|
||||
D2_EXEC(d2_settexopparam(_d2_handle, d2_cc_blue, (uint8_t)(cl >> 0UL),
|
||||
(uint8_t)(ch >> 0UL)));
|
||||
}
|
||||
|
||||
x = D2_FIX4(img_area->x1);
|
||||
y = D2_FIX4(img_area->y1);
|
||||
|
||||
/* define quad points */
|
||||
x1 = D2_FIX4(0);
|
||||
y1 = D2_FIX4(0);
|
||||
x2 = D2_FIX4(img_w);
|
||||
y2 = D2_FIX4(0);
|
||||
x3 = D2_FIX4(img_w);
|
||||
y3 = D2_FIX4(img_h);
|
||||
x4 = D2_FIX4(0);
|
||||
y4 = D2_FIX4(img_h);
|
||||
|
||||
/* rotate points for quad */
|
||||
pivot_scaled_x = (img_dsc.pivot.x * img_dsc.zoom) >> 4;
|
||||
pivot_scaled_y = (img_dsc.pivot.y * img_dsc.zoom) >> 4;
|
||||
|
||||
lv_port_gpu_rotate_point(&x1, &y1, cos_angle, sin_angle, pivot_scaled_x, pivot_scaled_y);
|
||||
lv_port_gpu_rotate_point(&x2, &y2, cos_angle, sin_angle, pivot_scaled_x, pivot_scaled_y);
|
||||
lv_port_gpu_rotate_point(&x3, &y3, cos_angle, sin_angle, pivot_scaled_x, pivot_scaled_y);
|
||||
lv_port_gpu_rotate_point(&x4, &y4, cos_angle, sin_angle, pivot_scaled_x, pivot_scaled_y);
|
||||
|
||||
/* compute texture increments */
|
||||
xx = (int)(cos_angle * 65536.0f);
|
||||
xy = (int)(sin_angle * 65536.0f);
|
||||
yx = (int)(-sin_angle * 65536.0f);
|
||||
yy = (int)(cos_angle * 65536.0f);
|
||||
dxu = ((D2_FIX16(w) / D2_FIX4(img_w)) * xx) >> 12;
|
||||
dxv = ((D2_FIX16(w) / D2_FIX4(img_w)) * xy) >> 12;
|
||||
dyu = ((D2_FIX16(h) / D2_FIX4(img_h)) * yx) >> 12;
|
||||
dyv = ((D2_FIX16(h) / D2_FIX4(img_h)) * yy) >> 12;
|
||||
|
||||
/* map texture exactly to rotated quad, so texel center is always (0/0) top-left */
|
||||
D2_EXEC(d2_settexelcenter(_d2_handle, 0, 0));
|
||||
D2_EXEC(d2_settexturemapping(_d2_handle, (d2_point)(x + x1), (d2_point)(y + y1),
|
||||
tex_offset, tex_offset, dxu, dxv, dyu, dyv));
|
||||
|
||||
int minx = MAX(dest_area->x1, D2_INT4(x + MIN(x1, MIN(x2, MIN(x3, x4)))));
|
||||
int maxx = MIN(dest_area->x2, D2_INT4(x + MAX(x1, MAX(x2, MAX(x3, x4)))));
|
||||
int slice = (flags & d2_bf_filter) ? 6 : 8;
|
||||
|
||||
/* Perform render operation in slices to acheive better performance */
|
||||
for(int posx = minx; posx < maxx; posx += slice) {
|
||||
D2_EXEC(d2_cliprect(_d2_handle, posx, dest_area->y1, MIN(posx + slice - 1, maxx), dest_area->y2));
|
||||
D2_EXEC(d2_renderquad(_d2_handle, (d2_point)(x + x1), (d2_point)(y + y1),
|
||||
(d2_point)(x + x2), (d2_point)(y + y2),
|
||||
(d2_point)(x + x3), (d2_point)(y + y3),
|
||||
(d2_point)(x + x4), (d2_point)(y + y4), 0));
|
||||
}
|
||||
D2_EXEC(d2_setfillmode(_d2_handle, fillmode_backup));
|
||||
}
|
||||
}
|
||||
|
||||
void lv_port_ra_gpu_blit(lv_color_t * dst, const lv_area_t * dst_area, lv_coord_t dest_stride,
|
||||
const lv_color_t * src, const lv_area_t * src_area, lv_opa_t opa)
|
||||
{
|
||||
d2_u32 flags = 0;
|
||||
const d2_color * clut = NULL;
|
||||
int clut_len = 0;
|
||||
|
||||
invalidate_cache();
|
||||
|
||||
clut_len = lv_port_gpu_handle_indexed_color(&src, &clut, src_cf_val);
|
||||
|
||||
lv_port_gpu_start_render();
|
||||
|
||||
D2_EXEC(d2_framebuffer(_d2_handle, d1_maptovidmem(_d2_handle, dst), MAX(dest_stride, 2),
|
||||
MAX(dst_area->x2 + 1, 2), MAX(dst_area->y2 + 1, 2), dst_cf_val));
|
||||
|
||||
flags |= alpha_enabled ? d2_bf_usealpha : 0;
|
||||
|
||||
D2_EXEC(d2_setalpha(_d2_handle, opa > LV_OPA_MAX ? LV_OPA_COVER : opa));
|
||||
|
||||
if(clut) {
|
||||
D2_EXEC(d2_writetexclut_direct(_d2_handle, clut, 0, clut_len));
|
||||
}
|
||||
|
||||
flags |= color_key_enabled ? d2_bf_usealpha : 0;
|
||||
flags |= (colorize_enabled || img_dsc.recolor_opa != LV_OPA_TRANSP) ? d2_bf_colorize2 : 0;
|
||||
if(colorize_enabled) {
|
||||
D2_EXEC(d2_setcolor(_d2_handle, 0, lv_port_gpu_color_lv_to_d2(img_dsc.recolor)));
|
||||
D2_EXEC(d2_setcolor(_d2_handle, 1, lv_port_gpu_color_lv_to_d2(img_dsc.recolor)));
|
||||
}
|
||||
else if(img_dsc.recolor_opa != LV_OPA_TRANSP) {
|
||||
d2_color cl = 0, ch = 0;
|
||||
lv_port_gpu_get_recolor_consts(&cl, &ch);
|
||||
D2_EXEC(d2_setcolor(_d2_handle, 0, cl));
|
||||
D2_EXEC(d2_setcolor(_d2_handle, 1, ch));
|
||||
}
|
||||
|
||||
flags |= ((img_dsc.angle || img_dsc.zoom != LV_IMG_ZOOM_NONE) && img_dsc.antialias) ? d2_bf_filter : 0;
|
||||
|
||||
if(blend_enabled) {
|
||||
D2_EXEC(d2_setblendmode(_d2_handle, d2_bm_alpha,
|
||||
img_dsc.blend_mode != LV_BLEND_MODE_NORMAL ? d2_bm_one : d2_bm_one_minus_alpha));
|
||||
D2_EXEC(d2_setalphablendmode(_d2_handle, d2_bm_one, d2_bm_one_minus_alpha));
|
||||
}
|
||||
else {
|
||||
D2_EXEC(d2_setblendmode(_d2_handle, d2_bm_one, d2_bm_zero));
|
||||
D2_EXEC(d2_setalphablendmode(_d2_handle, d2_bm_one, d2_bm_zero));
|
||||
}
|
||||
|
||||
lv_port_gpu_blit_internal(dst_area, src, src_area, flags);
|
||||
|
||||
lv_port_gpu_execute_render();
|
||||
}
|
||||
|
||||
void lv_draw_ra6m3_2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
||||
{
|
||||
lv_area_t blend_area;
|
||||
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) return;
|
||||
|
||||
bool done = false;
|
||||
|
||||
if(dsc->mask_buf == NULL && dsc->blend_mode == LV_BLEND_MODE_NORMAL && lv_area_get_size(&blend_area) > 100) {
|
||||
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
|
||||
|
||||
lv_color_t * dest_buf = draw_ctx->buf;
|
||||
|
||||
const lv_color_t * src_buf = dsc->src_buf;
|
||||
if(src_buf) {
|
||||
lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||
|
||||
lv_area_t src_area;
|
||||
src_area.x1 = blend_area.x1 - (dsc->blend_area->x1 - draw_ctx->buf_area->x1);
|
||||
src_area.y1 = blend_area.y1 - (dsc->blend_area->y1 - draw_ctx->buf_area->y1);
|
||||
src_area.x2 = src_area.x1 + lv_area_get_width(dsc->blend_area) - 1;
|
||||
src_area.y2 = src_area.y1 + lv_area_get_height(dsc->blend_area) - 1;
|
||||
|
||||
lv_port_ra_gpu_blit(dest_buf, &blend_area, dest_stride, src_buf, &src_area, dsc->opa);
|
||||
done = true;
|
||||
}
|
||||
else if(dsc->opa >= LV_OPA_MAX) {
|
||||
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||
lv_port_gpu_fill(dest_buf, &blend_area, dest_stride, dsc->color, dsc->opa);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!done) lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||
}
|
||||
|
||||
static void lv_port_gpu_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
|
||||
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format)
|
||||
{
|
||||
/*TODO basic ARGB8888 image can be handles here*/
|
||||
|
||||
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, color_format);
|
||||
}
|
||||
|
||||
void lv_draw_ra6m3_2d_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
lv_draw_sw_init_ctx(drv, draw_ctx);
|
||||
|
||||
lv_draw_ra6m3_dma2d_ctx_t * ra_2d_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx;
|
||||
|
||||
ra_2d_draw_ctx->blend = lv_draw_ra6m3_2d_blend;
|
||||
ra_2d_draw_ctx->base_draw.draw_img_decoded = lv_port_gpu_img_decoded;
|
||||
ra_2d_draw_ctx->base_draw.wait_for_finish = lv_port_gpu_wait;
|
||||
ra_2d_draw_ctx->base_draw.draw_letter = lv_draw_gpu_letter;
|
||||
//ra_2d_draw_ctx->base_draw.buffer_copy = lv_draw_ra6m3_2d_buffer_copy;
|
||||
}
|
||||
|
||||
void lv_draw_stm32_dma2d_ctx_deinit(lv_disp_t * disp, lv_draw_ctx_t * draw_ctx)
|
||||
{
|
||||
LV_UNUSED(disp);
|
||||
LV_UNUSED(draw_ctx);
|
||||
}
|
||||
|
||||
static void invalidate_cache(void)
|
||||
{
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
if(disp->driver->clean_dcache_cb) disp->driver->clean_dcache_cb(disp->driver);
|
||||
}
|
||||
|
||||
#ifdef LOG_ERRORS
|
||||
static void lv_port_gpu_log_error(d2_s32 status, const char * func, int line)
|
||||
{
|
||||
if(status) {
|
||||
log_error_list[error_list_index].error = status;
|
||||
log_error_list[error_list_index].func = func;
|
||||
log_error_list[error_list_index].line = line;
|
||||
LV_LOG_ERROR("%s\r\n", d2_geterrorstring(_d2_handle));
|
||||
LV_LOG_ERROR("%d:\t%d - %s : %d\r\n", error_count,
|
||||
log_error_list[error_list_index].error,
|
||||
log_error_list[error_list_index].func,
|
||||
log_error_list[error_list_index].line);
|
||||
|
||||
error_count++;
|
||||
error_list_index++;
|
||||
if(error_list_index >= ERROR_LIST_SIZE) {
|
||||
error_list_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* LV_USE_GPU_RA6M3_G2D */
|
||||
56
src/draw/renesas/lv_gpu_d2_ra6m3.h
Normal file
56
src/draw/renesas/lv_gpu_d2_ra6m3.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file lv_gpu_d2_ra6m3.h
|
||||
*
|
||||
*/
|
||||
#ifndef LV_GPU_D2_RA6M3_H
|
||||
#define LV_GPU_D2_RA6M3_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../misc/lv_color.h"
|
||||
|
||||
#if LV_USE_GPU_RA6M3_G2D
|
||||
#include "../../core/lv_disp.h"
|
||||
#include "../sw/lv_draw_sw.h"
|
||||
|
||||
/**********************
|
||||
* DEFINE
|
||||
**********************/
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#define M_PI 3.1415926
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef lv_draw_sw_ctx_t lv_draw_ra6m3_dma2d_ctx_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_draw_ra6m3_g2d_init(void);
|
||||
|
||||
void lv_port_gpu_init(void);
|
||||
|
||||
void lv_port_gpu_flush(void);
|
||||
|
||||
void lv_port_gpu_blit(int32_t x, int32_t y, lv_color_t * dst, const lv_area_t * fill_area);
|
||||
|
||||
void lv_draw_ra6m3_2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
|
||||
|
||||
void lv_draw_ra6m3_2d_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
void lv_draw_ra6m3_2d_ctx_deinit(lv_disp_drv_t * disp, lv_draw_ctx_t * draw_ctx);
|
||||
|
||||
#endif /*LV_USE_GPU_GD32_IPA*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -104,7 +104,9 @@ void lv_draw_sdl_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * ds
|
||||
}
|
||||
|
||||
lv_coord_t w = lv_area_get_width(&draw_area), h = lv_area_get_height(&draw_area);
|
||||
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h);
|
||||
bool texture_cached = false;
|
||||
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h,
|
||||
&texture_cached);
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
dump_masks(texture, &draw_area, mask_ids, mask_ids_count, cap_ids[0] != LV_MASK_ID_INV ? cap_ids : NULL);
|
||||
|
||||
@@ -135,6 +137,11 @@ void lv_draw_sdl_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * ds
|
||||
SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
|
||||
SDL_SetTextureAlphaMod(texture, dsc->opa);
|
||||
SDL_RenderCopy(ctx->renderer, texture, &srcrect, &dstrect);
|
||||
|
||||
if(!texture_cached) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -86,7 +86,8 @@ bool lv_draw_sdl_composite_begin(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coor
|
||||
LV_ASSERT(internals->mask == NULL && internals->composition == NULL && internals->target_backup == NULL);
|
||||
|
||||
lv_coord_t w = lv_area_get_width(apply_area), h = lv_area_get_height(apply_area);
|
||||
internals->composition = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET0, w, h);
|
||||
internals->composition = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET0, w, h,
|
||||
&internals->composition_cached);
|
||||
/* Don't need to worry about integral overflow */
|
||||
lv_coord_t ofs_x = (lv_coord_t) - apply_area->x1, ofs_y = (lv_coord_t) - apply_area->y1;
|
||||
/* Offset draw area to start with (0,0) of coords */
|
||||
@@ -95,7 +96,10 @@ bool lv_draw_sdl_composite_begin(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coor
|
||||
internals->target_backup = SDL_GetRenderTarget(ctx->renderer);
|
||||
SDL_SetRenderTarget(ctx->renderer, internals->composition);
|
||||
SDL_SetRenderDrawColor(ctx->renderer, 255, 255, 255, 0);
|
||||
SDL_RenderClear(ctx->renderer);
|
||||
/* SDL_RenderClear is not working properly, so we overwrite the target with solid color */
|
||||
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_NONE);
|
||||
SDL_RenderFillRect(ctx->renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_BLEND);
|
||||
#if LV_GPU_SDL_CUSTOM_BLEND_MODE
|
||||
internals->mask = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM0, w, h);
|
||||
dump_masks(internals->mask, apply_area);
|
||||
@@ -171,19 +175,23 @@ void lv_draw_sdl_composite_end(lv_draw_sdl_ctx_t * ctx, const lv_area_t * apply_
|
||||
break;
|
||||
}
|
||||
SDL_RenderCopy(ctx->renderer, internals->composition, &src_rect, &dst_rect);
|
||||
if(!internals->composition_cached) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
SDL_DestroyTexture(internals->composition);
|
||||
}
|
||||
}
|
||||
|
||||
internals->mask = internals->composition = internals->target_backup = NULL;
|
||||
}
|
||||
|
||||
SDL_Texture * lv_draw_sdl_composite_texture_obtain(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_composite_texture_id_t id,
|
||||
lv_coord_t w, lv_coord_t h)
|
||||
lv_coord_t w, lv_coord_t h, bool * texture_in_cache)
|
||||
{
|
||||
lv_point_t * tex_size = NULL;
|
||||
composite_key_t mask_key = mask_key_create(id);
|
||||
SDL_Texture * result = lv_draw_sdl_texture_cache_get_with_userdata(ctx, &mask_key, sizeof(composite_key_t), NULL,
|
||||
(void **) &tex_size);
|
||||
if(!result || tex_size->x < w || tex_size->y < h) {
|
||||
if(result == NULL || tex_size->x < w || tex_size->y < h) {
|
||||
lv_coord_t size = next_pow_of_2(LV_MAX(w, h));
|
||||
int access = SDL_TEXTUREACCESS_STREAMING;
|
||||
if(id >= LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TRANSFORM0) {
|
||||
@@ -195,8 +203,19 @@ SDL_Texture * lv_draw_sdl_composite_texture_obtain(lv_draw_sdl_ctx_t * ctx, lv_d
|
||||
result = SDL_CreateTexture(ctx->renderer, LV_DRAW_SDL_TEXTURE_FORMAT, access, size, size);
|
||||
tex_size = lv_mem_alloc(sizeof(lv_point_t));
|
||||
tex_size->x = tex_size->y = size;
|
||||
lv_draw_sdl_texture_cache_put_advanced(ctx, &mask_key, sizeof(composite_key_t), result, tex_size, lv_mem_free, 0);
|
||||
bool in_cache = lv_draw_sdl_texture_cache_put_advanced(ctx, &mask_key, sizeof(composite_key_t), result,
|
||||
tex_size, lv_mem_free, 0);
|
||||
if(!in_cache) {
|
||||
lv_mem_free(tex_size);
|
||||
}
|
||||
if(texture_in_cache != NULL) {
|
||||
*texture_in_cache = in_cache;
|
||||
}
|
||||
}
|
||||
else if(texture_in_cache != NULL) {
|
||||
*texture_in_cache = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ typedef enum lv_draw_sdl_composite_texture_id_t {
|
||||
/**
|
||||
* Begin drawing with mask. Render target will be switched to a temporary texture,
|
||||
* and drawing coordinates may get clipped or translated
|
||||
* @param ctx Drawing context
|
||||
* @param coords_in Original coordinates
|
||||
* @param clip_in Original clip area
|
||||
* @param extension Useful for shadows or outlines, can be NULL
|
||||
@@ -59,8 +60,18 @@ bool lv_draw_sdl_composite_begin(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coor
|
||||
|
||||
void lv_draw_sdl_composite_end(lv_draw_sdl_ctx_t * ctx, const lv_area_t * apply_area, lv_blend_mode_t blend_mode);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ctx Drawing context
|
||||
* @param id Texture ID
|
||||
* @param w Maximum width needed
|
||||
* @param h Maximum height needed
|
||||
* @param texture_in_cache output to query if the texture is in cache. If it's not in cache, you'll need to destroy it
|
||||
* by yourself
|
||||
* @return Obtained texture
|
||||
*/
|
||||
SDL_Texture * lv_draw_sdl_composite_texture_obtain(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_composite_texture_id_t id,
|
||||
lv_coord_t w, lv_coord_t h);
|
||||
lv_coord_t w, lv_coord_t h, bool * texture_in_cache);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -72,7 +72,8 @@ static void draw_img_rounded(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, con
|
||||
lv_coord_t radius);
|
||||
|
||||
static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture,
|
||||
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius);
|
||||
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius,
|
||||
bool * in_cache);
|
||||
|
||||
static lv_draw_img_rounded_key_t rounded_key_create(const SDL_Texture * texture, lv_coord_t w, lv_coord_t h,
|
||||
lv_coord_t radius);
|
||||
@@ -106,11 +107,16 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
||||
lv_draw_sdl_img_header_t * header = NULL;
|
||||
SDL_Texture * texture = lv_draw_sdl_texture_cache_get_with_userdata(ctx, key, key_size, &texture_found,
|
||||
(void **) &header);
|
||||
bool texture_in_cache = false;
|
||||
if(!texture_found) {
|
||||
lv_draw_sdl_img_load_texture(ctx, key, key_size, src, draw_dsc->frame_id, &texture, &header);
|
||||
lv_draw_sdl_img_load_texture(ctx, key, key_size, src, draw_dsc->frame_id, &texture, &header,
|
||||
&texture_in_cache);
|
||||
}
|
||||
else {
|
||||
texture_in_cache = true;
|
||||
}
|
||||
SDL_free(key);
|
||||
if(!texture) {
|
||||
if(!texture || !header) {
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
@@ -148,6 +154,14 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
||||
|
||||
lv_draw_sdl_composite_end(ctx, &apply_area, draw_dsc->blend_mode);
|
||||
|
||||
if(!texture_in_cache) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
if(!header->managed) {
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
lv_mem_free(header);
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
@@ -185,7 +199,7 @@ static void calc_draw_part(SDL_Texture * texture, const lv_draw_sdl_img_header_t
|
||||
|
||||
bool lv_draw_sdl_img_load_texture(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_cache_key_head_img_t * key, size_t key_size,
|
||||
const void * src, int32_t frame_id, SDL_Texture ** texture,
|
||||
lv_draw_sdl_img_header_t ** header)
|
||||
lv_draw_sdl_img_header_t ** header, bool * texture_in_cache)
|
||||
{
|
||||
_lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, lv_color_white(), frame_id);
|
||||
lv_draw_sdl_cache_flag_t tex_flags = 0;
|
||||
@@ -210,16 +224,18 @@ bool lv_draw_sdl_img_load_texture(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_cache_key
|
||||
#endif
|
||||
}
|
||||
if(texture && cdsc) {
|
||||
*header = SDL_malloc(sizeof(lv_draw_sdl_img_header_t));
|
||||
*header = lv_mem_alloc(sizeof(lv_draw_sdl_img_header_t));
|
||||
SDL_memcpy(&(*header)->base, &cdsc->dec_dsc.header, sizeof(lv_img_header_t));
|
||||
(*header)->rect = rect;
|
||||
lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_size, *texture, *header, SDL_free, tex_flags);
|
||||
(*header)->managed = (tex_flags & LV_DRAW_SDL_CACHE_FLAG_MANAGED) != 0;
|
||||
*texture_in_cache = lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_size, *texture, *header, SDL_free,
|
||||
tex_flags);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
lv_draw_sdl_texture_cache_put(ctx, key, key_size, NULL);
|
||||
*texture_in_cache = lv_draw_sdl_texture_cache_put(ctx, key, key_size, NULL);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************
|
||||
@@ -320,7 +336,8 @@ static void draw_img_rounded(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, con
|
||||
{
|
||||
const int w = lv_area_get_width(coords), h = lv_area_get_height(coords);
|
||||
lv_coord_t real_radius = LV_MIN3(radius, w, h);
|
||||
SDL_Texture * frag = img_rounded_frag_obtain(ctx, texture, header, w, h, real_radius);
|
||||
bool frag_in_cache = false;
|
||||
SDL_Texture * frag = img_rounded_frag_obtain(ctx, texture, header, w, h, real_radius, &frag_in_cache);
|
||||
apply_recolor_opa(frag, draw_dsc);
|
||||
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, frag, real_radius, coords, clip, true);
|
||||
|
||||
@@ -360,6 +377,11 @@ static void draw_img_rounded(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, con
|
||||
SDL_RenderCopy(ctx->renderer, texture, &src_rect, &dst_rect);
|
||||
}
|
||||
SDL_RenderSetClipRect(ctx->renderer, NULL);
|
||||
|
||||
if(!frag_in_cache) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
SDL_DestroyTexture(frag);
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_recolor_opa(SDL_Texture * texture, const lv_draw_img_dsc_t * draw_dsc)
|
||||
@@ -377,22 +399,28 @@ static void apply_recolor_opa(SDL_Texture * texture, const lv_draw_img_dsc_t * d
|
||||
}
|
||||
|
||||
static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture,
|
||||
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius)
|
||||
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius,
|
||||
bool * in_cache)
|
||||
{
|
||||
lv_draw_img_rounded_key_t key = rounded_key_create(texture, w, h, radius);
|
||||
SDL_Texture * mask_frag = lv_draw_sdl_rect_bg_frag_obtain(ctx, radius);
|
||||
bool mask_frag_in_cache = false;
|
||||
SDL_Texture * mask_frag = lv_draw_sdl_rect_bg_frag_obtain(ctx, radius, &mask_frag_in_cache);
|
||||
SDL_Texture * img_frag = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
|
||||
if(img_frag == NULL) {
|
||||
const lv_coord_t full_frag_size = radius * 2 + 3;
|
||||
img_frag = SDL_CreateTexture(ctx->renderer, LV_DRAW_SDL_TEXTURE_FORMAT, SDL_TEXTUREACCESS_TARGET,
|
||||
full_frag_size, full_frag_size);
|
||||
SDL_assert(img_frag);
|
||||
SDL_SetTextureBlendMode(img_frag, SDL_BLENDMODE_BLEND);
|
||||
SDL_Texture * old_target = SDL_GetRenderTarget(ctx->renderer);
|
||||
SDL_SetRenderTarget(ctx->renderer, img_frag);
|
||||
SDL_SetRenderDrawColor(ctx->renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(ctx->renderer);
|
||||
/* SDL_RenderClear is not working properly, so we overwrite the target with solid color */
|
||||
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_NONE);
|
||||
SDL_RenderFillRect(ctx->renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_BLEND);
|
||||
|
||||
lv_area_t coords = {0, 0, w - 1, h - 1}, clip;
|
||||
lv_area_t coords = {0, 0, w - 1, h - 1};
|
||||
lv_area_t frag_coords = {0, 0, full_frag_size - 1, full_frag_size - 1};
|
||||
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, mask_frag, radius, &frag_coords, NULL, false);
|
||||
|
||||
@@ -443,7 +471,14 @@ static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Textur
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
|
||||
SDL_SetRenderTarget(ctx->renderer, old_target);
|
||||
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), img_frag);
|
||||
*in_cache = lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), img_frag);
|
||||
}
|
||||
else {
|
||||
*in_cache = true;
|
||||
}
|
||||
if(!mask_frag_in_cache) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
SDL_DestroyTexture(mask_frag);
|
||||
}
|
||||
return img_frag;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ extern "C" {
|
||||
typedef struct lv_draw_sdl_img_header_t {
|
||||
lv_img_header_t base;
|
||||
SDL_Rect rect;
|
||||
bool managed;
|
||||
} lv_draw_sdl_img_header_t;
|
||||
|
||||
/**********************
|
||||
@@ -56,9 +57,22 @@ typedef struct lv_draw_sdl_img_header_t {
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
/**
|
||||
*
|
||||
* @param ctx Drawing context
|
||||
* @param key Texture cache key
|
||||
* @param key_size Size of texture cache key
|
||||
* @param src Image source pointer
|
||||
* @param frame_id Frame ID for animated image
|
||||
* @param texture Texture for render
|
||||
* @param header Header also holds sdl image info
|
||||
* @param texture_in_cache Whether the texture has been put in the cache. Please note for managed texture,
|
||||
* this will be false too. So you'll need to check header.managed too.
|
||||
* @return Whether the image has been loaded successfully
|
||||
*/
|
||||
bool lv_draw_sdl_img_load_texture(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_cache_key_head_img_t * key, size_t key_size,
|
||||
const void * src, int32_t frame_id, SDL_Texture ** texture,
|
||||
lv_draw_sdl_img_header_t ** header);
|
||||
lv_draw_sdl_img_header_t ** header, bool * texture_in_cache);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -54,7 +54,7 @@ static lv_font_glyph_key_t font_key_glyph_create(const lv_font_t * font_p, uint3
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p,
|
||||
void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p,
|
||||
uint32_t letter)
|
||||
{
|
||||
const lv_area_t * clip_area = draw_ctx->clip_area;
|
||||
@@ -117,6 +117,7 @@ void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t
|
||||
lv_font_glyph_key_t glyph_key = font_key_glyph_create(font_p, letter);
|
||||
bool glyph_found = false;
|
||||
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &glyph_key, sizeof(glyph_key), &glyph_found);
|
||||
bool in_cache = false;
|
||||
if(!glyph_found) {
|
||||
if(g.resolved_font) {
|
||||
font_p = g.resolved_font;
|
||||
@@ -128,7 +129,10 @@ void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t
|
||||
texture = SDL_CreateTextureFromSurface(renderer, mask);
|
||||
SDL_FreeSurface(mask);
|
||||
lv_mem_free(buf);
|
||||
lv_draw_sdl_texture_cache_put(ctx, &glyph_key, sizeof(glyph_key), texture);
|
||||
in_cache = lv_draw_sdl_texture_cache_put(ctx, &glyph_key, sizeof(glyph_key), texture);
|
||||
}
|
||||
else {
|
||||
in_cache = true;
|
||||
}
|
||||
if(!texture) {
|
||||
return;
|
||||
@@ -142,6 +146,10 @@ void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t
|
||||
|
||||
/*If the letter is completely out of mask don't draw it*/
|
||||
if(!_lv_area_intersect(&draw_area, &t_letter, &t_clip)) {
|
||||
if(!in_cache) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
return;
|
||||
}
|
||||
SDL_Rect srcrect, dstrect;
|
||||
@@ -156,6 +164,11 @@ void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t
|
||||
SDL_RenderCopy(renderer, texture, &srcrect, &dstrect);
|
||||
|
||||
lv_draw_sdl_composite_end(ctx, &apply_area, dsc->blend_mode);
|
||||
|
||||
if(!in_cache) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -58,15 +58,24 @@ lv_draw_layer_ctx_t * lv_draw_sdl_layer_init(lv_draw_ctx_t * draw_ctx, lv_draw_l
|
||||
|
||||
enum lv_draw_sdl_composite_texture_id_t texture_id = LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TRANSFORM0 +
|
||||
ctx->internals->transform_count;
|
||||
transform_ctx->target = lv_draw_sdl_composite_texture_obtain(ctx, texture_id, target_w, target_h);
|
||||
transform_ctx->target = lv_draw_sdl_composite_texture_obtain(ctx, texture_id, target_w, target_h,
|
||||
&transform_ctx->target_in_cache);
|
||||
transform_ctx->target_rect.x = 0;
|
||||
transform_ctx->target_rect.y = 0;
|
||||
transform_ctx->target_rect.w = target_w;
|
||||
transform_ctx->target_rect.h = target_h;
|
||||
|
||||
layer_ctx->max_row_with_alpha = target_h;
|
||||
layer_ctx->max_row_with_no_alpha = target_h;
|
||||
|
||||
SDL_SetTextureBlendMode(transform_ctx->target, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderTarget(renderer, transform_ctx->target);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
/* SDL_RenderClear is not working properly, so we overwrite the target with solid color */
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderFillRect(renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
|
||||
/* Set proper drawing context for transform layer */
|
||||
ctx->internals->transform_count += 1;
|
||||
@@ -100,6 +109,7 @@ void lv_draw_sdl_layer_blend(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * lay
|
||||
lv_area_to_sdl_rect(layer_ctx->original.clip_area, &clip_rect);
|
||||
SDL_Point center = {.x = draw_dsc->pivot.x, .y = draw_dsc->pivot.y};
|
||||
SDL_RenderSetClipRect(renderer, &clip_rect);
|
||||
SDL_SetTextureAlphaMod(transform_ctx->target, draw_dsc->opa);
|
||||
SDL_RenderCopyEx(renderer, transform_ctx->target, &transform_ctx->target_rect, &trans_rect,
|
||||
draw_dsc->angle, ¢er, SDL_FLIP_NONE);
|
||||
SDL_RenderSetClipRect(renderer, NULL);
|
||||
@@ -108,6 +118,11 @@ void lv_draw_sdl_layer_blend(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * lay
|
||||
void lv_draw_sdl_layer_destroy(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx)
|
||||
{
|
||||
lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
|
||||
lv_draw_sdl_layer_ctx_t * transform_ctx = (lv_draw_sdl_layer_ctx_t *) layer_ctx;
|
||||
if(!transform_ctx->target_in_cache && transform_ctx->target != NULL) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
SDL_DestroyTexture(transform_ctx->target);
|
||||
}
|
||||
ctx->internals->transform_count -= 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef struct _lv_draw_sdl_layer_ctx_t {
|
||||
SDL_Texture * orig_target;
|
||||
SDL_Texture * target;
|
||||
SDL_Rect target_rect;
|
||||
bool target_in_cache;
|
||||
lv_draw_layer_flags_t flags;
|
||||
} lv_draw_sdl_layer_ctx_t;
|
||||
/**********************
|
||||
|
||||
@@ -53,7 +53,7 @@ static SDL_Texture * line_texture_create(lv_draw_sdl_ctx_t * sdl_ctx, const lv_d
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
void lv_draw_sdl_draw_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1,
|
||||
const lv_point_t * point2)
|
||||
const lv_point_t * point2, bool * in_cache)
|
||||
{
|
||||
lv_draw_sdl_ctx_t * sdl_ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
|
||||
SDL_Renderer * renderer = sdl_ctx->renderer;
|
||||
@@ -68,7 +68,7 @@ void lv_draw_sdl_draw_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t *
|
||||
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(sdl_ctx, &key, sizeof(key), NULL);
|
||||
if(!texture) {
|
||||
texture = line_texture_create(sdl_ctx, dsc, (lv_coord_t) length);
|
||||
lv_draw_sdl_texture_cache_put(sdl_ctx, &key, sizeof(key), texture);
|
||||
*in_cache = lv_draw_sdl_texture_cache_put(sdl_ctx, &key, sizeof(key), texture);
|
||||
}
|
||||
|
||||
lv_area_t coords = {x1, y1, x2, y2};
|
||||
@@ -126,7 +126,10 @@ static SDL_Texture * line_texture_create(lv_draw_sdl_ctx_t * sdl_ctx, const lv_d
|
||||
SDL_SetRenderTarget(sdl_ctx->renderer, texture);
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(sdl_ctx->renderer, 0xFF, 0xFF, 0xFF, 0x0);
|
||||
SDL_RenderClear(sdl_ctx->renderer);
|
||||
/* SDL_RenderClear is not working properly, so we overwrite the target with solid color */
|
||||
SDL_SetRenderDrawBlendMode(sdl_ctx->renderer, SDL_BLENDMODE_NONE);
|
||||
SDL_RenderFillRect(sdl_ctx->renderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(sdl_ctx->renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(sdl_ctx->renderer, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
SDL_Rect line_rect = {1 + dsc->width / 2, 1, length, dsc->width};
|
||||
SDL_RenderFillRect(sdl_ctx->renderer, &line_rect);
|
||||
|
||||
@@ -77,7 +77,9 @@ void lv_draw_sdl_polygon(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dr
|
||||
int16_t mask_id = lv_draw_mask_add(&polygon_param, NULL);
|
||||
|
||||
lv_coord_t w = lv_area_get_width(&draw_area), h = lv_area_get_height(&draw_area);
|
||||
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h);
|
||||
bool texture_in_cache = false;
|
||||
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h,
|
||||
&texture_in_cache);
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
dump_masks(texture, &draw_area);
|
||||
|
||||
@@ -91,6 +93,10 @@ void lv_draw_sdl_polygon(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dr
|
||||
SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
|
||||
SDL_SetTextureAlphaMod(texture, draw_dsc->bg_opa);
|
||||
SDL_RenderCopy(ctx->renderer, texture, &srcrect, &dstrect);
|
||||
if(!texture_in_cache) {
|
||||
LV_LOG_WARN("Texture is not cached, this will impact performance.");
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef struct lv_draw_sdl_context_internals_t {
|
||||
lv_lru_t * texture_cache;
|
||||
SDL_Texture * mask;
|
||||
SDL_Texture * composition;
|
||||
bool composition_cached;
|
||||
SDL_Texture * target_backup;
|
||||
uint8_t transform_count;
|
||||
} lv_draw_sdl_context_internals_t;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user