MacOSX Performance

John M McIntosh johnmci at smalltalkconsulting.com
Mon Jan 24 18:51:08 UTC 2005


On Jan 24, 2005, at 4:55 AM, Karsten Wolf wrote:

>> So what if I tried it at 200 times/second?
> Lots of experimantation showed that 40 fps is really ok. Rethinking  
> the whole issue in this thread takes me to the conclusion that  
> QDFlushPortBuffer() _cannot_ be called more than ca. 200 times / sec.  
> IIRC degradation begins at 80…100 fps (haven't tried that for a long  
> time). This parameter is also _very_ machine specific. One of the  
> early ideas I had was about some calibration tool to find the  
> particular parameters for a specific machine. Still only an idea,  
> since I don't know how to detect the correct parameters.
>
>> a) sometimes a flush is left pending, not sure why since the dirty  
>> region should be flush occasionally (perhaps not occasionally  
>> enough?)
>>      Well I could do something about that if needed.
> That flush is always pending if you use constructs as "Display  
> restoreAfter:".
>
> When I implemented the framerateUpdate (IIRC TN2030) I inserted a call  
> to update somewhere in sqEvents.c. A small snippet that watched for  
> pending updates to be flushed. The updater "posts" an update at  
> now+minFPStimespan for the next update. Worked out fine except my vm  
> hangs on ca. every 10th launch. I left it untouched for a year or so.
>
> Recently I came up with another idea. Collecting the CopyBits() (as we  
> all know, another interprocess call; perhaps with not so much  
> limitations as QDFlushPortBuffer()) calls in a list of rectangles,  
> merging to a given tilesize for adjacent blits. Looks very promising.

Ok, things I noted, I tried 125 frames/second. That seems reasonable  
trade off. The benchmark completes in 1.2 seconds.  I could make this a  
runtime parm so people could fiddle as they see fit.

What I did in ioShowDisplayOnWindow is create an empty rectangle, then  
union update rectangles until we've reached  8 milliseconds of clock  
time, then I flush that rectangle to the display manager, this in turn  
unions with the quickdraw dirty region to ensure all drawing is  
completed.  When this happens I reset the clock and update rectangle.

Issues I found.


a) Using regions adds quite a bit of overhead, hence I switched to  
rectangles
b) Using the quickdraw dirty regions, say adding the update to the  
dirty regions (an obvious choice) for some reason results in crashes or  
hangs.
d) By using  
CFRunLoopIsWaiting(GetCFRunLoopFromEventLoop(GetMainEventLoop())) I  
avoid colliding with the FlushAllWindows observer loop logic.

Also see Apple's TN 2051

Outcome is that I got a lot of reading in on Apple's RunLoop processing  
and now have a better  understanding of what it does and issues we have  
with it.


Going forward

a) Testing
b) Beware of clock rollover
c) Working with multiple windows
d) Flushing every 1/60? of a second to ensure an pending updates are  
flushed.
e) Technically I could add a timer loop to the runtime loop to do the  
flush every 8ms, not sure about overall impact on bytecodes then.

>
> regards
> karsten
>
>
--
======================================================================== 
===
John M. McIntosh <johnmci at smalltalkconsulting.com> 1-800-477-2659
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
======================================================================== 
===




More information about the Squeak-dev mailing list