Repository navigation
Change image storage to use new ExtendedAttrs payload field - #5879
Conversation
|
An optional optimization is to replace A further possibility would be to remove the |
Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com>
|
On further thought, I think it might be worthwhile to consider merging the I believe the changes to Marker in PR #5853 provide a good foundation for this model. That change attaches the Markers directly to a With this change, I think we can gradually get rid of However, I do think it makes sense to merge in PR #5853 (which includes the changes in this PR) before going further with the "custom data" route. |
|
I merged from upstream and all tests pass. Can we merge this? It is blocking BufferLine/LogicalLine changes. @Tyriar requested one small change (which I believe I've made), and potentially a more general API (which is a bigger project that should be considered in conjunction with other Marker/Decorator changes). |
|
Could this be merged? It is a prerequisite for PR #5797. |
|
My thinking is it would make sense to review and hopefully merge this PR before trying to review the bigger and more complicated PR #5797. One reason is that PR #5797 CI runs fail until this is merged in. I don't say this PR is my ideal way of attaching images to lines: We're previously discussed ideas about how to combine the concepts of markers, decorators, and extended-attributes into some more general mechanism. However, I think this PR is a good interim step to reduce some technical debt. |
|
@PerBothner Had no chance yet to look at this, sorry. In general it would be good, if this rewrite passes:
For sixel-bench to work correctly in the xterm.js demo you have to increase the WriteBuffer cache to 500 MB (this is due to missing flow control in the demo, just append a zero for the tests) xterm.js/src/common/input/WriteBuffer.ts Lines 12 to 20 in 29a7384 |
|
All the image examples in the demo work. The tests here seem to work. I run sixel-bench under |
|
@PerBothner How are the throughput numbers of sixel-bench compared to master? The script should yield a MB/s number. It is a bit annoying to perf test things currently with devtools due to #6106, I hope to get most of the issues there fixed soon. 🫰 |
Master, 4 runs each test: For with this PR: Varibility between runs appears bigger than between forks. |
|
@PerBothner Yeah the varibility is high for those type of tests, due to the long line from app --> pty --> demo-server --> websocket --> browser --> xterm.js --> addon. You get halfway stable numbers only, if your computers is otherwise mostly at rest. I'd say there is a small decline, but not much. Gonna do my own perf tests before I check the code paths myself. By the way - bufferline.loadCell is quite expensive in master due to extended attr object creation, I also addressed this in #6114. |
|
It is plausible the slowdown is caused by using |
Also make faster by removing much loadCell calls.
|
sixel-bench results with latest check-in: I think that is basically the same. |
|
I believe this is ready to be merged. |
|
@PerBothner I think the higher runtime results from loadCell and the fact, that we now have to do two allocations ( I think the What we in fact need is the following: static ExtendedAttrs.register(propery_name: string, default_value: any, isSticky: boolean);
Note static pattern above is not right yet, as it would apply the slot registration to all terminals in a context. What I mean by it is - we need a terminal-wide class factory, that respects registered slots or disregards them on a terminal instance in a slick way without additional creation overhead. Example: term.buffer.registerExtendedAttribute('urlid', 0, true);
// --> registers a slot urlId on internal data:
{
urlid: 0,
}
term.buffer.registerExtendedAttribute('imageid', 0, false);
// internal data:
{
urlid: 0,
imageid: 0,
}Now the difference of public isEmpty(): boolean {
for (const slot of slots) {
if (slot.isSticky && this._data[slot] !== default) return false;
}
return true;
}
static clone(): ExtendedAttrs {
const obj = new ExtendedAttrs(/* no ctor params anymore*/);
for (const slot of slots) {
obj._data[slot] = slot.isSticky ? this._data[slot] : slot.default;
}
...
return obj;
}(Maybe Edit: |
|
@PerBothner I am not opposed to merge this as interim fix for the direct accesses. But I still think it does not solve the real extensibility issue of extended attributes as I stubbed above. --> #6142 |
There was a problem hiding this comment.
@PerBothner Plz have a look at my comment below. Looks like a state change bug to me, but I cannot repro it currently on the buffer.
| workCell.extended.payload = new ImageTileInfo(imageId, tileId); | ||
| return; |
There was a problem hiding this comment.
I think this is wrong, as it does not mutate the extended reference? Note that the original version creates a new ExtendedAttrsImage object here.
The issue with this code - loadCell pulls extended from a blueprint for empty extended values, whose ref never changes. Thus the ImageTileInfo will get written to that?
In general - the dance of loadCell - setCell is not meant be used outside of bufferline, as the reference carry-forward semantic is not encapsulated by those methods.
(Maybe I am overlooking something, because I dont see the sideeffects of it currently...)
There was a problem hiding this comment.
It seems reasonable to just just delete those two lines, and instead fall through. Do you agree?
There was a problem hiding this comment.
yes.
And found the repro in between:
echo -ne '\x1b[4:2mxxxxxxxxx\x1b[D' && imgcat -l addons/addon-image/fixture/palette.pngIssue: the "xxx..." gets overwritten with first image tile due to ref sharing.
There was a problem hiding this comment.
Change committed and pushed.
There was a problem hiding this comment.
Yupp - with this everything is fine 👍
It is a general extension hook - but as currently designed/implemented a given cell can only support a single payload. Adding support for a list of payloads would be a relatively minor enhancement. However, I have suggested earlier attaching Markers to LogicalLine, adding start/end-ranges to Markers, and then maybe merging the ExtendedAttr support into Marker. But first we should merge in the LogicalLine change before we can attached Markers to LogicalLine ranges.
That would be appreciated. I agree it is not the perfect/final design, but it gets us in the right direction. Though a simple refinement is a bit more future-proof. Perhaps something like this: |
|
Markers are a minefield perfwise. But lets move that discussion over to #6142 and get done with this here as interim fix. (Btw this PR runs slightly faster in my tests with sixel-bench doing less work in |
Adds a general-purpose
payloadhook toExtendedAttrs. This allows us to get rid of theExtendedAttrsImagelogic, which can easily conflict with other extensions.The PR avoids looking into
BufferLineinternals by instead usingloadCellandsetCell. The calls toloadCellmay add slightly more overhead; if that is measurable, we can look into reducing the number ofloadCellcalls.This is an implementation of this suggestion.
It might make sense for a future update to remove the
urlIdfield fromExtendedAttrsand instead use the generalpayloadhook.