diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-02-24 22:27:30 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-02-24 22:27:30 (GMT) |
commit | 97f268933a65cc3054c72748ff0b8b5042e70c2b (patch) | |
tree | 80db52f17eacb96bcaebcd50fcda403adba827e4 | |
parent | 4ef9e81c777affd140dbda97645b31b7658c7280 (diff) | |
parent | 4ae8ab9d7ce2cde5c798f13a7bccf05976eb5d54 (diff) | |
download | Qt-97f268933a65cc3054c72748ff0b8b5042e70c2b.zip Qt-97f268933a65cc3054c72748ff0b8b5042e70c2b.tar.gz Qt-97f268933a65cc3054c72748ff0b8b5042e70c2b.tar.bz2 |
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.6-integration
* '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-2:
Initialize mem to 0
Force DSFLIP_BLIT unless it's a full flip in DFB
Support for disabling partial flips in dfb
Allow forcing premultiplied format in DFB
Documentation update regarding DFB image providers
Documentation update for DirectFB
Better support tlw transparency in DirectFB
Fix an isOpaque bug in QDirectFBWindowSurface
5 files changed, 80 insertions, 46 deletions
diff --git a/doc/src/platforms/emb-directfb-EmbLinux.qdoc b/doc/src/platforms/emb-directfb-EmbLinux.qdoc index 74f2aaa..9e060f8 100644 --- a/doc/src/platforms/emb-directfb-EmbLinux.qdoc +++ b/doc/src/platforms/emb-directfb-EmbLinux.qdoc @@ -267,7 +267,8 @@ perform well. \o QT_NO_DIRECTFB_IMAGEPROVIDER \o By default Qt will use DirectFB to load QPixmaps from disk/memory. If your DirectFB implementation does not support this it might make sense to -define this. +define this. If you see strange rendering issues with pixmaps that have an +alpha channel defining this could solve the problem. \row \o QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE @@ -327,4 +328,9 @@ QT_DIRECTFB_DISABLE_RASTERFALLBACKS is defined, DirectFB will only return instead of falling back to QRasterPaintEngine. Please note that these defines should only be used when optimizing the application. +\section2 Top level transparency +\note DirectFB supports partially or fully transparent top level windows, +either through QWidget::setWindowOpacity or through setting a non-opaque +background brush. Note that for the latter it is not supported to change an +opaque window to be transparent at runtime. */ diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index cd4d5c2..cffd4e3 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1126,6 +1126,8 @@ bool QDirectFBScreen::connect(const QString &displaySpec) if (displayArgs.contains(QLatin1String("boundingrectflip"), Qt::CaseInsensitive)) { d_ptr->directFBFlags |= BoundingRectFlip; + } else if (displayArgs.contains(QLatin1String("nopartialflip"), Qt::CaseInsensitive)) { + d_ptr->directFBFlags |= NoPartialFlip; } #ifdef QT_DIRECTFB_IMAGECACHE @@ -1139,6 +1141,8 @@ bool QDirectFBScreen::connect(const QString &displaySpec) #endif d_ptr->dfb->SetCooperativeLevel(d_ptr->dfb, DFSCL_FULLSCREEN); + const bool forcePremultiplied = displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive); + DFBSurfaceDescription description; memset(&description, 0, sizeof(DFBSurfaceDescription)); IDirectFBSurface *surface; @@ -1167,7 +1171,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec) description.caps |= capabilities[i].cap; } - if (displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive)) { + if (forcePremultiplied) { description.caps |= DSCAPS_PREMULTIPLIED; } @@ -1217,6 +1221,8 @@ bool QDirectFBScreen::connect(const QString &displaySpec) d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied; break; case QImage::Format_ARGB32: + if (forcePremultiplied) + d_ptr->alphaPixmapFormat = pixelFormat = QImage::Format_ARGB32_Premultiplied; case QImage::Format_ARGB32_Premultiplied: case QImage::Format_ARGB4444_Premultiplied: case QImage::Format_ARGB8555_Premultiplied: @@ -1674,7 +1680,7 @@ bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *d uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl) { - void *mem; + void *mem = 0; const DFBResult result = surface->Lock(surface, flags, &mem, bpl); if (result != DFB_OK) { DirectFBError("QDirectFBScreen::lockSurface()", result); @@ -1683,11 +1689,22 @@ uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFla return reinterpret_cast<uchar*>(mem); } +static inline bool isFullUpdate(IDirectFBSurface *surface, const QRegion ®ion, const QPoint &offset) +{ + if (offset == QPoint(0, 0) && region.rectCount() == 1) { + QSize size; + surface->GetSize(surface, &size.rwidth(), &size.rheight()); + if (region.boundingRect().size() == size) + return true; + } + return false; +} void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags, const QRegion ®ion, const QPoint &offset) { - if (!(flipFlags & DSFLIP_BLIT)) { + if (d_ptr->directFBFlags & NoPartialFlip + || (!(flipFlags & DSFLIP_BLIT) && QT_PREPEND_NAMESPACE(isFullUpdate(surface, region, offset)))) { surface->Flip(surface, 0, flipFlags); } else { if (!(d_ptr->directFBFlags & BoundingRectFlip) && region.rectCount() > 1) { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index a8c4b43..c483020 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -144,7 +144,8 @@ public: NoFlags = 0x00, VideoOnly = 0x01, SystemOnly = 0x02, - BoundingRectFlip = 0x04 + BoundingRectFlip = 0x04, + NoPartialFlip = 0x08 }; Q_DECLARE_FLAGS(DirectFBFlags, DirectFBFlag); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index 6764e75..a8bdb65 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -92,10 +92,6 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect mode = Offscreen; flags = Buffered; } -#else - noSystemBackground = widget && widget->testAttribute(Qt::WA_NoSystemBackground); - if (noSystemBackground) - flags &= ~Opaque; #endif setSurfaceFlags(flags); #ifdef QT_DIRECTFB_TIMING @@ -134,33 +130,35 @@ void QDirectFBWindowSurface::createWindow(const QRect &rect) if (!layer) qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); + updateIsOpaque(); + DFBWindowDescription description; memset(&description, 0, sizeof(DFBWindowDescription)); + description.flags = DWDESC_CAPS|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT; description.caps = DWCAPS_NODECORATION; - description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY; -#if (Q_DIRECTFB_VERSION >= 0x010200) - description.flags |= DWDESC_OPTIONS; -#endif + description.surface_caps = DSCAPS_NONE; + imageFormat = screen->pixelFormat(); - if (noSystemBackground) { + if (!(surfaceFlags() & Opaque)) { + imageFormat = screen->alphaPixmapFormat(); description.caps |= DWCAPS_ALPHACHANNEL; #if (Q_DIRECTFB_VERSION >= 0x010200) + description.flags |= DWDESC_OPTIONS; description.options |= DWOP_ALPHACHANNEL; #endif } - + description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(imageFormat); description.posx = rect.x(); description.posy = rect.y(); description.width = rect.width(); description.height = rect.height(); - description.surface_caps = DSCAPS_NONE; + + if (QDirectFBScreen::isPremultiplied(imageFormat)) + description.surface_caps = DSCAPS_PREMULTIPLIED; + if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) description.surface_caps |= DSCAPS_VIDEOONLY; - const QImage::Format format = (noSystemBackground ? screen->alphaPixmapFormat() : screen->pixelFormat()); - description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); - if (QDirectFBScreen::isPremultiplied(format)) - description.surface_caps = DSCAPS_PREMULTIPLIED; DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); @@ -182,7 +180,6 @@ void QDirectFBWindowSurface::createWindow(const QRect &rect) Q_ASSERT(!dfbSurface); dfbWindow->GetSurface(dfbWindow, &dfbSurface); - updateFormat(); } static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect) @@ -267,15 +264,17 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) } } else { // mode == Offscreen if (!dfbSurface) { - dfbSurface = screen->createDFBSurface(rect.size(), screen->pixelFormat(), QDirectFBScreen::DontTrackSurface); + dfbSurface = screen->createDFBSurface(rect.size(), surfaceFlags() & Opaque ? screen->pixelFormat() : screen->alphaPixmapFormat(), + QDirectFBScreen::DontTrackSurface); } } if (result != DFB_OK) DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); #endif } - if (oldSurface != dfbSurface) - updateFormat(); + if (oldSurface != dfbSurface) { + imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid; + } if (oldRect.size() != rect.size()) { QWSWindowSurface::setGeometry(rect); @@ -296,7 +295,7 @@ void QDirectFBWindowSurface::setPermanentState(const QByteArray &state) if (state.size() == sizeof(this)) { sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData()); Q_ASSERT(sibling); - sibling->setSurfaceFlags(surfaceFlags()); + setSurfaceFlags(sibling->surfaceFlags()); } } @@ -359,8 +358,6 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff); const QRect windowGeometry = geometry(); #ifdef QT_DIRECTFB_WM - const bool wasNoSystemBackground = noSystemBackground; - noSystemBackground = win->testAttribute(Qt::WA_NoSystemBackground); quint8 currentOpacity; Q_ASSERT(dfbWindow); dfbWindow->GetOpacity(dfbWindow, ¤tOpacity); @@ -368,18 +365,9 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, dfbWindow->SetOpacity(dfbWindow, windowOpacity); } - setOpaque(noSystemBackground || windowOpacity != 0xff); - if (wasNoSystemBackground != noSystemBackground) { - releaseSurface(); - dfbWindow->Release(dfbWindow); - dfbWindow = 0; - createWindow(windowGeometry); - win->update(); - return; - } screen->flipSurface(dfbSurface, flipFlags, region, offset); #else - setOpaque(windowOpacity != 0xff); + setOpaque(windowOpacity == 0xff); if (mode == Offscreen) { screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0); } else { @@ -442,11 +430,6 @@ IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget return dfbSurface; } -void QDirectFBWindowSurface::updateFormat() -{ - imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid; -} - void QDirectFBWindowSurface::releaseSurface() { if (dfbSurface) { @@ -465,9 +448,37 @@ void QDirectFBWindowSurface::releaseSurface() } } +void QDirectFBWindowSurface::updateIsOpaque() +{ + const QWidget *win = window(); + Q_ASSERT(win); + if (win->testAttribute(Qt::WA_OpaquePaintEvent) || win->testAttribute(Qt::WA_PaintOnScreen)) { + setOpaque(true); + return; + } -QT_END_NAMESPACE + if (qFuzzyCompare(static_cast<float>(win->windowOpacity()), 1.0f)) { + const QPalette &pal = win->palette(); -#endif // QT_NO_QWS_DIRECTFB + if (win->autoFillBackground()) { + const QBrush &autoFillBrush = pal.brush(win->backgroundRole()); + if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) { + setOpaque(true); + return; + } + } + + if (win->isWindow() && !win->testAttribute(Qt::WA_NoSystemBackground)) { + const QBrush &windowBrush = win->palette().brush(QPalette::Window); + if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) { + setOpaque(true); + return; + } + } + } + setOpaque(false); +} +QT_END_NAMESPACE +#endif // QT_NO_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index 9568067..a6138f6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -97,8 +97,8 @@ public: IDirectFBWindow *directFBWindow() const; #endif private: + void updateIsOpaque(); void setOpaque(bool opaque); - void updateFormat(); void releaseSurface(); QDirectFBWindowSurface *sibling; @@ -113,7 +113,6 @@ private: #endif DFBSurfaceFlipFlags flipFlags; - bool noSystemBackground; bool boundingRectFlip; #ifdef QT_DIRECTFB_TIMING int frames; |