On Sun, Nov 21, 2004 at 08:07:58PM +0100, Alfredo Braunstein wrote:
> Andre Poenitz wrote:
> 
> > We could e.g. have a 'metrics dirty flag' which is set to true
> > by default and in cases we know that we haven't changed anything (i.e.
> > just selecting and the creen hasn't moved) we set it to false.
> 
> Sure, but metrics is only one thing. 

But the important one...
 
> When selecting, the bottleneck is drawing on screen. So we need to draw only
> part of the selection (say the cursor row, or something like that) and not
> the full screen. I'm not saying it's impossible, I think that it needs
> careful thinking in order to keep the code clear.

So lets think a bit about it.

My stomach says "Full repaint is just fine". Most of the other time
consuming stuff can be done in the metrics phase and cached (e.g. in
MetricsBase or the position cache) if necessary. So metrics() is the
part that hurts.

Of course, we can't fully redraw a hundred times per second, yet this
is what happens when we use the mouse to select a whole line going from
the begin to the and and getting a mouse event after each character.

Now, that's not needed. Optically, 15 or so redraws per second are
enough and that can be achieved by a timer mostly independent of the
drawing mechanism.

Ok. That leaves the people using X on the wrong end of a 56k line...

Now, we could have a 'cheap repaint' mechanism pretty much the same
way as the current update() suppression or the proposed metrics()
supression mechanism [Uh, this somehow goes in the direction of the old
update flag stuff...]  This mechanism would be used for situations like
mouse selection without screen movement and store an old cursor y
position. metrics() would be suppressed, and at drawing time we'd draw
the full screen to the buffer pixmap, yet we'd only send the part
between old cursor.y and current cursor.y (+/- ascent/descent) to the X
server.

So no inset::draw needs to be touched, it's just setting a flag in
LyXText::dispatch() and a few lines in screen.C and the actual frontend
code. Let's call this 'Option 1'.

If that's not enough (which I doubt), we could always have two buffer
pixmaps (one for background, one for text) and bitblt background + draw
selection + bitblt foreground. When selection changes without shifting
screen, neither buffer is invalidated and we'd get super fast redraw
times as long as the screen does not need to be shifted. This also
means no fiddling we row-wise redraw. Call it 'Option 2'.

When I think about it, we should do just this. The cost is an extra
pixmap buffer for the background plus dividing the inset::draw stuff
into inset::drawBackground() and inset::draw [Foreground, but I'd stick
to the 'draw()' naming]. As only very few insets actively use
backgrounds, this is altogether not much more work than option 1.

Comments?

Andre'

Reply via email to