-
-
Notifications
You must be signed in to change notification settings - Fork 629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable pagination for sign/verify message #1337
Conversation
we should make the right margin wider in such case |
core/src/trezor/ui/text.py
Outdated
) -> None: | ||
if not pre_linebreaked: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like having both pre_linebreaked
and new_lines
. What is currently the difference? Could we maybe get rid of new_lines
now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- both=
False
:words
are treated as words, if a word fits on single line it is never broken, if it doesn't fit it's broken such that as many characters as possible stay on the first line. Spaces are treated as any other character when breaking a word containing them. new_lines=True
:words
are treated more as a lines, insertingBR
after every one. Otherwise behaves as above. This is the most common use in our codebase.pre_linebreaked=True
:words
are expected to contain linebreaks at the right places and are not processed before rendering.
Thinking about this, the result will be the same often for the latter two options.
Then there's another behaviour we want but is not part of this PR - accept strings containing spaces and break on spaces wherever possible. Perhaps it would make sense to merge all these flags into something like mode
which would take three different values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm still a little confused so I'm going to make a full table:
new_lines | pre_linebreaked | Behavior |
---|---|---|
False | False | Text is split at (a) explicit BRs, (b) end of screen |
True | False | Text is split at (a) explicit BRs, (b) end of screen, (c) end of individual item. This is most common. |
Any | True | Text is split at (a) explicit BRs. I.e, no magic happens if the text overflows. |
Is this correct?
I believe that going forward, we will be able to completely get rid of the (c) variant, "end of individual item". But for this PR it stays.
I'm not sure, however, how valuable is keeping the (b) variant. If we removed that, then there is no difference in behavior between pre_linebreaked=True
and `False.
Also implementation-wise it's just a matter of "reflowing" the words
parameter via a separate call.
(BTW, I believe the reason new_lines
is a parameter of render_text()
is to save memory and/or processing time otherwise needed to insert the BR symbols to the list. But going forward we'll be splitting strings anyway so I don't think this is relevant, but let's keep that in mind)
Anyway.
I think pre_linebreaked
should only be argument of Text
class, not render_text
call, and Text
should be responsible for calling break_lines
also i'd call it something else, something along the lines of auto_linebreaks=True
instead of pre_linebreaked=False
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'd say the table is correct. Agreed that it probably doesn't make sense to keep (b) long-term.
Regarding memory & time, this PR probably makes things worse but not sure how to get around that.
Will look into your suggestions, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding memory & time, this PR probably makes things worse but not sure how to get around that.
Total allocations for device tests in text.py
went from 180000 to 390000, that's pretty bad ...
core/src/trezor/ui/text.py
Outdated
offset_x: int = TEXT_MARGIN_LEFT, | ||
offset_y: int = TEXT_HEADER_HEIGHT + TEXT_LINE_HEIGHT, | ||
offset_x_max: int = ui.WIDTH, | ||
) -> List[List[TextContent]]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why return List[List] if you convert it to a flat list anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In apps/common/signverify.py
(and then apps/common/layout
) we first call chunks
on the result before passing it to render_text
which flattens it.
Changed:
|
Yeaahh... I guess I take everything back 👀 this here is the reason rewriting the UI in Rust would be so nice.
Although the refactor looks good on paper, I'm afraid this is showing that it's the wrong approach. The advantage of the original (my code from #1312 also does rough outline of a solution that looks like it would work better in this regard:
then the message pagination is done either by pre-breaking the message at given indexes, or we add a and we use this to get completely rid of |
not sure why, but it seems that they do |
of course, if your "get rid of nested lists" modification is OK memory-wise, we don't actually need to do the above :) |
Removing the nesting decreased the allocations from 390k to 330k which is far from OK. Back to the drawing board then ... |
Changed: - use MONO-sized space instead of NORMAL-sized space when rendering MONO text - fix corner case where word is broken before 0-th character - add flag for breaking text on spaces
Avoid enumerate(). Decreases number of allocations by ~90k.
Turn the line breaking generator into a function that returns list. Decreases the number of allocations by ~30k.
Get rid of the next_line() closure in break_lines(). Decreases the number of allocations by ~90k.
1598add
to
f5da228
Compare
I've force-pushed a version where
|
thanks for the measurements, these show hotspots nicely so, a problem I see is returning and manipulating tuples repeatedly. each "return tuple()" is an allocation. I'm not sure about this but maybe tuple deconstruction is also an allocation? Furthermore, you're reusing the results of my suggestion would be reworking so that: I'm not sure I completely understand the reason for I believe that by modifying
For now I wouldn't worry about calling |
what worries me is that the perhaps we could extend the |
i'm also kind of surprised that |
would you mind retrying with |
Fixes #1271. Required rather intrusive changes to
render_text()
.Some notes: