Compare commits
2 Commits
db5ee5d20d
...
6a3d5aa0b0
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a3d5aa0b0 | |||
| 5fdae1e7d5 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -6,3 +6,7 @@ result-*
|
|||||||
*.jar
|
*.jar
|
||||||
.devenv
|
.devenv
|
||||||
BUG.md
|
BUG.md
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
bin
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ public record RenderCell(
|
|||||||
}
|
}
|
||||||
|
|
||||||
public RenderCell {
|
public RenderCell {
|
||||||
codepoints = codepoints.clone();
|
// Stored by reference: the marshaller hands us freshly allocated (or the shared
|
||||||
|
// empty) arrays it never mutates, so cloning here would double-allocate every
|
||||||
|
// cell and defeat the shared-empty optimization. The codepoints() accessor still
|
||||||
|
// clones on read to protect external callers.
|
||||||
foreground = foreground == null ? Optional.empty() : foreground;
|
foreground = foreground == null ? Optional.empty() : foreground;
|
||||||
background = background == null ? Optional.empty() : background;
|
background = background == null ? Optional.empty() : background;
|
||||||
kittyPlaceholder = kittyPlaceholder == null ? Optional.empty() : kittyPlaceholder;
|
kittyPlaceholder = kittyPlaceholder == null ? Optional.empty() : kittyPlaceholder;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -950,17 +951,20 @@ public final class GhosttyLibrary {
|
|||||||
try (Arena scratchArena = Arena.ofConfined()) {
|
try (Arena scratchArena = Arena.ofConfined()) {
|
||||||
Scratch scratch = new Scratch(scratchArena);
|
Scratch scratch = new Scratch(scratchArena);
|
||||||
renderStatePopulateRowIterator(state, iterator);
|
renderStatePopulateRowIterator(state, iterator);
|
||||||
List<RenderRow> rows = new ArrayList<>();
|
int cols = renderStateGetU16(state, RENDER_STATE_DATA_COLS);
|
||||||
|
List<RenderRow> rows = new ArrayList<>(renderStateGetU16(state, RENDER_STATE_DATA_ROWS));
|
||||||
int rowIndex = 0;
|
int rowIndex = 0;
|
||||||
while (renderStateRowIteratorNext(iterator)) {
|
while (renderStateRowIteratorNext(iterator)) {
|
||||||
boolean dirty = renderStateRowGetBoolean(iterator, RENDER_STATE_ROW_DATA_DIRTY, scratch);
|
boolean dirty = renderStateRowGetBoolean(iterator, RENDER_STATE_ROW_DATA_DIRTY, scratch);
|
||||||
List<RenderCell> cells = (dirtyRowsOnly && !dirty)
|
List<RenderCell> cells = (dirtyRowsOnly && !dirty)
|
||||||
? List.of()
|
? List.of()
|
||||||
: renderStateRowCells(iterator, scratch);
|
: renderStateRowCells(iterator, scratch, cols);
|
||||||
rows.add(new RenderRow(rowIndex, dirty, cells));
|
rows.add(new RenderRow(rowIndex, dirty, cells));
|
||||||
rowIndex++;
|
rowIndex++;
|
||||||
}
|
}
|
||||||
return List.copyOf(rows);
|
// rows is a fresh local that never escapes, so an unmodifiable wrapper gives
|
||||||
|
// the same immutability as List.copyOf without re-copying every row per frame.
|
||||||
|
return Collections.unmodifiableList(rows);
|
||||||
} finally {
|
} finally {
|
||||||
renderStateRowIteratorFree(iterator);
|
renderStateRowIteratorFree(iterator);
|
||||||
}
|
}
|
||||||
@@ -1054,13 +1058,13 @@ public final class GhosttyLibrary {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RenderCell> renderStateRowCells(MemorySegment rowIterator, Scratch scratch) {
|
private List<RenderCell> renderStateRowCells(MemorySegment rowIterator, Scratch scratch, int cols) {
|
||||||
MemorySegment cells = renderStateRowCellsNew();
|
MemorySegment cells = renderStateRowCellsNew();
|
||||||
try {
|
try {
|
||||||
renderStatePopulateRowCells(rowIterator, cells);
|
renderStatePopulateRowCells(rowIterator, cells);
|
||||||
// Returned raw: RenderRow's constructor already wraps this in an immutable copy,
|
// Returned raw: RenderRow's constructor already wraps this in an immutable copy,
|
||||||
// so a List.copyOf here would copy the per-cell list a second time every row.
|
// so a List.copyOf here would copy the per-cell list a second time every row.
|
||||||
List<RenderCell> result = new ArrayList<>();
|
List<RenderCell> result = new ArrayList<>(cols);
|
||||||
int column = 0;
|
int column = 0;
|
||||||
while (renderStateRowCellsNext(cells)) {
|
while (renderStateRowCellsNext(cells)) {
|
||||||
int[] codepoints = renderStateRowCellGraphemes(cells, scratch);
|
int[] codepoints = renderStateRowCellGraphemes(cells, scratch);
|
||||||
|
|||||||
Reference in New Issue
Block a user