Introducing the Microsoft Direct2D API
One of the challenging aspects of working on a product development team is that you often have to keep the subject of your work secret for various reasons. I’m a Dev Lead in the Windows Desktop Graphics organization, and my team has been working quietly for the past year on an exciting new graphics technology – Direct2D –that was announced recently at the Professional Developer’s Conference (PDC) in Los Angeles.
Direct2D (or D2D) is a native immediate-mode 2D graphics rendering API that is built on top of Direct3D, and offers some compelling performance and visual quality improvements over GDI and GDI+ :
· Software fallback when hardware isn’t available
· Interoperability with GDI, GDI+, and Direct3D
· ClearType text rendering
· Per primitive antialiasing
· Device-independent coordinate system
· Draw and fill commands for geometries (lines, curves) and bitmaps
· Solid color, linear, radial, and bitmap brushes.
· Rendering to intermediate layers
· Rich geometry operations (eg. unions, intersections, widening, outlining, etc)
· Server-side rendering
· Preservation of rendering state
Since Direct2D is now public, I can finally talk about it, and this blog is intended to provide a forum for sharing information and tips.I encourage you to send me your feedback and comments, and I will share them with the rest of the development team. While I can’t promise that we’ll act on every piece of feedback, we will take everything that you submit seriously, and we will use the data to better understand your development priorities.
Back to the Future
Do we really need another 2D API? To answer this question, we need to backtrack a little bit and discuss some ancient graphics history. Windows applications continue to rely overwhelmingly on GDI/GDI+2D graphics technologies that were designed for hardware that shipped in the 1990’s. Hardware in that era was optimized largely for simple, fixed-function scenarios (eg. BitBlt, StretchBlt, DrawRect , etc). Modern graphics hardware has evolved dramatically since that time. Much of the processing that used to occur in software has now migrated down to the video card’s Graphics Processing Unit (GPU) in the form of programmable pixel and vertex shaders; which increase performance by moving pixel data closer to where it will be manipulated & consumed, in massively parallel (SIMD) fashion. These changes have staggering implications for graphics applications. Expensive pixel-processing operations can be offloaded from the CPU to the GPU which, in turn, frees the CPU to take on other useful tasks, such as creating rich UI, driving animations, doing computations, etc. It also allows applications to scale up primitive counts dramatically with minimal CPU impact.
One of the first proposals on the table was to update GDI/GDI+ to take advantage of these technologies; however, as we surveyed the requirements, we ran into some fundamental limitations that would have made the effort very difficult. For example, GDI/GDI+ are limited to 32 bits-per-pixel, and there’s a ton of stuff – both public and internal – that would need to be revamped or extended (eg. RGBQUAD, COLORREF, PALETTEENTRY) to support high dynamic range pixel formats beyond 32 bits-per-pixel. Similarly, there are quality and performance issues: modulo ClearType text, GDIcan only produce aliased graphics (jaggies) and, while GDI+can render anti-aliased graphics, it can only do so in software. GDI uses an integer coordinate system, so it can't take advantage of improvements related to sub-pixel positioning. Another fundamental problem is that GDI/GDI+ , and Direct3D are wholly separate graphics subsystems, with their own formats, memory structures, and synchronization constructs. Getting all of these moving parts to work in unison would have been a huge challenge, to say the least, so we went back to the drawing board to consider an alternative proposal: to create a new 2D graphics stack on top of Direct3D-- which would interoperate with the latest Direct3Dhardware -- while also providing a migration path for GDIand GDI+ applications.
When we compared the development costs of these two proposals, it became clear that creating a new graphics stack would take far less time, would avoid destabilizing the huge number of GDIand GDI+applications, and would enable us to provide a more cohesive, interoperable, and forward-thinking API. So, we embarked on building the new API, which went through several geeky name changes, until it emerged from the primordial acronym-soup as Direct2D. This isn’t surprising, given that my team is part of the same group that produces Direct3D. It was a natural fit.
We started with some fundamental goals for Direct2D:
· Native Code – Should be accessible to the widest possible community of developers. Minimal footprint for native code callers, and also callable by managed code.
· Lightweight COM – Should use C++ style interfaces which model Direct3D usage. No support for proxies, cross-process remoting, BSTRs, VARIANTs, COM registration (e.g. the heavyweight stuff).
· Immediate Mode – Simple BeginDraw/Draw/EndDraw semantic. No expensive retained tree structures.
· Hardware – Should leverage available hardware for rendering.
· Scalable – Pay-for-Play. Performance and memory usage should scale as linearly as possible while primitive counts increase. No hidden costs. Hardware improvements should scale performance accordingly.
· Policy-Free – Should impose as little policy as possible on callers; that is, it should seek to do no more (and no less) than what the caller expects it to do. Minimal amount of abstraction.
· Software Fallback – Should automatically fall back to software when hardware isn’t available (eg. session 0, server rendering scenarios).
· High Quality Output – Should produce superb anti-aliased and aliased content. ClearType for text.
· High Performance – Should leverage GPU hardware as much as possible and minimize CPU usage.
· Interoperable – Should permit rendering to and from a Direct3D surface, as well as to and from a GDI/GDI+ device context (HDC). Serialization of content to and from surfaces and device contexts must be explicit and predictable. Should work seamlessly with other native Windows technologies (DirectWrite, Windows Imaging Codecs, etc).
· Direct3D 10.1 – Should utilize D3D10.1 (and/or D3D10Level9) for hardware support.
· Device-Independent Coordinate System – Should allow applications to be written that automatically handle DPI changes and differences.
· Rich Geometry – Should provide a rich set of functions for both defining geometries and performing common geometric operations (eg. combining, intersecting)
Direct2D Team Members
I want to thank the following folks for their tireless passion and dedication to making D2D possible:
Mark Lawrence, Chris Raubacher, Tom Mulcahy, Anthony Hodsdon, Miles Cohen, Ben Constable, Leonardo Blanco, Alexander Stevenson, Megha Jain, Kam VedBrat, Andy Precious, Brett Bloomquist, Bilgem Cakir, Chris Chui, Bob Brown, Samrach Tun, Sriya Blanco, Jason Hartman
Furthermore, I’d like to acknowledge the following folks for understanding the importance of this new technology and funding the effort:
Anuj Gosalia, Anantha Kacherla, Jeff Norris, Todd Frost
Watch the Platform Overview PDC session: https://channel9.msdn.com/pdc2008/PC04/
Watch the Direct2D and DirectWrite PDC session: https://channel9.msdn.com/pdc2008/PC18/
Also, I'm posting a Direct2D whitepaper that was distributed at the PDC. Future posts will drilldown into interesting code examples.
More Direct2D Blogs
Tom Mulcahy -- Tom is a Software Design Engineer on the Direct2D team, and owns a good swathe of infrastructure (bitmaps and texture management, WIC interop, clipping, etc). Prior to Direct2D, Tom worked on WPF and is widely regarded as our resident video guru.
Mark Lawrence -- Mark is a Senior Software Design Engineer on the Direct2D team, and driving force behind the design and philosophy of the Direct2D API. He brings a ton of experience from his previous work on WPF, Windows Print architecture, and private industry.
Ben Constable -- Ben is a Senior Software Design Engineer on the Direct2D team, and implemented all of the Direct3D and GDI Interop functionality within Direct2D. He is a self-described "graphics nerd" who brings considerable experience in 2D and 3D rendering to the team, and has contributed to numerous Microsoft products (Visual Studio, Windows, Office, SQL, etc).