Explanation of Slow Window Resizing

Posted:
in macOS edited January 2014
Lately, many people have been posting complaints about OS X's slow speed. Most of these complaints are related to OS X's slow window resizing. I thought I would discuss it here to help people understand some of the design decisions that Apple is making. (And no, they are not idiots.) I am a professional programmer, but be forewarned that I don't work for Apple, and I don't do much Mac programming. So much of the following is pure speculation.



The first reason for slow window resizing is that OS X resizes windows in real-time (duh). But Windows NT and Windows 2000 handle real-time window resizing much faster on seemingly comparable hardware. So there must be other factors involved...



The second reason for slow window resizing is that OS X double buffers windows. ( And, no Scott H, it's not just because the buffers take up a ton of memory.) In case you don't know, OS X stores a copy of every window's contents in an offscreen memory buffer. So suppose a window is obscured by a bunch of other windows. Then suppose it is brought to the front (top of the z order). OS X can use the double buffer to restore the window without the application's help. In contrast, Windows and (sort of) UNIX do not double buffer. Instead, the application is responsible for redrawing the windows contents when it becomes unobscured. Double buffering negatively impacts window resizing because:



1. Whenever the window size increases, the size of the offscreen buffer will need to increase. The operating system will first try to extend (realloc) the offscreen buffer. In some cases, it may not be possible to just extend the buffer, so the operating system will have to allocate a whole new buffer and copy the old buffer's contents there. This could be really slow...



2. Graphical images are normally stored in memory as rows of pixels (scanlines). In this scheme, the second row will start right after the first row ends. The third row starts right after the second row ends. And so on. Changing the width (pitch) of a window upsets this organization and forces the operating system to perform many copies to realign the rows (scanlines). This would also be very slow...



3. I am guessing that all of the offscreen buffers are stored in system memory since they don't have a finite size (there could be an unlimited number of windows open). And since the offscreen buffers are not stored in video memory, graphic operations in double buffered windows are not hardware accelerated by video hardware. Ouch! However, I would assume that OpenGL games and multimedia are not automatically double buffered, so they don't see the same performance hit.



4. Every graphics operation requires an extra step. First the operation must be performed in the offscreen buffer and then the changes must be transferred (blit) to screen memory (framebuffer). In my experience, this extra blit should not be that big of a performance hit though.





That being said, I still think double buffering was a good design choice because:



1. It makes the programmer's life much easier. Many, if not most, applications need some sort of double buffering anyways. On Windows and UNIX, double buffering has to be implemented in each application that needs it. In OS X, the application developer does not have to worry about it. It's already there.



2. Obviously, when a window gets brought to the front (top of the z-order), the window's contents are restored faster.



3. Movement of windows is smoother.



4. Without double buffering, advanced visual effects like shadows, see through title bars (alpha channel), window thumbnails in dock, and opening window animations would be slow or impossible.



5. This one is probably a stretch, but when developing a game, it is normal to use double buffering to prevent "tearing" (screen shows something that wasn't done being drawn). I doubt Apple is going to that much trouble though.



In conclusion, I think it's totally unrealistic for people to expect OS X to ever be as fast as OS 9. OS X has very advanced features which need to run on equally advanced hardware. Preemptive multitasking alone could cause a substantial performance hit (which is why all of the old Photoshop bakeoffs are total bulls**t).



Personally, I'm glad they did not compromise features for performance. If you mess up your feature set in the beginning, it's hard to fix that later. (Remember the ridiculous lack of multitasking and memory protection in Mac OS 1-9?) Eventually, "the hardware will catch up with the software", and the Macintosh will be, undisputably, the best platform in the world.



[ 01-19-2002: Message edited by: Brian J. ]</p>
«1

Comments

  • Reply 1 of 36
    synsyn Posts: 329member
    I think moki demonstrated a while ago that the "blit" part was unnecassarily slow, and unoptimized. I might have completely misunderstood though. moki?
  • Reply 2 of 36
    You have no idea what you are talking about.
  • Reply 3 of 36
    [quote]Originally posted by Scott H.:

    <strong>You have no idea what you are talking about.</strong><hr></blockquote>



    Why don't you explain it to me then?
  • Reply 4 of 36
    Brian, Interesting theories....

    I also think many OsX apps may be getting sent an update message every available tick while the window is getting resized. I'm actually thinking of creating a timer for my graphical apps to only have them update every 24 or 48 fps kinda like film. Maybe...





    Hey, where do you work?

    I used to live in Eatontown/Red Bank.
  • Reply 5 of 36
    [quote]Originally posted by Brian J.:

    <strong>



    Why don't you explain it to me then?</strong><hr></blockquote>



    I can't because none of us knows the exact details of how Apple wrote the display layers.



    Just as an example when a window is resized I would imagine that Quatrz rerenders the rerenders window from scratch.



    Also you seem to think that each window is double buffered. It's the output frame that's double buffered. Of course it's a good thing who ever said it wasn't? Where did you get this idea that UNIX doesn't double buffer?





    Also ...

    I don't think you understand what double buffering is and why it's done.



    [ 01-20-2002: Message edited by: Scott H. ]</p>
  • Reply 6 of 36
    [quote]Originally posted by Scott H.:

    <strong>

    Just as an example when a window is resized I would imagine that Quatrz rerenders the rerenders window from scratch.</strong><hr></blockquote>



    Except of course for the case when the contents don't change size and are just cropped. As pointed out in the Ars review of OS X.
  • Reply 7 of 36
    fluffyfluffy Posts: 361member
    [quote]Originally posted by Scott H.:

    <strong>

    Also you seem to think that each window is double buffered. It's the output frame that's double buffered. Of course it's a good thing who ever said it wasn't? Where did you get this idea that UNIX doesn't double buffer?

    </strong><hr></blockquote>



    What do you mean by the output frame?
  • Reply 8 of 36
    [quote]Originally posted by Scott H.:

    <strong>Also you seem to think that each window is double buffered. It's the output frame that's double buffered.</strong><hr></blockquote>

    Scott, I believe most of the windows are double buffered. How else can you explain the results in the Quartz Debug.app?
  • Reply 9 of 36
    majormattmajormatt Posts: 1,077member
    Brian's explanation is a tad better than yours, Scott.



    For Apple to sacrafice features for temporary boost speed would be foolish for the future. Lets use this analagous situation: Back in the days of yore when we all used System 6, it was fairly fast, but limited. Then Apple released System 7.0, it was a slower OS by far, it added many things that slowed down the system as a whole. However, as newer hardware is released, that slow OS on a LC2 is blazing on a 6100. Its a matter of time when these speed issues will be illrelavent.
  • Reply 10 of 36
    The display is double buffered not the windows. Holy cow.



    Double buffering is when two buffers are used for updating the screen. One buffer is the one currently being displayed. The other is one that is drawn to. When the second buffer is finished being drawn to you swap them. It keeps the "flicker" down because you don't have to see the stuff being dawn.



    So, no, the windows are not double buffered.



    [ 01-20-2002: Message edited by: Scott H. ]</p>
  • Reply 11 of 36
    fluffyfluffy Posts: 361member
    [quote]Originally posted by Scott H.:

    <strong>

    Double buffering is when two buffers are used for updating the screen. One buffer is the one currently being displayed. The other is one that is drawn to. When the second buffer is finished being drawn to you swap them. It keeps the "flicker" down because you don't have to see the stuff being dawn.



    So, no, the windows are not double buffered.

    </strong><hr></blockquote>



    By that definition, yes, all of the windows are double buffered. Each window has an offscreen memory buffer that the quartz engine uses to composite the screen. The display is not double buffered. See Apple's documentation <a href="http://developer.apple.com/techpubs/macosx/Essentials/Performance/Carbon/Carbon_and___X_Graphics.html"; target="_blank">here.</a> Applications cannot draw to the windows on the screen, the drawing calls are automatically routed to the offscreen window buffer. All of the window buffers are then composited on the fly to the screen.
  • Reply 12 of 36
    applenutapplenut Posts: 5,768member
    [quote]Originally posted by MajorMatt:

    <strong>Brian's explanation is a tad better than yours, Scott.



    For Apple to sacrafice features for temporary boost speed would be foolish for the future. Lets use this analagous situation: Back in the days of yore when we all used System 6, it was fairly fast, but limited. Then Apple released System 7.0, it was a slower OS by far, it added many things that slowed down the system as a whole. However, as newer hardware is released, that slow OS on a LC2 is blazing on a 6100. Its a matter of time when these speed issues will be illrelavent.</strong><hr></blockquote>





    ape already has made such sacrifices in 10.1



    prime example: the finder when resized no longer dynamically resizes its contents like the finder does in 10.0.
  • Reply 13 of 36
    [quote]Originally posted by Scott H.:

    <strong>



    I can't because none of us knows the exact details of how Apple wrote the display layers.



    Just as an example when a window is resized I would imagine that Quatrz rerenders the rerenders window from scratch.



    Also you seem to think that each window is double buffered. It's the output frame that's double buffered. Of course it's a good thing who ever said it wasn't? Where did you get this idea that UNIX doesn't double buffer?





    Also ...

    I don't think you understand what double buffering is and why it's done.



    [ 01-20-2002: Message edited by: Scott H. ]</strong><hr></blockquote>





    Double buffering is a general term for rendering output to an offscreen buffer, and then copying the changes from the offscreen buffer to a visible frame buffer. The technique of double buffering can be applied to a window or, in the case of games, the entire screen. This can be done for a variety of reasons. In games, double buffering is often used to eliminate tearing (half rendered frames are shown on screen ). Sometimes an application will triple buffer so it can work on one buffer while blitting between the other two. Sometimes a fairly static page is double buffered so the page only has to be rendered once. There are a variety of reasons for double buffering. I described the one which made sense in Quartz.



    There are some implementations of X Windows (UNIX GUI) that double buffer the frame buffer (the buffer in your video card that holds the visible screen contents) . But, in general, X Windows does not double buffer the frame buffer. For instance, XDarwin currently does a form of double buffering called shadow buffering. But this is not done for any performance or functional reason. This was just a quick hack to get XDarwin up and running on Mac OS X.



    Backing store in UNIX X Windows (sort of) provides some of the benefits of window double buffering though. But backing store functionality is not guaranteed, and the X Servers that implement it do not guarantee perfect support. Also, X Windows does have a Double Buffer Extension, but once again X Servers are not required to support it (hence the word "extension"). Since an application programmer cannot rely on DBE or backing store in their X applications (hence the "sort of" in paragraph three), they must write their own double buffering, if they want to ensure their application will double buffer.



    OS X does double buffer every window. From "Inside Mac OS X: System Overview" (get it at <a href="http://www.download.com"; target="_blank">www.download.com</a> ):



    [quote]Each window is represented as a bitmap which contains both translucency (alpha-channel) and anti-alias information. The bitmap is buffered, allowing the window server to "remember" an application's window contents and recomposite it without the application's involvement.<hr></blockquote>





    Anyways, I never claimed to be a Mac expert, and I said that I was speculating (see the first paragraph). Plus, I oversimplified some of issues for the sake of readability. (My posts have been long enough as it is.) However, anyone who writes software knows that sofware design is all about tradeoffs. I thought it would be more useful to attempt to understand every aspect (positive and negative) of these design tradeoffs rather than perpetually focusing on and ranting about the negative (like you Scott).



    However, my theories did not just fall out of the sky either. The theories I presented were based on my own experiences writing a windowing system (I am porting the UNIX X Server to the PC), and my own experiences with operating system development (I used to hack around with FreeBSD for some grad school projects.)



    [ 01-20-2002: Message edited by: Brian J. ]</p>
  • Reply 14 of 36
    serranoserrano Posts: 1,806member
    oooo, burn :eek:
  • Reply 15 of 36
    [quote]Originally posted by havanas:

    <strong>Brian, Interesting theories....

    I also think many OsX apps may be getting sent an update message every available tick while the window is getting resized. I'm actually thinking of creating a timer for my graphical apps to only have them update every 24 or 48 fps kinda like film. Maybe...





    Hey, where do you work?

    I used to live in Eatontown/Red Bank.</strong><hr></blockquote>



    I work out of my apartment. I am trying to get my own company off the ground and am working on my first product right now. I originally came here to work for Lucent (like almost everyone else who lives around here). Is that why you lived there?
  • Reply 16 of 36
    The window isn't double buffered you ****ing moron. How hard is that to understand?
  • Reply 17 of 36
    kickahakickaha Posts: 8,760member
    From 'Quartz Primer', at <a href="http://developer.apple.com/techpubs/macosx/Essentials/QuartzPrimer.pdf"; target="_blank">http://developer.apple.com/techpubs/macosx/Essentials/QuartzPrim er.pdf</a> on page 9:



    "I regularly buffer my windows to protect them from other applications. Should I continue to do this if I use Quartz?



    No. Core Graphics Services automatically buffers your windows so extra buffering is unnecessary and will negatively affect performance on Mac OS X." (Emphasis mine.)



    Run the application QuartzDebug at /Developer/Applications/QuartzDebug.



    Click on 'Show Window List'. The fourth column, on a *per window* basis, indicates whether or not the window is buffered.



    From <a href="http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/WinPanel/index.html"; target="_blank">http://developer.apple.com/tech pubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/WinPanel/index.html</a> in the Cocoa documentation on using NSWindows...



    [quote]

    Setting How To Store the Window's Image





    A window device's backing store type determines how the window's image is stored. It's set when the NSWindow is initialized and can be one of three types.



    A buffered window device renders all drawing into a display buffer and then flushes it to the screen. Always drawing to the buffer produces very smooth display, but can require significant amounts of memory. Buffered windows are best for displaying material that must be redrawn often, such as text.



    A retained window device also uses a buffer, but draws directly to the screen where possible and to the buffer for any portions that are obscured.



    A nonretained window device has no buffer at all, and must redraw portions as they're exposed. Further, this redrawing is suspended when the NSWindow's display mechanism is preempted. For example, if the user drags a window across a nonretained window, the nonretained window is "erased" and isn't redrawn until the user releases the mouse.



    Both retained and nonretained windows are also subject to a flashing effect as individual drawing operations are performed, but their results do get to the screen more quickly than those of buffered windows.



    You can change the backing store type between buffered and retained after initialization using the setBackingType: method.<hr></blockquote>



    Note again that this is done on a per window basis.



    Sorry Scott. Unless you can produce official documentation to validate your position, I'm going to have to say Brian's got you on this one.



    [ 01-20-2002: Message edited by: Kickaha ]</p>
  • Reply 18 of 36
    Brian J.:



    but...

    if ms windows and x windows do do double buffering with every window because it is implemented by the programmer, is the only benifit of osx's double buffering just that it's built into the system and easier for a programmer to write a program? (all the other advantages that you listed didn't seem limited to osx's implementation os double buffering, but a double buffering and single buffering system)



    i mean just going through you list of advantages of the macosx, and it seems that all those are generic double buffering advantages except for the first one. (at least for me, windows seem to move windows around as fast/faster than macosx, contents are restored very quickly, the transparntcy features are not unusably slow, and i can get rid of screen tearing in 3d games by syncing the frames with the monitor refresh rate)



    of course, i can't stop tearing with just plain windows, but since apple is moving towards lcds, tearing in regular windows is a non-issue anyhow.



    i guess my point is, sure, it might be future-proofing, by the speed hit has caused more bad publicity than was worth it, in my humble opinion. generall double buffering code would be cut and pasteable anyhow. (or at least when learning directx, it's in the early chapters)



    Ted
  • Reply 19 of 36
    BOOYAH! Take that!
  • Reply 20 of 36
    synsyn Posts: 329member
    [quote]The window isn't double buffered you ****ing moron. How hard is that to understand? <hr></blockquote>



    Scott H, I think you've outstayed your welcome here. If you're not capable of maintaining a decent conversation about a screen buffer, or refraining yourself from criticizing Apple every other post because they aren't supporting your RagePro, then do us a favor, go do it elsewhere. Hell, go see a hooker and let all that frustration go, it can't be all due to that Rage Pro, can it?



Sign In or Register to comment.