On Tue, Sep 27, 2005 at 05:51:47PM +0300, Martin Vermeer wrote:
> Sort of. But how would you do that? And how would you achieve this while 
> preserving one-paragraph update where that is what you want? I sort of 
> see what you are hinting at, but I have no idea how to do it.

The whole update machinery is still in a somewhat unsatisfactory state.

We can make it work but simply doing more than we actually need, but
making it efficient and complete seems to be tricky.

I have been thinking about it since Martin's first patches arrived on
the list, and by now I am faily confident that it is achievable, but
not without effort.

Up to 1.3.x we have 'The old update machinery', which tries to do
immediate, but minimal updates. It has certain limitations to 'minimal'
as we e.g. rebreak whole paragraphs there, and behaviour is not excatly
deterministic as updates go up and down the inset hierarchy until thinks
have settled. Sometimes finishing was enforced by explicit 'premature'
braking endless loops and such.

In current 1.4.0cvs we have 'update everything' which is conceptionally
pretty robust but seemingly too slow in some cases.

In my opinion we should just make it faster and retain the simplicity of
the concept and only add structural changes if really necesary.
Currently we have four(!) calls to Paragraph::redoParagraph() for a 
single paragraph. Obviously, the concept requires only a single one.

Moreover, redoParagraph examines each item twice (in rowBreakPoint()
and setRowWidth()), so we pass through the critical singleWidth()
path eight(!) times instead of just once.

So we should try hard to pass through the critical path just once.  I'll
send later today a preliminary patch that folds rowBreakPoint() and
setRowWidth(), i.e. reduces this by a factor of two and gives an overall
gain of 8-12% when typing into a single long paragraph of about 1200
chars. I won't be able to take care of this patch after I send it to the
list, so I wouldn't mind if somebody took over.

Now, suppose that even reducing the four calls to Paragraph::
redoParagraph() to a single one is not enough.  The singlepar machinery
won't help because a paragraph is the granularity there. So we'd need
something finer like a row.  [This might be reasonable, as is most cases
after a single keystroke at most a single row is changed on screen.]

For this to happen I'd think we should decouple the updating mechanism
from the actual structural changes by moving the actual redrawing into
a 'second phase' while the actual lfun handling only records what needs
to be done.

I.e. when inserting a character somewhere we might just record 'inserted
at DocIteratorPos x'. More complex operations would just end up
recording several such items. In any case, the simple recording is not 
expensive.

Close to the end of the LFUN handling (or maybe just in the actual
paintEvent()) we could look at all recorded changes an make a fairly
educated guess on the absolut minimum required work.

When e.g. inserting a single character, we could try to rebreak only the
row containing this characters. If still still yields only a single row
(i.e. the row was stretched enough to include the new character as well)
we are basically done - and we do not even have to redraw the whole
screen as we do currently, but just that single changed row.

Does this sound like a plan?

Andre'

Reply via email to