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

Made with FB

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

Robert


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).

joe kovac