diff -r dee5afe5301f -r 3f74d0d4af4c src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp Mon Mar 15 12:43:09 2010 +0200 +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp Thu Apr 08 14:19:33 2010 +0300 @@ -61,6 +61,7 @@ #endif , flipFlags(flip) , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) + , flushPending(false) { #ifdef QT_NO_DIRECTFB_WM mode = Offscreen; @@ -80,6 +81,7 @@ #endif , flipFlags(flip) , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) + , flushPending(false) { SurfaceFlags flags = 0; if (!widget || widget->window()->windowOpacity() == 0xff) @@ -92,10 +94,6 @@ 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 +132,35 @@ 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 +182,6 @@ Q_ASSERT(!dfbSurface); dfbWindow->GetSurface(dfbWindow, &dfbSurface); - updateFormat(); } static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect) @@ -267,15 +266,17 @@ } } 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,32 +297,23 @@ if (state.size() == sizeof(this)) { sibling = *reinterpret_cast(state.constData()); Q_ASSERT(sibling); - sibling->setSurfaceFlags(surfaceFlags()); + setSurfaceFlags(sibling->surfaceFlags()); } } -static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int dx, int dy) -{ - const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() }; - surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy); - const DFBRegion region = { rect.x + dx, rect.y + dy, r.right() + dx, r.bottom() + dy }; - surface->Flip(surface, ®ion, DSFLIP_BLIT); -} - bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) { - if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.isEmpty()) + if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.rectCount() != 1) return false; - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); - if (region.rectCount() == 1) { - scrollSurface(dfbSurface, region.boundingRect(), dx, dy); + if (flushPending) { + dfbSurface->Flip(dfbSurface, 0, DSFLIP_BLIT); } else { - const QVector rects = region.rects(); - const int n = rects.size(); - for (int i=0; iSetBlittingFlags(dfbSurface, DSBLIT_NOFX); + const QRect r = region.boundingRect(); + const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() }; + dfbSurface->Blit(dfbSurface, dfbSurface, &rect, r.x() + dx, r.y() + dy); return true; } @@ -359,8 +351,6 @@ 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 +358,9 @@ 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 { @@ -396,6 +377,7 @@ timer.restart(); } #endif + flushPending = false; } void QDirectFBWindowSurface::beginPaint(const QRegion &) @@ -403,6 +385,7 @@ if (!engine) { engine = new QDirectFBPaintEngine(this); } + flushPending = true; } void QDirectFBWindowSurface::endPaint(const QRegion &) @@ -442,11 +425,6 @@ return dfbSurface; } -void QDirectFBWindowSurface::updateFormat() -{ - imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid; -} - void QDirectFBWindowSurface::releaseSurface() { if (dfbSurface) { @@ -465,9 +443,37 @@ } } +void QDirectFBWindowSurface::updateIsOpaque() +{ + const QWidget *win = window(); + Q_ASSERT(win); + if (win->testAttribute(Qt::WA_OpaquePaintEvent) || win->testAttribute(Qt::WA_PaintOnScreen)) { + setOpaque(true); + return; + } + + if (qFuzzyCompare(static_cast(win->windowOpacity()), 1.0f)) { + const QPalette &pal = win->palette(); + + 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 - -