src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
changeset 19 fcece45ef507
parent 18 2f34d5167611
equal deleted inserted replaced
18:2f34d5167611 19:fcece45ef507
    59 #ifndef QT_NO_DIRECTFB_WM
    59 #ifndef QT_NO_DIRECTFB_WM
    60     , dfbWindow(0)
    60     , dfbWindow(0)
    61 #endif
    61 #endif
    62     , flipFlags(flip)
    62     , flipFlags(flip)
    63     , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
    63     , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
       
    64     , flushPending(false)
    64 {
    65 {
    65 #ifdef QT_NO_DIRECTFB_WM
    66 #ifdef QT_NO_DIRECTFB_WM
    66     mode = Offscreen;
    67     mode = Offscreen;
    67 #endif
    68 #endif
    68     setSurfaceFlags(Opaque | Buffered);
    69     setSurfaceFlags(Opaque | Buffered);
    78 #ifndef QT_NO_DIRECTFB_WM
    79 #ifndef QT_NO_DIRECTFB_WM
    79     , dfbWindow(0)
    80     , dfbWindow(0)
    80 #endif
    81 #endif
    81     , flipFlags(flip)
    82     , flipFlags(flip)
    82     , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
    83     , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
       
    84     , flushPending(false)
    83 {
    85 {
    84     SurfaceFlags flags = 0;
    86     SurfaceFlags flags = 0;
    85     if (!widget || widget->window()->windowOpacity() == 0xff)
    87     if (!widget || widget->window()->windowOpacity() == 0xff)
    86         flags |= Opaque;
    88         flags |= Opaque;
    87 #ifdef QT_NO_DIRECTFB_WM
    89 #ifdef QT_NO_DIRECTFB_WM
    90         mode = Primary;
    92         mode = Primary;
    91     } else {
    93     } else {
    92         mode = Offscreen;
    94         mode = Offscreen;
    93         flags = Buffered;
    95         flags = Buffered;
    94     }
    96     }
    95 #else
       
    96     noSystemBackground = widget && widget->testAttribute(Qt::WA_NoSystemBackground);
       
    97     if (noSystemBackground)
       
    98         flags &= ~Opaque;
       
    99 #endif
    97 #endif
   100     setSurfaceFlags(flags);
    98     setSurfaceFlags(flags);
   101 #ifdef QT_DIRECTFB_TIMING
    99 #ifdef QT_DIRECTFB_TIMING
   102     frames = 0;
   100     frames = 0;
   103     timer.start();
   101     timer.start();
   132 {
   130 {
   133     IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
   131     IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
   134     if (!layer)
   132     if (!layer)
   135         qFatal("QDirectFBWindowSurface: Unable to get primary display layer!");
   133         qFatal("QDirectFBWindowSurface: Unable to get primary display layer!");
   136 
   134 
       
   135     updateIsOpaque();
       
   136 
   137     DFBWindowDescription description;
   137     DFBWindowDescription description;
   138     memset(&description, 0, sizeof(DFBWindowDescription));
   138     memset(&description, 0, sizeof(DFBWindowDescription));
   139 
   139 
       
   140     description.flags = DWDESC_CAPS|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT;
   140     description.caps = DWCAPS_NODECORATION;
   141     description.caps = DWCAPS_NODECORATION;
   141     description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY;
   142     description.surface_caps = DSCAPS_NONE;
   142 #if (Q_DIRECTFB_VERSION >= 0x010200)
   143     imageFormat = screen->pixelFormat();
   143     description.flags |= DWDESC_OPTIONS;
   144 
   144 #endif
   145     if (!(surfaceFlags() & Opaque)) {
   145 
   146         imageFormat = screen->alphaPixmapFormat();
   146     if (noSystemBackground) {
       
   147         description.caps |= DWCAPS_ALPHACHANNEL;
   147         description.caps |= DWCAPS_ALPHACHANNEL;
   148 #if (Q_DIRECTFB_VERSION >= 0x010200)
   148 #if (Q_DIRECTFB_VERSION >= 0x010200)
       
   149         description.flags |= DWDESC_OPTIONS;
   149         description.options |= DWOP_ALPHACHANNEL;
   150         description.options |= DWOP_ALPHACHANNEL;
   150 #endif
   151 #endif
   151     }
   152     }
   152 
   153     description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(imageFormat);
   153     description.posx = rect.x();
   154     description.posx = rect.x();
   154     description.posy = rect.y();
   155     description.posy = rect.y();
   155     description.width = rect.width();
   156     description.width = rect.width();
   156     description.height = rect.height();
   157     description.height = rect.height();
   157     description.surface_caps = DSCAPS_NONE;
   158 
       
   159     if (QDirectFBScreen::isPremultiplied(imageFormat))
       
   160         description.surface_caps = DSCAPS_PREMULTIPLIED;
       
   161 
   158     if (screen->directFBFlags() & QDirectFBScreen::VideoOnly)
   162     if (screen->directFBFlags() & QDirectFBScreen::VideoOnly)
   159         description.surface_caps |= DSCAPS_VIDEOONLY;
   163         description.surface_caps |= DSCAPS_VIDEOONLY;
   160     const QImage::Format format = (noSystemBackground ? screen->alphaPixmapFormat() : screen->pixelFormat());
       
   161     description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
       
   162     if (QDirectFBScreen::isPremultiplied(format))
       
   163         description.surface_caps = DSCAPS_PREMULTIPLIED;
       
   164 
   164 
   165     DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);
   165     DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);
   166 
   166 
   167     if (result != DFB_OK)
   167     if (result != DFB_OK)
   168         DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result);
   168         DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result);
   180         }
   180         }
   181     }
   181     }
   182 
   182 
   183     Q_ASSERT(!dfbSurface);
   183     Q_ASSERT(!dfbSurface);
   184     dfbWindow->GetSurface(dfbWindow, &dfbSurface);
   184     dfbWindow->GetSurface(dfbWindow, &dfbSurface);
   185     updateFormat();
       
   186 }
   185 }
   187 
   186 
   188 static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect)
   187 static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect)
   189 {
   188 {
   190     DFBResult result = DFB_OK;
   189     DFBResult result = DFB_OK;
   265                                          rect.width(), rect.height() };
   264                                          rect.width(), rect.height() };
   266                 result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
   265                 result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
   267             }
   266             }
   268         } else { // mode == Offscreen
   267         } else { // mode == Offscreen
   269             if (!dfbSurface) {
   268             if (!dfbSurface) {
   270                 dfbSurface = screen->createDFBSurface(rect.size(), screen->pixelFormat(), QDirectFBScreen::DontTrackSurface);
   269                 dfbSurface = screen->createDFBSurface(rect.size(), surfaceFlags() & Opaque ? screen->pixelFormat() : screen->alphaPixmapFormat(),
       
   270                                                       QDirectFBScreen::DontTrackSurface);
   271             }
   271             }
   272         }
   272         }
   273         if (result != DFB_OK)
   273         if (result != DFB_OK)
   274             DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result);
   274             DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result);
   275 #endif
   275 #endif
   276     }
   276     }
   277     if (oldSurface != dfbSurface)
   277     if (oldSurface != dfbSurface) {
   278         updateFormat();
   278         imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
       
   279     }
   279 
   280 
   280     if (oldRect.size() != rect.size()) {
   281     if (oldRect.size() != rect.size()) {
   281         QWSWindowSurface::setGeometry(rect);
   282         QWSWindowSurface::setGeometry(rect);
   282     } else {
   283     } else {
   283         QWindowSurface::setGeometry(rect);
   284         QWindowSurface::setGeometry(rect);
   294 void QDirectFBWindowSurface::setPermanentState(const QByteArray &state)
   295 void QDirectFBWindowSurface::setPermanentState(const QByteArray &state)
   295 {
   296 {
   296     if (state.size() == sizeof(this)) {
   297     if (state.size() == sizeof(this)) {
   297         sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData());
   298         sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData());
   298         Q_ASSERT(sibling);
   299         Q_ASSERT(sibling);
   299         sibling->setSurfaceFlags(surfaceFlags());
   300         setSurfaceFlags(sibling->surfaceFlags());
   300     }
   301     }
   301 }
   302 }
   302 
   303 
   303 static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int dx, int dy)
   304 bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
   304 {
   305 {
       
   306     if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.rectCount() != 1)
       
   307         return false;
       
   308     if (flushPending) {
       
   309         dfbSurface->Flip(dfbSurface, 0, DSFLIP_BLIT);
       
   310     } else {
       
   311         flushPending = true;
       
   312     }
       
   313     dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
       
   314     const QRect r = region.boundingRect();
   305     const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() };
   315     const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() };
   306     surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy);
   316     dfbSurface->Blit(dfbSurface, dfbSurface, &rect, r.x() + dx, r.y() + dy);
   307     const DFBRegion region = { rect.x + dx, rect.y + dy, r.right() + dx, r.bottom() + dy };
       
   308     surface->Flip(surface, &region, DSFLIP_BLIT);
       
   309 }
       
   310 
       
   311 bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
       
   312 {
       
   313     if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.isEmpty())
       
   314         return false;
       
   315     dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
       
   316     if (region.rectCount() == 1) {
       
   317         scrollSurface(dfbSurface, region.boundingRect(), dx, dy);
       
   318     } else {
       
   319         const QVector<QRect> rects = region.rects();
       
   320         const int n = rects.size();
       
   321         for (int i=0; i<n; ++i) {
       
   322             scrollSurface(dfbSurface, rects.at(i), dx, dy);
       
   323         }
       
   324     }
       
   325     return true;
   317     return true;
   326 }
   318 }
   327 
   319 
   328 bool QDirectFBWindowSurface::move(const QPoint &moveBy)
   320 bool QDirectFBWindowSurface::move(const QPoint &moveBy)
   329 {
   321 {
   357         return;
   349         return;
   358 
   350 
   359     const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff);
   351     const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff);
   360     const QRect windowGeometry = geometry();
   352     const QRect windowGeometry = geometry();
   361 #ifdef QT_DIRECTFB_WM
   353 #ifdef QT_DIRECTFB_WM
   362     const bool wasNoSystemBackground = noSystemBackground;
       
   363     noSystemBackground = win->testAttribute(Qt::WA_NoSystemBackground);
       
   364     quint8 currentOpacity;
   354     quint8 currentOpacity;
   365     Q_ASSERT(dfbWindow);
   355     Q_ASSERT(dfbWindow);
   366     dfbWindow->GetOpacity(dfbWindow, &currentOpacity);
   356     dfbWindow->GetOpacity(dfbWindow, &currentOpacity);
   367     if (currentOpacity != windowOpacity) {
   357     if (currentOpacity != windowOpacity) {
   368         dfbWindow->SetOpacity(dfbWindow, windowOpacity);
   358         dfbWindow->SetOpacity(dfbWindow, windowOpacity);
   369     }
   359     }
   370 
   360 
   371     setOpaque(noSystemBackground || windowOpacity != 0xff);
       
   372     if (wasNoSystemBackground != noSystemBackground) {
       
   373         releaseSurface();
       
   374         dfbWindow->Release(dfbWindow);
       
   375         dfbWindow = 0;
       
   376         createWindow(windowGeometry);
       
   377         win->update();
       
   378         return;
       
   379     }
       
   380     screen->flipSurface(dfbSurface, flipFlags, region, offset);
   361     screen->flipSurface(dfbSurface, flipFlags, region, offset);
   381 #else
   362 #else
   382     setOpaque(windowOpacity != 0xff);
   363     setOpaque(windowOpacity == 0xff);
   383     if (mode == Offscreen) {
   364     if (mode == Offscreen) {
   384         screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0);
   365         screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0);
   385     } else {
   366     } else {
   386         screen->flipSurface(dfbSurface, flipFlags, region, offset);
   367         screen->flipSurface(dfbSurface, flipFlags, region, offset);
   387     }
   368     }
   394         qDebug("%d fps", int(double(frames) / double(Secs)));
   375         qDebug("%d fps", int(double(frames) / double(Secs)));
   395         frames = 0;
   376         frames = 0;
   396         timer.restart();
   377         timer.restart();
   397     }
   378     }
   398 #endif
   379 #endif
       
   380     flushPending = false;
   399 }
   381 }
   400 
   382 
   401 void QDirectFBWindowSurface::beginPaint(const QRegion &)
   383 void QDirectFBWindowSurface::beginPaint(const QRegion &)
   402 {
   384 {
   403     if (!engine) {
   385     if (!engine) {
   404         engine = new QDirectFBPaintEngine(this);
   386         engine = new QDirectFBPaintEngine(this);
   405     }
   387     }
       
   388     flushPending = true;
   406 }
   389 }
   407 
   390 
   408 void QDirectFBWindowSurface::endPaint(const QRegion &)
   391 void QDirectFBWindowSurface::endPaint(const QRegion &)
   409 {
   392 {
   410 #ifdef QT_NO_DIRECTFB_SUBSURFACE
   393 #ifdef QT_NO_DIRECTFB_SUBSURFACE
   440 
   423 
   441     Q_ASSERT(win == widget || win->isAncestorOf(widget));
   424     Q_ASSERT(win == widget || win->isAncestorOf(widget));
   442     return dfbSurface;
   425     return dfbSurface;
   443 }
   426 }
   444 
   427 
   445 void QDirectFBWindowSurface::updateFormat()
       
   446 {
       
   447     imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
       
   448 }
       
   449 
       
   450 void QDirectFBWindowSurface::releaseSurface()
   428 void QDirectFBWindowSurface::releaseSurface()
   451 {
   429 {
   452     if (dfbSurface) {
   430     if (dfbSurface) {
   453 #ifdef QT_DIRECTFB_SUBSURFACE
   431 #ifdef QT_DIRECTFB_SUBSURFACE
   454         releaseSubSurface();
   432         releaseSubSurface();
   463             dfbSurface->Release(dfbSurface);
   441             dfbSurface->Release(dfbSurface);
   464         dfbSurface = 0;
   442         dfbSurface = 0;
   465     }
   443     }
   466 }
   444 }
   467 
   445 
       
   446 void QDirectFBWindowSurface::updateIsOpaque()
       
   447 {
       
   448     const QWidget *win = window();
       
   449     Q_ASSERT(win);
       
   450     if (win->testAttribute(Qt::WA_OpaquePaintEvent) || win->testAttribute(Qt::WA_PaintOnScreen)) {
       
   451         setOpaque(true);
       
   452         return;
       
   453     }
       
   454 
       
   455     if (qFuzzyCompare(static_cast<float>(win->windowOpacity()), 1.0f)) {
       
   456         const QPalette &pal = win->palette();
       
   457 
       
   458         if (win->autoFillBackground()) {
       
   459             const QBrush &autoFillBrush = pal.brush(win->backgroundRole());
       
   460             if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
       
   461                 setOpaque(true);
       
   462                 return;
       
   463             }
       
   464         }
       
   465 
       
   466         if (win->isWindow() && !win->testAttribute(Qt::WA_NoSystemBackground)) {
       
   467             const QBrush &windowBrush = win->palette().brush(QPalette::Window);
       
   468             if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
       
   469                 setOpaque(true);
       
   470                 return;
       
   471             }
       
   472         }
       
   473     }
       
   474     setOpaque(false);
       
   475 }
   468 
   476 
   469 QT_END_NAMESPACE
   477 QT_END_NAMESPACE
   470 
   478 
   471 #endif // QT_NO_QWS_DIRECTFB
   479 #endif // QT_NO_QWS_DIRECTFB
   472 
       
   473