Monday, April 13, 2009

Revisiting the Carousel - II

I finally found a solution for the speed problem of rendering the carousel icons: caching the image. After a big wild goose chase, the solution was under my very nose all the time. To see the dramatic performance improvement, open the CarouselDemo2 project I published on my last post, and go to the image.h file. At the top of the file, there is a private method named CreateImage, where the IImage object is created. Right after creating the object:

hr = spFactory->CreateImageFromBuffer(m_pImageData, m_nImageSize, BufferDisposalFlagNone, &m_spImage);

just add the following lines:

if(SUCCEEDED(hr))
hr = m_spImage->SetImageFlags(ImageFlagsCaching);

Now run the demo again and see how much the performance has improved!

Now that this issue is solved, let me tell you about the wild goose chase. My original idea was to use the AlphaBlend API that has been added to Windows Mobile 5. This function does support per-pixel alpha blending so it looked very promising. Unfortunately, there seems to be no easy way to load a 32 bpp bitmap image with Windows Mobile. I tried using SHLoadImageResource (I read somewhere that this would keep the alpha channel intact) but the returned HBITMAP was smashed down to 16 bpp, so the alpha channel was lost. I still have not given up to find an easy way to load the PNG files into memory, and when I do you will be the first to know. Oh, by the way, if you do know please post a comment here!

3 comments:

Miguel Branco said...

Fantástico! Este post sozinho vale o mundo inteiro.

Não sei porque é que isto não está escrito em letras grandes na homepage da msdn.

Muitíssimo obrigado, fiquei fã ;)

João Paulo Figueira said...

Obrigado pelo comentário! Desde que descobri esta funcionalidade do interface IImage, tenho-a usado muito mas acho que a performance de pintura deixa a desejar quando se pintam imagens PNG com transparências. Estou à procura de uma alternativa.

Miguel Branco said...

Comparando com a performance sem Cache é uma maravilha!

Estou a fazer uma aplicação com animações algo complexas e não conseguia mover 2 PNGs no ecrã sem solavancos.
Agora a conversa é outra.

Provavelmente estou a ensinar a missa ao padre, mas para fazer aplicações que desenhem PNGs imóveis, recomendo fazer buffering para um HDC auxiliar, mantê-lo em memória e na rotina de desenho apenas fazer um BitBlt para o hdc "real".