Search code examples
javaawtalpha-transparency

java performance hit of drawing with transparent color?


Does anyone know if filling rectangle with fully transparent color (alpha = 0) creates a performance hit? Or is it optimized and skipped entirely? I am talking about code like this:

Graphics g;
....
g.setColor(new Color(0xFF,0xFF,0xFF,0x00));
g.fillRect(0, 0, width, height);    // <= does this take any CPU?

Solution

  • Not sure whether this can be considered as an "acceptable" answer, but maybe helpful at least:

    As pointed out in the comments: It depends.

    The Java Graphics class is a very thick abstraction layer. You can use it to render on every Operating System, with every JVM, with every Graphics Card, with every driver, and even then, still, using different methods.

    As an example: On a usual Windows machine, you may explictly specify whether you want an OpenGL accelerated graphics pipeline or a Direct3D based graphics pipeline, with the -Dsun.java2d.opengl or -Dsun.java2d.d3d flags. This might cause the actual g.fillRect call to either end up in the corresponding D3DRenderer or the OGLRenderer method (*) - and from there on, it's a matter of the driver to figure out whether it actually has to do something for this call (considering the current color is transparent).


    Interestingly, your comment said // <= does this take any CPU?. In most cases, the CPU will not care about whether the color is transparent or not. It will just forward the call to the rendering pipeline. So in doubt, it imposes a load on the GPU.

    For a completely opaque color, filling a rectangle is trivial: The existing pixels are simply replaced, as one block. The fact that the color is transparent makes things a bit more difficult: The new color has to be "mixed" with the color of the pixels that have already been there. In the case of a completely transparent color, this would not be necessary, but I doubt that this is treated as a special case.


    Usually, painting a single rectangle (regardless of the color) should not have a noticable performance impact at all: It takes a few microseconds, on the GPU. If you are about to paint many rectanges (really many), then this question might become more relevant - but in this case, you'd rather add a query like

    if (color.getAlpha() > 0) paintMillionsOfRectangles();
    

    in order to avoid the loop that does millions of calls to g.fillRect, which might impose a higher computational load (particularly: on the CPU) than the actual operations that are done due to the fillRect calls (which are done in hardware, on the GPU).


    (*) I'm not entirely sure whether these are really the right methods - again, the abstraction layer is very thick...