Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New to quartz; avoiding triple-buffering when porting win32 code?




On Jun 17, 2005, at 8:28 AM, Simon Finne wrote:

Hello,

I've searched the list archives and googled the last couple of days, but haven't found an answer to this problem which I however assume is rather trivial. I'm porting a win32 application which has the following basic structure:

mainloop:
    poll & handle events
        draw changes to window backbuffer
    draw changes in backbuffer to screen

Actually the port has been done for a while, it was started on Jaguar and finished on Panther, but because my own benchmarks gave the result that QuickDraw was the most efficient way to draw graphics I was simply using an NSQuickDrawView and then porting was rather straight-forward. Now in Tiger it however seems that Quartz has surpassed QuickDraw in speed (is this correct?).

For many operations Quartz may be faster than QuickDraw. For others, it is not. It depends on what you are trying to draw.


For this application, however, the speed of your engine may be eclipsed by the triple buffering scheme. The application would have to move main memory from your back buffer to the windows back buffer and then from the window's back buffer to the video card. That seems like an awful lot of memory copying.

My problem with switching to Quartz (this problem was there also in the port using QuickDraw, but I'd like to correct it now) is that I would like to avoid having an "extra backbuffer", as each window already has it's own backbuffer it feels unnecessary to have another backbuffer allocated by the application into which all drawing is first done which is then copied to the window's backbuffer.

Exactly.

Basically my question is: Is there any way to draw directly to the backbuffer of the window, outside of the drawRect method in my NSView? The problem is that while handling events the application will need to update graphical elements, and I want to avoid having an extra backbuffer.

You can use the "lockFocus" method of an NSView to activate its graphics context (i.e. [myView lockFocus]. You can then draw into the view and when you are done you should call [myView unlockFocus].


This is generally frowned upon because the system can, potentially, synchronize the calls to drawRect with whatever else may be happening in the system.

It is much more efficient to do ALL of your drawing in the drawRect method. If something outside of that routine needs the display to be updated, you should make a note of what needs to be drawn and call [myView setNeedsDisplayInRect: someRect] (or any of the setNeedsDisplay routines). At that point the system will make note of the fact that your view needs drawing and will ensure that drawRect is called at the most appropriate time.

Since your application seems to be doing some animation... another option is to let your engine run and return to the event loop without drawing or calling setNeedsDisplay. You can then set up an event timer that fires at some reasonable time (say 30 times a second) which calls the setNeedsDisplay on your view. Only when you get that message, then, would you collect your graphics and draw them.

Scott

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartz-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartz-dev/email@hidden

This email sent to email@hidden
References: 
 >New to quartz; avoiding triple-buffering when porting win32 code? (From: Simon Finne <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.