Skip to content

[Parallel rendering] Masking #4059

Closed
Closed
@kisvegabor

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.
  • 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.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions