RE: [VW7.4] Window damage repair - the real fix?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

RE: [VW7.4] Window damage repair - the real fix?

Steven Kelly
From: [hidden email] [mailto:[hidden email]]
> Here's a quick & dirty fix for the problem (it cost me half a day):

Well done Andre! For my part, I spent half an hour delving into the VM C
code that handles the event queue. Up to VW 7.1 it ignored events after
the 1024th i.e. when the buffer was full. Sames made a change in 7.1
that tried to handle at least repaint events after that, merging them
with the last in the buffer. Unfortunately, this doesn't work, and as I
have already emailed Sames, I think I know why. Here's the condensed
version, without the proprietary details:

The event queue is stored in a circular buffer. Each new event gets
added to the next slot in the buffer. Each event that is processed gets
eaten off the tail end. The VM remembers the position of the head and
tail, and both of these wrap round to the start of the buffer when they
reach the end. So the sequence of as-yet-unprocessed events is like a
snake that grows at the head as new events appear from Windows, and
shrinks at the tail as they are passed to the VW image for processing.
This makes it work like a snake in a video game, crawling along the
buffer from left to right, wrapping round at the edge of the "screen".

Sames' code to merge an event starts at either the head and the tail,
whichever index is larger (further right), and then heads back left
looking for the previous repaint event on that window.

If the queue is in the middle of the buffer, that's fine: (O is oldest
event, N is newest, # is an unprocessed event, . is old data).
[......O########N......]
Sames' code starts at N and decrements until it reaches O.

But what if the queue 'snake' is wrapped around:
[###N.........O#######]
Then Sames' code starts at O and decrement until it reaches N -
completely missing the events.

During a drag, N moves right, cycling at the end, until it catches up
with O from behind. Even if we start off near the start of the buffer:
[...ON................]
the end result is:
[#N.O#################]
(a few blank slots, one dot here, are left as a safety margin).

If I'm right, this means Sames' algorithm will almost ALWAYS fail: when
the queue overflows, unless O was initially at the left-most index, N
will be to the left of O. Thus the algorithm will always start at O and
search left to N, completely missing the events.

This would explain why having a bigger queue didn't help. The solution
is to change the algorithm so it always starts at the most recent event,
then goes leftwards to the oldest event, wrapping round as necessary.

My apologies if I'm wrong: I've not programmed in anger in C for 15
years, so I'm a bit rusty on the details; I have no debugger to run this
in, and the use of macros in the code makes it a little hard to debug in
my head. And of course even if I am right, there may be other bugs in
the code after this too...

All the best,
Steve