Description
Part of #4016
Introduce the problem
In the current stage of parallel rendering an lot of drawing related features are disabled. We should reconsider and re-implement them. This issue is to discuss how to handle masks, effects, etc in the new parallel render architecture.
Examples and cases
Here are a few use-case for which we should have a solution in the end. I also add my proposed solution (see their description in the next section)
Mixed use cases
- Alpha gradient: Use
lv_color32_t
in APIs and make gradients deal with the alpha channel too. - Music player demo stripes around the cover: Use triangles (now they are trapezoids but in v9 Sw render shouldn't support polygons)
- Chart faded area (like in the widgets demo): Use right angle triangles with gradient
- Transform widget parts (e.g. slider knob rotation) : Allow easily creating and managing new layers manually in draw events
- Masking
- Clip corner: Built-in solution for better optimization, render children to a new layer if they overlap the corner and apply mask
- Bitmap or text mask to any drawing or layer: There are special "mask draw tasks". If they are added the widget are drawn to a new ARGB layer and that layer is masked by the masking draw tasks.
- Blur and other filters:
post process cb
- Backdrop filter (e.g. blur): ???
- Drop shadow on ARGB images:
post process cb
- Real time outline for ARGB images:
post process cb
- GPU effects (e.g. contrast):
post process cb
- Perspective transform: just implement it
- SVG/vector graphics: generic API + 3rd party lib
Software rendered primitives
- Line:
- idea: use A8 image rotation
- dash skewed: dash the A8 image
- square and rounded line ending: add rounded caps to the A8 image
- line joint: not supported, use SVG instead
- Arc
- square and rounded line ending: custom mask, some local masking magic
- process in 16x16 blocks to easily ignore chunks in the middle
- Rounded rectangle and border
- different radius on corners
- process large radius in 16x16 chunks to have simplify squares on not radius parts.
- Triangle
- simple anti-aliasing
- polygons are not supported: use SVG lib if needed
- Image
- Transform the image in 8x8 squares to easily discard 64 px if they are out of the original image
Not strictly related
- Text on path
- Text shadow
- Gradient on border and shadow
- Multiple border,s outlines and shadows
Suggested solution
- Have built-in mask-related draw tasks applied only on ARGB images (layers). It's like
LV_DRAW_TASK_TYPE_IMAGE
but it performs masking. The following mask sources should be supported: bitmap, text, rounded rectangle post_process cb
:- A style property which can add new draw tasks e.g. for masking, blurring, etc. It's called when all children's draw tasks are added. If there is a
post_process cb
the widget with its children are drawn on a new layer and that layer can be manipulated independently of the other parts of the screen. - An other option is to add new draw tasks in
LV_EVENT_DRAW_POST_END
. The object needs to know to create a new layer.
- A style property which can add new draw tasks e.g. for masking, blurring, etc. It's called when all children's draw tasks are added. If there is a
- clip corner: A special mask (i.e. rectangle mask with radius). It should be applied only on the direct children if they are on a radius area. Not called from
post_process_cb
as LVGL needs to do some special considerations with it and enable it only if needed. - new layer during drawing: Make it simple to manually create nee layers. E.g. in a draw begin event create a layer and continue the drawing there. In a draw end event merge the layer back to the original (parent) layer. It can be done automatically if a part has transformations, or anything requiring a new layer.
I'm thinking about these for months and I believe it's hard to see how the pieces fit together, especially as it's heavily related to the new parallel rendering architecture. However, if you have any idea or remark about, I'd be more than happy the hear it 🙂
I can take care most of the implementation but it'd be amazing if you could bring up other use cases that we should consider.