[PR #4877] [MERGED] Optimize rendering runs of spaces when there is no visual change #26004

Open
opened 2026-01-31 09:13:16 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/4877
Author: @DHowett-MSFT
Created: 3/10/2020
Status: Merged
Merged: 3/13/2020
Merged by: @DHowett-MSFT

Base: masterHead: dev/duhowett/cmatrix


📝 Commits (4)

  • a857291 Optimize rendering runs of spaces when only the foreground changes
  • 621581d Take global and local inversion into account
  • 04c65ec don't forget grid lines
  • f9150c2 okay.

📊 Changes

8 files changed (+73 additions, -8 deletions)

View changed files

📝 src/buffer/out/TextAttribute.cpp (+0 -5)
📝 src/buffer/out/TextAttribute.hpp (+30 -1)
📝 src/cascadia/TerminalCore/Terminal.hpp (+1 -0)
📝 src/cascadia/TerminalCore/terminalrenderdata.cpp (+10 -0)
📝 src/host/renderData.cpp (+12 -0)
📝 src/host/renderData.hpp (+2 -0)
📝 src/renderer/base/renderer.cpp (+16 -2)
📝 src/renderer/inc/IRenderData.hpp (+2 -0)

📄 Description

cmatrix is somewhat of a pathological case for our infrastructure: it
prints out a bunch of green and white characters and then updates them a
million times a second.

It also maintains a column of space between every green character. When
it prints this column, it prints it in "default" or "white". This ends
up making runs of text that look like this:

(def: G=green B=bright white W=white *=matrix char =space)

G W G W G W G W G W G W G W G W
G W G W G W G W G W G W G W G W
G W G W G W G W G W G W G W G W
G W G W G W G W G W G W G W G W
G W G W G W G W G W G W G W G W
G W G W G W G W G W G W G W G W
G W G W G W G W G W G W G W G W
G W G W G W G W G W G W G W G W

As characters trickle in:

G*W G*W G*W G*W G*W G*W G*W B*W
G*W G*W G*W G*W G*W G*W G*W G W
G*W G*W G*W B*W G*W G*W G*W G W
G*W B*W G*W G W G*W G*W G*W G*W
G*W G W G*W G W G*W B*W G*W G*W
B*W G W G*W G W G*W G W B*W G*W
G W G W G*W G W G*W G W G W B*W
G W G W B*W G W G*W G W G W G W

Every one of those color transitions causes us to break up the run of
text and start rendering it again. This impacts GDI, Direct2D and
ConPTY. In the example above, there are 120 runs.

The problem is, printing a space doesn't use the foreground color!

This commit introduces an optimization. When we're about to break a text
cluster because its attributes changed, we make sure that it's not just
filled with spaces and doesn't differ in any visually-meaningful way
(like underline or strikethrough, considering global invert state).

This lets us optimize both the rendering and the PTY output to look
like this:

G*   *   *   *   *   *   *  B*G
G*   *   *   *   *   *   *
G*   *   *  B*G  *   *   *
G*  B*G  *       *   *   *   *
G*       *       *  B*G  *   *
B*G      *       *      B*G  *
G        *       *          B*G
G       B*G      *

Text will be printed at best line-by-line and at worst only when the
visible properties of the screen actually change. In the example
above, there are only 21 runs.

This speeds up cmatrix remarkably.

PR Checklist


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/4877 **Author:** [@DHowett-MSFT](https://github.com/DHowett-MSFT) **Created:** 3/10/2020 **Status:** ✅ Merged **Merged:** 3/13/2020 **Merged by:** [@DHowett-MSFT](https://github.com/DHowett-MSFT) **Base:** `master` ← **Head:** `dev/duhowett/cmatrix` --- ### 📝 Commits (4) - [`a857291`](https://github.com/microsoft/terminal/commit/a857291e52366e15a37fd67eaffd2b9d48ffbf2d) Optimize rendering runs of spaces when only the foreground changes - [`621581d`](https://github.com/microsoft/terminal/commit/621581dad18666474fbfb79fff86adbe37053a7c) Take global and local inversion into account - [`04c65ec`](https://github.com/microsoft/terminal/commit/04c65eca2a7ab58286307b242446397953a2680d) don't forget grid lines - [`f9150c2`](https://github.com/microsoft/terminal/commit/f9150c2a4c1476d47091dbe364bd8eba51c90e08) okay. ### 📊 Changes **8 files changed** (+73 additions, -8 deletions) <details> <summary>View changed files</summary> 📝 `src/buffer/out/TextAttribute.cpp` (+0 -5) 📝 `src/buffer/out/TextAttribute.hpp` (+30 -1) 📝 `src/cascadia/TerminalCore/Terminal.hpp` (+1 -0) 📝 `src/cascadia/TerminalCore/terminalrenderdata.cpp` (+10 -0) 📝 `src/host/renderData.cpp` (+12 -0) 📝 `src/host/renderData.hpp` (+2 -0) 📝 `src/renderer/base/renderer.cpp` (+16 -2) 📝 `src/renderer/inc/IRenderData.hpp` (+2 -0) </details> ### 📄 Description cmatrix is somewhat of a pathological case for our infrastructure: it prints out a bunch of green and white characters and then updates them a million times a second. It also maintains a column of space between every green character. When it prints this column, it prints it in "default" or "white". This ends up making runs of text that look like this: `(def: G=green B=bright white W=white *=matrix char =space)` ``` G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W G W ``` As characters trickle in: ``` G*W G*W G*W G*W G*W G*W G*W B*W G*W G*W G*W G*W G*W G*W G*W G W G*W G*W G*W B*W G*W G*W G*W G W G*W B*W G*W G W G*W G*W G*W G*W G*W G W G*W G W G*W B*W G*W G*W B*W G W G*W G W G*W G W B*W G*W G W G W G*W G W G*W G W G W B*W G W G W B*W G W G*W G W G W G W ``` Every one of those color transitions causes us to break up the run of text and start rendering it again. This impacts GDI, Direct2D *and* ConPTY. In the example above, there are 120 runs. The problem is, printing a space doesn't **use** the foreground color! This commit introduces an optimization. When we're about to break a text cluster because its attributes changed, we make sure that it's not just filled with spaces and doesn't differ in any visually-meaningful way (like underline or strikethrough, considering global invert state). This lets us optimize both the rendering _and_ the PTY output to look like this: ``` G* * * * * * * B*G G* * * * * * * G* * * B*G * * * G* B*G * * * * * G* * * B*G * * B*G * * B*G * G * * B*G G B*G * ``` Text will be printed at best line-by-line and at worst only when the visible properties of the screen actually change. In the example above, there are only 21 runs. This speeds up cmatrix remarkably. ## PR Checklist * [x] Related to #1064 * [x] CLA signed * [ ] Tests added/passed (I haven't run these yet.) * [ ] Requires documentation to be updated * [x] Core contributee --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:13:16 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#26004