[Solved] Setting Qt for Embedded Pixel Type to 24bpp BGR
-
I am trying to display my Qt for Embedded Linux application on a 24-bit framebuffer using BGR. I've been reading the QScreen docs:
http://doc.qt.nokia.com/4.7-snapshot/qscreen.html#pixeltype-var
It sounds like the only way to get BGR is to subclass QScreen in a custom screen driver plugin? Is that true? Is there an easier way to tell Qt to use 24-bit BGR?
On my i.mx51 evaluation board, RGB 16 bit and 32 bit work fine. At 24 bit, the hardware wants BGR.
Thanks in advance!
Matt
-
After some more research, this looks like an issue with my framebuffer driver.
Qt should auto detect and use BGR if the kernel reports BGR in use:
struct fb_var_screeninfo is a kernel data structure that includes bitfields defining red, blue, green, and transparent.
Qt calls ioctl FBIOGET_VSCREENINFO to populate fb_var_screeninfo
Qt detects Pixel Type and Format using fb_var_screeninfo
./gui/embedded/qscreenlinuxfb_qws.cpp
@
1286 void QLinuxFbScreen::setPixelFormat(struct fb_var_screeninfo info)
1287 {
1288 const fb_bitfield rgba[4] = { info.red, info.green,
1289 info.blue, info.transp };1309 case 24: {
1310 const fb_bitfield rgb888[4] = {{16, 8, 0}, {8, 8, 0},
1311 {0, 8, 0}, {0, 0, 0}};
1312 const fb_bitfield bgr888[4] = {{0, 8, 0}, {8, 8, 0},
1313 {16, 8, 0}, {0, 0, 0}};
1314 if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) {
1315 format = QImage::Format_RGB888;
1316 } else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) {
1317 format = QImage::Format_RGB888;
1318 pixeltype = QScreen::BGRPixel;
1319 }
1320 break;
1321 }
@format is set properly to QImage::Format_RGB888, so the branch at 1314 is taken. If the kernel were reporting a BGR bitfield, then the branch at 1316 would be taken instead and Qt would display BGR pixels.
Any advice on where to look in the Kernel 2.6.35.3 is appreciated!
Thanks,
Matt -
Matt:
I am using imx6 with Qt 4.8.2.
I have meet the same question.
so, I start to read Qt opensource.
please look at this source../gui/embedded/qscreen_qws.cpp
Line 1208void qt_blit_setup(QScreen *screen, const QImage &image,
const QPoint &topLeft, const QRegion ®ion)
{
switch (screen->depth()) {
#ifdef QT_QWS_DEPTH_32
case 32:
if (screen->pixelType() == QScreen::NormalPixel)
screen->d_ptr->blit = blit_32;
else
screen->d_ptr->blit = blit_template<qabgr8888, quint32>;
break;
#endif
#ifdef QT_QWS_DEPTH_24
case 24:
if (screen->pixelType() == QScreen::NormalPixel)
screen->d_ptr->blit = blit_qrgb888;
else
screen->d_ptr->blit = blit_24;
break;
#endif#ifdef QT_QWS_DEPTH_16
case 16:
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
if (screen->d_ptr->fb_is_littleEndian)
screen->d_ptr->blit = blit_16_bigToLittleEndian;
else
#endif
if (screen->pixelType() == QScreen::NormalPixel)
screen->d_ptr->blit = blit_16;
else
screen->d_ptr->blit = blit_template<qbgr565, quint16>;
break;
#endif32bit, 16bit are same.
24bit is different.
why 24bit is different?
I have modified 24bit to same as 32bit and 16bit.
The color is all right.
Is this a bug for Qt?
modified code is
#ifdef QT_QWS_DEPTH_24
case 24:
if (screen->pixelType() == QScreen::NormalPixel)
screen->d_ptr->blit = blit_24;
else
screen->d_ptr->blit = blit_template<qrgb888, quint24>;
break;
#endif