You are not logged in.

1

Wednesday, June 20th 2012, 9:51pm

Potential OpenGL2 paint engine bugs

I've encountered a few issues with the OpenGL2 paint engine recently and I am wondering if they are bugs, if they have workarounds or if I am potentially setting things up correctly. The latter I feel is unlikely as they are all reproducible in a very bare-bones Qt app.

The first two issues are related to rendering text and appear to only occur when cached glyphs are being used. Both problems go away when the pixel dimensions of the drawn text get large enough that Qt decides not to cache them.

I'm using Qt 4.8.0, which I'm fairly certain is relevant as the Qt code that appears to be causing both issues looks like it was added in 4.8.0 - it involves using the SRGB framebuffer extension for font gamma correction. I was getting black (or very dimly colored) text when its pixel size went below 64 (which is the pixel size Qt defines as being too big to cache). I also noticed that this only occurs when rendering to a QGLFramebufferObject. Rendering directly to a QGLWidget results in correctly colored text. When I went through the code and noticed that Qt performs gamma correction with FRAMEBUFFER_SRGB_EXT under certain circumstances I set the FBO internal texture format to GL_SRGB8_ALPHA8 and this fixed the coloring problem. That said this doesn't seem to be documented anywhere and it certainly wasn't clear to me that I would needed to make a change until actually wading through Qt code. I should note that this only occurs on Windows. There are OS related ifdefs around the srgb fbo code and I assume that on the Mac that code may not be hit in my case.

The other text issue also occurs when drawing with cached glyph textures. It's a bit more obscure in that it only occurs on Windows machines with NVIDIA cards. I've looked through most (if not all) of the text artifact related bugs in the Qt bug tracker and it seems that they all claim to be fixed before or by 4.8.0 or have workarounds and none seem to be precisely what I'm experiencing. The artifacts only occur when rendering to a buffer with alpha (i.e. if I'm rendering to a QGLWidget they only appear when I explicitly call setAlpha(true)). They always appear when rendering to a QGLFramebufferObject. The attached screenshot ogl_font_artifacts.png shows what I'm talking about. The top image is rendering to a QGLWidget with no alpha. The bottom two are rendered in precisely the same way to a QGLWidget with alpha. Note that at a pixel size of 64 or greater the artifacts go away. Also note that results are identical to the bottom image when rendering to an fbo. Because it only happens when the target paint device has an alpha channel I'm inclined to believe this is also related to the srgb fbo code as an alpha channel is what causes (in my case) Qt to actually hit that code. I haven't figured out a workaround for this yet, other than rendering to a QGLWidget but that would significantly complicate our code and doesn't seem like a reasonable solution at this point.

My final issue also appears to be GPU-vendor specific but this time the problem is on ATI cards (both Mac and Windows). It does not occur when rendering to a QGLWidget, only when rendering to a QGLFramebufferObject. When attempting to draw perfectly horizontal lines with QPainter::drawLine the result is occasional missing lines or lines that are too thick (by a pixel). The attached image ogl_line_glitch.png makes it pretty clear. The lines must be perfectly horizontal (to within some small floating point error). My workaround is to simply add some tiny fractional amount (like 0.001) to either the line start or end point y-coordinate. My guess is that there is a difference in how ATI and NVIDIA handle floating point rounding (though I'm not really an expert) and that on ATI cards occasionally a round-down occurs when it doesn't on NVIDIA cards. Since the ogl2 paint engine renders all lines with triangle strips this round down will result in either no line - where the y-coordinates of each triangle vertex is the same, resulting in degenerate triangles - or a 1px too thick line - where just one or two of the triangle vertex y-coords is rounded down. This is just speculation.

The only issue that doesn't have a reasonable workaround is the artifacts in text. If anyone has a potential solution it would be greatly appreciated, as would any feedback. I'll also post bug reports but the unfixed issue I'd like to get figured out sooner than later if that's possible. Thanks!
Aztral has attached the following files:

2

Wednesday, August 1st 2012, 2:03pm

Hi,

I experienced what I think is the same problem you refer to about text rendering artifacts in Qt 4.8. It is also mentioned in a bug report here:
https://bugreports.qt-project.org/browse/QTBUG-26126

The issue specificallly seems to happen when rendering text to a QGLWidget that has alpha channel enabled. I found a patch that fixes the problem for me: if you comment out "|| d->device->alphaRequested()" on line 1523 of qpaintengineex_opengl2.cpp then that prevents it from switching the glyph type to QFontEngineGlyphCache::Raster_A8 which is the type that has the bug. Note: this is a work around not a bug fix, but it doesn't seem to have any side effects that I can tell.

3

Wednesday, August 1st 2012, 6:41pm

That does indeed seem to be the same issue. I submitted a couple of bug reports with demo apps and both were verified.

Horizontal Line Bug: https://bugreports.qt-project.org/browse/QTBUG-26447
Text Rendering Bug: https://bugreports.qt-project.org/browse/QTBUG-26444

I can reproduce the text artifacts rendering to both a QGLWidget and QGLFramebufferObject as long as the alpha channel is enabled as you mention. Your fix should certainly work, and Qt also provided a patch, but for a number of reasons we're contemplating implementing our own workaround that doesn't involve modifying the Qt source.