Skip to content

Draw the background separately from the foreground during render passes #6193

Closed as not planned

Description

preliminary work: https://github.com/microsoft/terminal/tree/dev/duhowett/background-atlas

I've been thinking a bit about the DX renderer drawing a "background atlas" before it draws any text.

If we separate background drawing into a totally separate phase, we get the following benefits:

It would look, roughly, like this:

step 1 (empty renderer)

image

step 2 (drawing background atlas)

image

step 3 (drawing foreground)

image

may need a mini-spec

Activity

  1. added
    Area-RenderingText rendering, emoji, complex glyph & font-fallback issues
    Issue-TaskIt's a feature request, but it doesn't really need a major design.
    on May 26, 2020
  2. ghost added
    Needs-TriageIt's a new issue that the core contributor team needs to triage at the next triage meeting
    on May 26, 2020
  3. removed
    Needs-TriageIt's a new issue that the core contributor team needs to triage at the next triage meeting
    on May 26, 2020
  4. DHowett commented on May 26, 2020

    @DHowett
    MemberAuthor

    Hey, it works!

    image

  5. DHowett commented on May 26, 2020

    @DHowett
    MemberAuthor

    Right now, I'm inefficiently iterating over the entire dirty region twice -- once row by row x attr by attr with an AttrRowIterator, and once row by row x cell by cell with a TextBufferCellIterator.

    They're the same expense, roughly, because AttrRowIterator doesn't have any affordances for getting the run length and skipping it. If it did, we could dispense with some of the complexity.

    IDEALLY, I would have one function that turned out a vector of clusters and a vector of backgrounds. This would save the cost of iterating twice.

  6. zadjii-msft commented on May 26, 2020

    @zadjii-msft
    Member

    Okay, so this might be working better than my hack to manually break the run with the cursor on it. I need to add at least O(Rows+Cols) checks to painting the frame in my prototype, to check if we're on the cursor row, and the perf so far is horrifyingly bad.

    If this truly doesn't double the work done for a single frame, then this seems like it might be a better solution to combine with the pre/post rendering of the cursor.

  7. egmontkob commented on May 26, 2020

    @egmontkob

    VTE does 2-pass rendering like this.

    IMO the biggest advantage is that letters can slightly overflow to neighboring cells, e.g. diacritics above or below don't get cropped, bold letters don't get their right edge cut off.

  8. DHowett commented on May 27, 2020

    @DHowett
    MemberAuthor

    Alright, I've got this down to a single function that takes each dirty region and produces...

    • A list of damaged backgrounds to repaint
    • A list of colored cluster lists to repaint

    I don't like the number of vectors here, but... we're saving money by invalidating narrowly whenever possible.

    Dirty Region [1..n]
    - Origin (SCREEN CHAR COORDS)
    - At line wrap point
    - Region intersected right half of DBCS char (left trim)
    - Background Run [1..n]
      - Attribute
      - Rect Covered (SCREEN CHAR COORDS)
    - Colored Foreground Run [1..n]
      - Attribute
      - Columns
      - Cluster [1..n]
    

    Right now, because of some minor issues (#2661), backgrounds are attributes and actual final colors. It's not pleasant!

    To fix:

    • reverse is occasionally (!) broken
    • render engines need flags to say "plz no background splitting" (vt engine needs to update drawing brushes per text run, foreground and background)
    • need to re-enable space optimization (if the cell is non-printing (and has no underline, etc.), no point in forwarding it to the cluster renderer!)
  9. DHowett commented on May 27, 2020

    @DHowett
    MemberAuthor
  10. 2 remaining items

  11. DHowett commented on Jun 3, 2020

    @DHowett
    MemberAuthor

    Michael's got some ideas that will be less invasive than this.

  12. added a commit that references this issue on Sep 5, 2020
  13. DHowett commented on Jun 29, 2022

    @DHowett
    MemberAuthor

    Atlas supersedes this.

  14. ghost added
    Needs-Tag-FixDoesn't match tag requirements
    on Jun 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-RenderingText rendering, emoji, complex glyph & font-fallback issuesIssue-TaskIt's a feature request, but it doesn't really need a major design.Needs-Tag-FixDoesn't match tag requirementsProduct-TerminalThe new Windows Terminal.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions