[comp.sys.mac.programmer] How do I code for 8.24 GC QuickDraw?

sundinKC@dna.lth.se (Anders Sundin) (04/14/91)

How do I write for the 8.24 GC Display Card, or rather, where can I
find an example of code that really gets accelerated by this card?
I have read #TN 289 "Deaccelerated CopyBits & 8.24 GC QuickDraw".
I have also read #TN 277 about CopyBits, and Develop nr 1 and 3
about GWorlds and the 8.24 GC.
But I still don't have a clue why my CopyBits is *much* slower when
"accelerated" by a 8.24 GC Display Card.

program SlowWhenAccelerated;
uses  Types, QuickDraw, Events, Fonts, Menus, QDOffscreen,
       SegLoad, Traps, Windows, Dialogs;

var
   gDrawingPort : GWorldPtr;
   gWindow      : WindowPtr;
   gRect        : Rect;
   gRGBBlack    : RGBColor;
   gRGBWhite    : RGBColor;
   gVert        : Boolean;
   gFlags       : GWorldFlags;

procedure DrawSomeStuff;
begin
   RGBForeColor(gRGBBlack);
   RGBBackColor(gRGBWhite);
   ClipRect(gRect);
   PaintRect(gRect);
   RGBForeColor(gRGBWhite);
   if gVert then
   begin
      MoveTo(200, 50);
      LineTo(200, 350);
   end
   else
   begin
      MoveTo(50, 200);
      LineTo(350, 200);
   end;
   gVert := not gVert;
end;

procedure DrawInAltScreen;
var
   oldPort   : CGrafPtr;
   oldDevice : GDHandle;

begin
   gFlags := UpdateGWorld(gDrawingPort, 0, screenbits.bounds,
                          nil, GetMainDevice, []);
   GetGWorld(oldPort, oldDevice);
   SetGWorld(gDrawingPort, nil);
   if not LockPixels(gDrawingPort^.portPixMap) then
      ExitToShell;
   DrawSomeStuff;
   UnlockPixels(gDrawingPort^.portPixMap);
   SetGWorld(oldPort, oldDevice);
end;

procedure BlitIt;
begin
   RGBForeColor(gRGBBlack);
   RGBBackColor(gRGBWhite);
   if not LockPixels(gDrawingPort^.portPixMap) then
      ExitToShell;
   CopyBits( GrafPtr(gDrawingPort)^.portBits,
             gWindow^.portBits,
             gRect,
             gRect,
             srcCopy,
             nil);
   UnlockPixels(gDrawingPort^.portPixMap);
end;

begin
   InitGraf(@thePort);
   InitFonts;
   InitWindows;
   InitMenus;
   TEInit;
   InitDialogs(nil);
   InitCursor;
   gVert := true;
   gRGBBlack.red :=     $0000;
   gRGBBlack.green :=   $0000;
   gRGBBlack.blue :=    $0000;
   gRGBWhite.red :=     $FFFF;
   gRGBWhite.green :=   $FFFF;
   gRGBWhite.blue :=    $FFFF;
   SetRect(gRect, 50, 50, 450, 450);
   gWindow := NewCWindow(nil, gRect, '', true, noGrowDocProc,
                         WindowPtr(-1), false, 0);
   if gWindow = nil then
      ExitToShell;
   if NewGWorld(gDrawingPort, 0, screenBits.bounds,
                nil, GetMainDevice, []) <> noErr then
      ExitToShell;
   SetRect(gRect, 0, 0, 400, 400);
   repeat
      DrawInAltScreen;
      BlitIt;
   until Button;
   DisposeGWorld(gDrawingPort);
end.
-- 
   -------------------------------------------------------------
  |  Anders Sundin          |  e-mail: sundinKC@dna.lth.se      |
  |  University of Lund     |          ok2aps@gemini.ldc.lu.se  |
  |  Organic Chemistry 2,   |          ok2aps@seldc52.bitnet    |
  |  P.O. Box 124           |   phone:  +46 46 108214           |
  |  S-22100 Lund, Sweden   |   fax:    +46 46 108209           |
   -------------------------------------------------------------

keith@Apple.COM (Keith Rollin) (04/16/91)

In article <1991Apr13.192211.27446@lth.se> sundinKC@dna.lth.se (Anders Sundin) writes:
>How do I write for the 8.24 GC Display Card, or rather, where can I
>find an example of code that really gets accelerated by this card?
>I have read #TN 289 "Deaccelerated CopyBits & 8.24 GC QuickDraw".
>I have also read #TN 277 about CopyBits, and Develop nr 1 and 3
>about GWorlds and the 8.24 GC.
>But I still don't have a clue why my CopyBits is *much* slower when
>"accelerated" by a 8.24 GC Display Card.

Anders,

I sent your questions to The QuickDraw Dude in Mac DTS, Guillermo
Ortiz. He had some comments for you. I've included them in the body of
your program below. 

Note to the reader: Guillermo's comments are the _only_ comments in the
program, so you should be able to pick them out pretty easily.

>
>program SlowWhenAccelerated;
>
{ This program shows that although CopyBits is faster with acceleration on, the
  overall performance of the program suffers due to the numerous problems in
  the code giving the perception that QD is slower under acceleration. Note
  all the comments to see the points where changes to the code make things
  significantly faster} 

>uses  Types, QuickDraw, Events, Fonts, Menus, QDOffscreen,
>       SegLoad, Traps, Windows, Dialogs;
>
>var
>   gDrawingPort : GWorldPtr;
>   gWindow      : WindowPtr;
>   gRect        : Rect;
>   gRGBBlack    : RGBColor;
>   gRGBWhite    : RGBColor;
>   gVert        : Boolean;
>   gFlags       : GWorldFlags;
>
>procedure DrawSomeStuff;
>begin
>   RGBForeColor(gRGBBlack);
>   RGBBackColor(gRGBWhite);
>   ClipRect(gRect);
>   PaintRect(gRect);
>   RGBForeColor(gRGBWhite);
>   if gVert then
>   begin
>      MoveTo(200, 50);
>      LineTo(200, 350);
>   end
>   else
>   begin
>      MoveTo(50, 200);
>      LineTo(350, 200);
>   end;
>   gVert := not gVert;
>end;
>
>procedure DrawInAltScreen;
>var
>   oldPort   : CGrafPtr;
>   oldDevice : GDHandle;
>
>begin

{ As in the case of NewGWorld when passing a depth of zero (see below) it
  doesn't make sense to pass a GDevice or the rect corresponding to the
  screen; you want to pass a nil for GDHandle and the windows port rect.  
  
  It is also important to note that calling UpdateGWorld here is what really
  kills the performance of the resulting code since the pixmap is (most
  probably) uncached from the card to main then massaged and finally copied
  back to the card; since there is no change to make to the GWorld it does not
  make sense to have this call at all; it can and should be removed. }  

>   gFlags := UpdateGWorld(gDrawingPort, 0, screenbits.bounds,
>                          nil, GetMainDevice, []);
>   GetGWorld(oldPort, oldDevice);
>   SetGWorld(gDrawingPort, nil);
>   if not LockPixels(gDrawingPort^.portPixMap) then
>      ExitToShell;
>   DrawSomeStuff;
>   UnlockPixels(gDrawingPort^.portPixMap);
>   SetGWorld(oldPort, oldDevice);
>end;
>
>procedure BlitIt;
>begin
>   RGBForeColor(gRGBBlack);
>   RGBBackColor(gRGBWhite);
>   if not LockPixels(gDrawingPort^.portPixMap) then
>      ExitToShell;
>   CopyBits( GrafPtr(gDrawingPort)^.portBits,
>             gWindow^.portBits,
>             gRect,
>             gRect,
>             srcCopy,
>             nil);
>   UnlockPixels(gDrawingPort^.portPixMap);
>end;
>
>begin
>   InitGraf(@thePort);
>   InitFonts;
>   InitWindows;
>   InitMenus;
>   TEInit;
>   InitDialogs(nil);
>   InitCursor;
>   gVert := true;
>   gRGBBlack.red :=     $0000;
>   gRGBBlack.green :=   $0000;
>   gRGBBlack.blue :=    $0000;
>   gRGBWhite.red :=     $FFFF;
>   gRGBWhite.green :=   $FFFF;
>   gRGBWhite.blue :=    $FFFF;
>   SetRect(gRect, 50, 50, 450, 450);
>   gWindow := NewCWindow(nil, gRect, '', true, noGrowDocProc,
>                         WindowPtr(-1), false, 0);
>   if gWindow = nil then
>      ExitToShell;

{ The following line should be changed:

	IF NewGWorld(gDrawingPort, 0, screenbits.bounds, NIL, GetMainDevice,
	   []) <> noErr THEN

  First it doesn't make sense to call GetMainDevice since passing zero as the
  depth makes the system ignore the GDevice being passes but also because
  second when you pass a depth of zero you want to pass the rect of a window
  you want to ensure the best performance for. So we have: }  

>   if NewGWorld(gDrawingPort, 0, gWindow^.portRect,
>                nil, nil, []) <> noErr then
>      ExitToShell;
>   SetRect(gRect, 0, 0, 400, 400);


{ If there was a real reason to call UpdateGWorld I would put it here so it is
  called just once as in: } 

	gFlags := UpdateGworld(gDrawingPort, 0, gWindow^.portRect, NIL, NIL,
		  []);	   { No need for GDHandle }

>   repeat
>      DrawInAltScreen;
>      BlitIt;
>   until Button;
>   DisposeGWorld(gDrawingPort);
>end.
>-- 
>   -------------------------------------------------------------
>  |  Anders Sundin          |  e-mail: sundinKC@dna.lth.se      |
>  |  University of Lund     |          ok2aps@gemini.ldc.lu.se  |
>  |  Organic Chemistry 2,   |          ok2aps@seldc52.bitnet    |
>  |  P.O. Box 124           |   phone:  +46 46 108214           |
>  |  S-22100 Lund, Sweden   |   fax:    +46 46 108209           |
>   -------------------------------------------------------------

Hope this helps,

-- 
------------------------------------------------------------------------------
Keith Rollin  ---  Apple Computer, Inc. 
INTERNET: keith@apple.com
    UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith
"But where the senses fail us, reason must step in."  - Galileo