
FB II Compiler
PG PRO
Debugging
Memory
System
Mathematics
Resources
Disk I/O
Windows
Controls
Menus
Mouse
Keyboard
Text
Fonts
Drawing
Sound
Clipboard
Printing
Communication
ASM |
DRAWING
Compare speed between direct versus offscreen drawing
<< Sending the same drawing commands to an offscreen GWorld would not speed things up, I think. >>
Reluctant as I am to disagree with Rick, a direct comparison shows the answer to be "yes, and by a substantial factor" --- 4-5 times faster (on an iMac). See the comparison program below. A further advantage of the GW method is that having drawn the polys in the GWorld you can then refresh your window with a single call to FN CopyGW, which is _very_ fast.
'-------------------------------------
LOCAL FN MakeAndClearGWorld&(rectPtr&)
DIM offPort&
LONG IF FN NEWGWORLD(offPort&,0,#rectPtr&,0,0,0)=_noErr
LONG IF (offPort&<>_nil)
CALL SETGWORLD(offPort&,0)
CALL FORECOLOR(_blackColor)
CALL BACKCOLOR(_whiteColor)
CALL ERASERECT(#rectPtr&)
END IF
XELSE
offPort&=_nil
END IF
END FN=offPort&
LOCAL FN CopyGW (sPort&,dPort&, sRPtr&,dRPtr&)
LONG IF FN LOCKPIXELS(FN GETGWORLDPIXMAP(sPort&))
CALL COPYBITS(#sPort&+2,#dPort&+2,# sRPtr&,#dRPtr&,_srcCopy,0)
CALL UNLOCKPIXELS(FN GETGWORLDPIXMAP(sPort&))
END IF
END FN
LOCAL FN MakePoly& ' make a huge polygon
DIM j,polyH&
polyH&=FN OPENPOLY
CALL MOVETO(0,0)
FOR j=1 TO 8000
CALL LINETO(RND(579),RND(419))
NEXT
CALL LINETO(0,0)
CALL CLOSEPOLY
END FN=polyH&
WINDOW 1,"",(0,0)-(600,440)
DIM rect;8, polyH&, tk1&, tk2&
DIM offPort&,currPort&,GDevice&
polyH&=FN MakePoly&
tk1&=FN TICKCOUNT
CALL FRAMEPOLY (polyH&)
tk1&=FN TICKCOUNT-tk1&
CLS
CALL SETRECT(rect, 0,0,580,420)
CALL GETGWORLD(currPort&,GDevice&)
offPort&=FN MakeAndClearGWorld&(@rect)
tk2&=FN TICKCOUNT
LONG IF offPort&
CALL FRAMEPOLY (polyH&)
CALL SETGWORLD(currPort&,0)
FN CopyGW (offPort&,currPort&,@rect,@rect)
CALL DISPOSEGWORLD(offPort&)
END IF
tk2&=FN TICKCOUNT-tk2&
CALL TEXTMODE(_srcCopy)
PRINT tk1& "direct"
PRINT tk2& "GW"
CALL KILLPOLY(polyH&)
DO : UNTIL FN BUTTON
[Rick]
<< Sending the same drawing commands to an offscreen GWorld would not speed things up, I think. >>
[Robert]
<< Reluctant as I am to disagree with Rick, a direct comparison shows the answer to be "yes, and by a substantial factor" --- 4-5 times faster (on an iMac). >>
[Rick]
<< I too found the GWorld draw to be faster (by a factor ofalmost 3 on my G3). >>
[Mel]
<< 4% faster in a gworld on my PowerPC 7300/200 >>
[Mike]
<< FWIW Robert Purves' CALL FRAMEPOLY speed comparison example was faster by x6 on my 8600/250. >>
[Pete]
<< I ran the demo a couple of times and there was only a 2 or 3 "tick" difference on my G3/266 >>
The advantages of using GWorlds are not usually stated to include a big increase in raw drawing speed, so the speed-up in drawing polygons came as a surprise to me.
Let me stir the hornet's nest again and also try to reconcile the differing reports.
1. There is nothing special about FRAMEPOLY. The speed-up by the Gworld method is observed even with a sequence of ordinary LINETOs, as shown by the revised program below. And other graphics commands as well...
2. The relative speed depends on the bit-depth of the monitor:-
Time in ticks on iMac/8.5.1
Colours: 256 1000's millions
direct 43 72 25
GW 13 17 24
Conclusion:
GWorld is always faster, but the speed-up is negligible with millions of colours. (Another surprise: plain direct QuickDraw is faster with millions of colours than with smaller depths).
3. The relative speed depends on machine and/or system.
Time in ticks on Quadra650/7.6.1 256 colours
direct 97
GW 100
Here we see the result that most people would "expect" -- GW is a litle slower.
'---------------------------------------
COMPILE ,_dimmedVarsOnly
_nPoint=8000
DIM gX(_nPoint), gY(_nPoint)
END GLOBALS
LOCAL FN MakeAndClearGWorld&(rectPtr&)
DIM offPort&
LONG IF FN NEWGWORLD(offPort&,0,#rectPtr&,0,0,0)=_noErr
LONG IF (offPort&<>_nil)
CALL SETGWORLD(offPort&,0)
CALL FORECOLOR(_blackColor)
CALL BACKCOLOR(_whiteColor)
CALL ERASERECT(#rectPtr&)
END IF
XELSE
offPort&=_nil
END IF
END FN=offPort&
LOCAL FN CopyGW (sPort&,dPort&, sRPtr&,dRPtr&)
LONG IF FN LOCKPIXELS(FN GETGWORLDPIXMAP(sPort&))
CALL COPYBITS(#sPort&+2,#dPort&+2,# sRPtr&,#dRPtr&,_srcCopy,0)
CALL UNLOCKPIXELS(FN GETGWORLDPIXMAP(sPort&))
END IF
END FN
LOCAL FN MakeDrawingData
DIM j
FOR j=0 TO _nPoint
gX(j)=RND(600): gY(j)=RND(440)
NEXT
END FN
LOCAL FN DrawData
DIM j
CALL MOVETO(0,0)
FOR j=0 TO _nPoint
CALL LINETO (gX(j),gY(j))
NEXT
END FN
WINDOW 1,"",(0,0)-(600,440),_dialogPlain
DIM rect;8, tk1&, tk2&
DIM offPort&,currPort&,GDevice&
FN MakeDrawingData
tk1&=FN TICKCOUNT
FN DrawData
tk1&=FN TICKCOUNT-tk1&
CLS
CALL SETRECT(rect, 0,0,600,440)
CALL GETGWORLD(currPort&,GDevice&)
offPort&=FN MakeAndClearGWorld&(@rect)
tk2&=FN TICKCOUNT
LONG IF offPort&
COLOR=_zRed
FN DrawData
CALL SETGWORLD(currPort&,0)
FN CopyGW (offPort&,currPort&,@rect,@rect)
CALL DISPOSEGWORLD(offPort&)
END IF
tk2&=FN TICKCOUNT-tk2&
CALL TEXTMODE(_srcCopy)
PRINT tk1& "direct " tk2& "GW"
DO : UNTIL FN BUTTON
There could be a couple good reasons for this:
1. Drawing to video memory takes a lot more work then drawing to an offscreen. Quickdraw has to do a bunch of things it doesn't have to do when it uses the offscreen like making sure the cursor isn't drawn over, and bounding the image to the clip region. On 68K machines it also has to swap MMU modes. It does these things for each and every line drawn.
2. On machines which have a hardware version of copybits the time required to move the image onscreen is virtually nothing provided that the Gworld also exists on the video card (which is usually the case).
|