I have a Windows CE application that uses a lot of vector graphics and in places is quite slow. I’m currently using GDI for rendering via a bitmap for flicker free refreshes. Typically, I’m windowing in on part of a large 3d map. On some devices (e.g. 166mhz SH4), this gets slow with 3-5 second refresh times for big datasets. My question is this;
-
Has anyone done any comparisons on the relative speed of graphic operations on Windows mobile versus Win32. Put another way, are profiling results from a Win32 version of the software applicable to a WinCE version, assuming we are only looking a GDI calls.
-
Has anyone tried profiling onboard on a WinCE platform (C++ app), if yes, using what tools.
-
Is anyone aware of any methods to improve drawing speed on Windows CE. I’m currently looking at FastGraph following feedback from a previous question, but this is a slightly longer term solution. Bad and all as it is, I’m looking for something faster to implement for an upcoming release.
Before Windows CE 6.0 – therefore including all Windows Mobile/Windows Embedded Handheld versions – the graphics code was implemented in another process (GWES.EXE), requiring a cross-process call every time you make a GDI call. CE 5.x cross-process calls are much cheaper than on the desktop, but still more expensive than a plain function call or a call into kernel mode.
On the desktop, GDI is implemented in kernel mode since NT 4.0. In the original NT 3.1, it was like the CE model, cross-process calls. To mitigate the overhead of cross-process calls or user/kernel mode switches, desktop GDI batches up operations on the user-mode side until you do something that requires it to flush the queue – like selecting a different pen or brush, or using one of the legacy functions that returns something other than
BOOL– or the buffer is full, or you explicitly flush it by callingGdiFlush.Windows CE does not have this batching capability – all calls result in a direct call to the GWES process, making it a lot slower. You can mitigate it by doing as much work as possible in each call. If you need a complex line, consider Polyline rather than individual MoveToEx/LineTo calls. Try to only touch each pixel once rather than rendering overlapping objects, and make use of the invalid region to only paint parts of the screen that need repainting (use
GetUpdateRgnorGetUpdateRectbut do it before callingBeginPaint, which marks the region valid).The CE graphics acceleration model is fairly basic, being based around bit-blits. It doesn’t support the larger set of capabilities that Windows 2000-model desktop device drivers support. Whether any acceleration is available depends on whether the hardware even has an accelerator chip – many devices will use the LCD controller embedded in the application processor, which usually doesn’t do any acceleration.
You can simulate CE’s behaviour on the desktop by disabling batching, using
GdiSetBatchLimitto set the limit to 1. Also consider using the SVGA graphics driver to disable acceleration. On Windows Vista or Windows 7, GDI is not accelerated if you’re using the Aero environment, all operations are implemented in software, although Windows 7 added back some new bit-blit hardware acceleration capabilities.Windows CE 6.0 has a new kernel and process model, which moves GDI into kernel mode as on desktop Windows (before Vista), so the cost of calling a GDI function should be slightly reduced. There is still no batching.