On Windows it looks like the rendering code produces an alpha channel no matter what the transparency / drop shadow setting of the ComponentPeer
juce_win32_Windowing.cpp
static bool alwaysUseARGB = isGraphicsCard32Bit(); // NB: for 32-bit cards, it's faster to use a 32-bit image.
const Image::PixelFormat format = (transparent || alwaysUseARGB) ? Image::ARGB : Image::RGB;
I agree with the comment that it is faster to use an image with 32 bits per pixel. But I would expect that it is slower to do the work of producing the alpha mask. For example, when drawing text into a Graphics using the software renderer, RenderingHelpers goes into PixelARGB::blend() instead of PixelRGB::blend(), because the destination is Image::ARGB instead of Image::RGB.
Really, what we want during ComponentPeer::handleRepaint() is to create an Image with 32 bits per pixel (i.e. pixelStride == 4) but whose format is Image::RGB. This way all of the blending code will go through the faster path where the destination is PixelRGB instead of PixelARGB. This will certainly speed up rendering across the board.
However, there’s a problem. While the Image class is very well designed and supports flexible layout of image data via the lineStride and pixelStride members, the rendering code breaks on certain combinations of pixelStride and ImageFormat!!! Case in point:
juce_RenderingHelpers.h
template <class Iterator, class DestPixelType>
void renderSolidFill (...)
{
jassert (destData.pixelStride == sizeof (DestPixelType));
This makes it impossible to render into an Image whose ImageFormat == Image::RGB but whose pixelStride == 4.
Another example:
juce_RenderingHelpers.h
template <class DestPixelType, class SrcPixelType, bool repeatPattern>
class ImageFill
...
dest++ ->blend (sourceLineStart [repeatPattern ? (x++ % srcData.width) : x++], (uint32) alphaLevel);
Here dest++ is the problem, because it ignores srcData.pixelStride and destdata.pixelStride and assumes that the stride is 3 or 4 depending on the DestPixelType template parameter.
Can we please remove the assumption in the software renderer that pixelStride == sizeof (DestPixelType) and use the pixelStride field from the Image::BitmapData for image fills, solid fills, and gradient fills?
I believe that we will improve the performance of the software renderer if we make these changes, since we will be switching to ARGB on RGB blend instead of ARGB on ARGB blend.