Final Countdown for GDI

After writing my previous post, I happened to pass by my archival bookshelf, and an opus caught my eye: Programming Windows by Charles Petzold from 1988. It has been ages since I last opened this classic, and yet, if I narrow my eyes a bit, it looks like it was written yesterday. What we call Win32 API today was just Windows API in 1988, but the 16-bit ancestor is amazingly similar to its 32-bit offspring. Even if we program in a high-level language like C# and use the .NET Framework, this ancient API dictates a lot we do with managed classes. Especially this goes for GDI (in Windows API) and GD I+ (in .NET Framework).

When Graphics Device Interface (GDI) was introduced, there were no hardware-accelerated display adapters. All the grunt work of calculating logical coordinates to physical pixels had to be done by the main processor, either in the application program or in Windows (i.e. GDI). Because performance was rationed, optimizing graphics performance was a joint venture between Windows and the application. Windows tried to be as helpful as possible, but the decisions were left to the application that knew what had to be done and was able to choose the right strategy.

This strategy was known as the “mapping mode” that is still present in GDI+ as the GraphicsUnit property of the Graphics class. In fact all major structures and functions in GDI find their counterparts in GDI+ as properties and methods of Graphics: hDC -> Graphics, SetViewportExt() -> PageScale, SetViewportOrg() -> TranslateTransform(), MoveTo()/LineTo() -> DrawLine(), Ellipse() -> DrawEllipse(), etc. to name just a few. This is all logical because GDI+ has to call GDI to get the pixels all the way to the display device.

Now enter Windows Presentation Foundation! WPF is different because it does not use GDI but gets its message to the display surface through DirectX. Game developers and enthusiasts have known for years that DirectX can use hardware acceleration, which GDI can’t. The mapping mode is gone: WPF uses device-independent pixels, each of which is defined to be 1/96th of an inch. Mapping to physical pixels is done by DirectX assisted by display adapter hardware, which the application can be totally agnostic of.

Drawing methods like DrawEllipse() are also gone – you just place graphic elements like Ellipse or LinearGradientBrush inside other graphic elements, and WPF gets them painted. I would see this as a significant move from imperative to declarative programming, which becomes more obvious if you create these elements in markup (XAML) rather than code (C#). In plain English this means that you tell WPF what you want, not how to do it. I like declarative programming!

I now place Programming Windows back in my shelf next to Kernighan & Ritchie and The MS-DOS Encyclopedia. Sleep well, my friend!

2 Comments

  1. Jayvardhan Patil:

    Hello Hex,

    This is a wonderful post and you have presented a lot of knowledge in small post.

    For those who have extensively worked on GDI++ in .NET, their mind will automatically start analyzing why something works like this in WPF and not in .NET 2.0 and now I have started feeling that I do not know GDI++ well.

    I was working as a GDI++ programmer with Tieto (now working as a MOSS2007 developer) for many years (almost 2) and I didn’t know that GDI++ is just a wrapper to GDI.

    While working with WPF was cool and a complete new experience, but I didn’t got chance to work on it extensively.

    Jay
    http://codeforfuture.com

  2. KrisBelucci:

    Hi, good post! I have been wondering about this issue, so thanks for posting.