From f8f5fe02590da7e67829caf118ba73d455192ec8 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 4 May 2009 11:45:15 -0700 Subject: Rename QDirectFBSurface to QDirectFBWindowSurface This helps avoid confusion between IDirectFBSurface and QDirectFBSurface. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/directfb.pro | 4 +- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 2 +- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 12 +- .../gfxdrivers/directfb/qdirectfbsurface.cpp | 449 --------------------- src/plugins/gfxdrivers/directfb/qdirectfbsurface.h | 112 ----- .../gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 449 +++++++++++++++++++++ .../gfxdrivers/directfb/qdirectfbwindowsurface.h | 112 +++++ 7 files changed, 570 insertions(+), 570 deletions(-) delete mode 100644 src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp delete mode 100644 src/plugins/gfxdrivers/directfb/qdirectfbsurface.h create mode 100644 src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp create mode 100644 src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro index 67f5d61..abdb78f 100644 --- a/src/plugins/gfxdrivers/directfb/directfb.pro +++ b/src/plugins/gfxdrivers/directfb/directfb.pro @@ -22,7 +22,7 @@ target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers INSTALLS += target HEADERS = qdirectfbscreen.h \ - qdirectfbsurface.h \ + qdirectfbwindowsurface.h \ qdirectfbpaintengine.h \ qdirectfbpaintdevice.h \ qdirectfbpixmap.h \ @@ -31,7 +31,7 @@ HEADERS = qdirectfbscreen.h \ SOURCES = qdirectfbscreen.cpp \ qdirectfbscreenplugin.cpp \ - qdirectfbsurface.cpp \ + qdirectfbwindowsurface.cpp \ qdirectfbpaintengine.cpp \ qdirectfbpaintdevice.cpp \ qdirectfbpixmap.cpp \ diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index e9e2b1f..92f717e 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -43,7 +43,7 @@ #ifndef QT_NO_DIRECTFB -#include "qdirectfbsurface.h" +#include "qdirectfbwindowsurface.h" #include "qdirectfbscreen.h" #include "qdirectfbpixmap.h" #include diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 9ec5f5f..59f5934 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "qdirectfbscreen.h" -#include "qdirectfbsurface.h" +#include "qdirectfbwindowsurface.h" #include "qdirectfbpixmap.h" #include "qdirectfbmouse.h" #include "qdirectfbkeyboard.h" @@ -1102,19 +1102,19 @@ QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const { #ifdef QT_NO_DIRECTFB_WM if (QApplication::type() == QApplication::GuiServer) { - return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this), widget); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast(this), widget); } else { return QScreen::createSurface(widget); } #else - return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this), widget); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast(this), widget); #endif } QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const { if (key == QLatin1String("directfb")) { - return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this)); + return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast(this)); } return QScreen::createSurface(key); } @@ -1147,7 +1147,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) const QPoint offset = win->requestedRegion().boundingRect().topLeft(); if (surface->key() == QLatin1String("directfb")) { - QDirectFBSurface *s = static_cast(surface); + QDirectFBWindowSurface *s = static_cast(surface); blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); @@ -1196,7 +1196,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) const QPoint offset = win->requestedRegion().boundingRect().topLeft(); if (surface->key() == QLatin1String("directfb")) { - QDirectFBSurface *s = static_cast(surface); + QDirectFBWindowSurface *s = static_cast(surface); blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp deleted file mode 100644 index 827e10d..0000000 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdirectfbsurface.h" -#include "qdirectfbscreen.h" -#include "qdirectfbpaintengine.h" - -#include -#include -#include - - -//#define QT_DIRECTFB_DEBUG_SURFACES 1 - -QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) - : QDirectFBPaintDevice(scr) -#ifndef QT_NO_DIRECTFB_WM - , dfbWindow(0) -#endif - , engine(0) - , flipFlags(flip) - , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) -{ - setSurfaceFlags(Opaque | Buffered); -#ifdef QT_DIRECTFB_TIMING - frames = 0; - timer.start(); -#endif -} - -QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) - : QWSWindowSurface(widget), QDirectFBPaintDevice(scr) -#ifndef QT_NO_DIRECTFB_WM - , dfbWindow(0) -#endif - , engine(0) - , flipFlags(flip) - , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) -{ - onscreen = widget->testAttribute(Qt::WA_PaintOnScreen); - if (onscreen) - setSurfaceFlags(Opaque | RegionReserved); - else - setSurfaceFlags(Opaque | Buffered); -#ifdef QT_DIRECTFB_TIMING - frames = 0; - timer.start(); -#endif -} - -QDirectFBSurface::~QDirectFBSurface() -{ -} - -bool QDirectFBSurface::isValid() const -{ - return true; -} - -#ifndef QT_NO_DIRECTFB_WM -void QDirectFBSurface::createWindow() -{ -#ifdef QT_NO_DIRECTFB_LAYER -#warning QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM -#else - IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); - if (!layer) - qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); - - DFBWindowDescription description; - description.caps = DFBWindowCapabilities(DWCAPS_NODECORATION); - description.flags = DFBWindowDescriptionFlags(DWDESC_CAPS - |DWDESC_SURFACE_CAPS - |DWDESC_PIXELFORMAT); - - description.surface_caps = DSCAPS_NONE; - if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) - description.surface_caps = DFBSurfaceCapabilities(description.surface_caps|DSCAPS_VIDEOONLY); - const QImage::Format format = screen->pixelFormat(); - description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); - if (QDirectFBScreen::isPremultiplied(format)) - description.surface_caps = DFBSurfaceCapabilities(DSCAPS_PREMULTIPLIED|description.caps); - - DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); - if (result != DFB_OK) - DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result); - - if (dfbSurface) - dfbSurface->Release(dfbSurface); - - dfbWindow->GetSurface(dfbWindow, &dfbSurface); - forceRaster = (format == QImage::Format_RGB32); -#endif -} -#endif // QT_NO_DIRECTFB_WM - -void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) -{ - if (rect.isNull()) { -#ifndef QT_NO_DIRECTFB_WM - if (dfbWindow) { - dfbWindow->Release(dfbWindow); - dfbWindow = 0; - } -#endif - if (dfbSurface && dfbSurface != screen->dfbSurface()) { - dfbSurface->Release(dfbSurface); - dfbSurface = 0; - } - } else if (rect != geometry()) { - DFBResult result = DFB_OK; - - // If we're in a resize, the surface shouldn't be locked - Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size())); - - if (onscreen) { - IDirectFBSurface *primarySurface = screen->dfbSurface(); - Q_ASSERT(primarySurface); - if (dfbSurface && dfbSurface != primarySurface) - dfbSurface->Release(dfbSurface); - - if (rect == screen->region().boundingRect()) { - dfbSurface = primarySurface; - } else { - const DFBRectangle r = { rect.x(), rect.y(), - rect.width(), rect.height() }; - result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); - } - forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); - } else { - const bool isResize = rect.size() != geometry().size(); -#ifdef QT_NO_DIRECTFB_WM - if (isResize) { - if (dfbSurface) - dfbSurface->Release(dfbSurface); - - IDirectFB *dfb = screen->dfb(); - if (!dfb) { - qFatal("QDirectFBWindowSurface::setGeometry(): " - "Unable to get DirectFB handle!"); - } - - DFBSurfaceDescription description; - description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | - DSDESC_HEIGHT | - DSDESC_PIXELFORMAT); - description.width = rect.width(); - description.height = rect.height(); - QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, - screen->pixelFormat()); - dfbSurface = screen->createDFBSurface(description, false); - forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); - } else { - Q_ASSERT(dfbSurface); - } -#else - const QRect oldRect = geometry(); - const bool isMove = oldRect.isEmpty() || - rect.topLeft() != oldRect.topLeft(); - - if (!dfbWindow) - createWindow(); - - if (isResize && isMove) - result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(), - rect.width(), rect.height()); - else if (isResize) - result = dfbWindow->Resize(dfbWindow, - rect.width(), rect.height()); - else if (isMove) - result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y()); -#endif - } - - if (result != DFB_OK) - DirectFBErrorFatal("QDirectFBSurface::setGeometry()", result); - } - - QWSWindowSurface::setGeometry(rect, mask); -} - -QByteArray QDirectFBSurface::permanentState() const -{ - QByteArray array; -#ifdef QT_NO_DIRECTFB_WM - array.resize(sizeof(SurfaceFlags) + sizeof(IDirectFBSurface*)); -#else - array.resize(sizeof(SurfaceFlags)); -#endif - char *ptr = array.data(); - - *reinterpret_cast(ptr) = surfaceFlags(); - ptr += sizeof(SurfaceFlags); - -#ifdef QT_NO_DIRECTFB_WM - *reinterpret_cast(ptr) = dfbSurface; -#endif - return array; -} - -void QDirectFBSurface::setPermanentState(const QByteArray &state) -{ - SurfaceFlags flags; - const char *ptr = state.constData(); - - flags = *reinterpret_cast(ptr); - setSurfaceFlags(flags); - -#ifdef QT_NO_DIRECTFB_WM - ptr += sizeof(SurfaceFlags); - dfbSurface = *reinterpret_cast(ptr); -#endif -} - -bool QDirectFBSurface::scroll(const QRegion ®ion, int dx, int dy) -{ - if (!dfbSurface || !(flipFlags & DSFLIP_BLIT)) - return false; - - const QVector rects = region.rects(); - const int n = rects.size(); - - QVarLengthArray dfbRects(n); - QVarLengthArray dfbPoints(n); - - for (int i = 0; i < n; ++i) { - const QRect r = rects.at(i); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); - dfbPoints[i].x = r.x() + dx; - dfbPoints[i].y = r.y() + dy; - } - - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); - dfbSurface->BatchBlit(dfbSurface, dfbSurface, - dfbRects.data(), dfbPoints.data(), n); - dfbSurface->ReleaseSource(dfbSurface); - return true; -} - -bool QDirectFBSurface::move(const QPoint &offset) -{ - QWSWindowSurface::move(offset); - -#ifdef QT_NO_DIRECTFB_WM - return true; // buffered -#else - if (!dfbWindow) - return false; - - DFBResult status = dfbWindow->Move(dfbWindow, offset.x(), offset.y()); - return (status == DFB_OK); -#endif -} - -QRegion QDirectFBSurface::move(const QPoint &offset, const QRegion &newClip) -{ -#ifdef QT_NO_DIRECTFB_WM - return QWSWindowSurface::move(offset, newClip); -#else - Q_UNUSED(offset); - Q_UNUSED(newClip); - - // DirectFB handles the entire move, so there's no need to blit. - return QRegion(); -#endif -} - -QPaintEngine* QDirectFBSurface::paintEngine() const -{ - if (!engine) { - QDirectFBSurface *that = const_cast(this); - that->engine = new QDirectFBPaintEngine(that); - return that->engine; - } - return engine; -} - -// hw: XXX: copied from QWidgetPrivate::isOpaque() -inline bool isWidgetOpaque(const QWidget *w) -{ - if (w->testAttribute(Qt::WA_OpaquePaintEvent) - || w->testAttribute(Qt::WA_PaintOnScreen)) - return true; - - const QPalette &pal = w->palette(); - - if (w->autoFillBackground()) { - const QBrush &autoFillBrush = pal.brush(w->backgroundRole()); - if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) - return true; - } - - if (!w->testAttribute(Qt::WA_NoSystemBackground)) { - const QBrush &windowBrush = w->palette().brush(QPalette::Window); - if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) - return true; - } - - return false; -} -void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, - const QPoint &offset) -{ - Q_UNUSED(widget); -#ifdef QT_NO_DIRECTFB_WM - Q_UNUSED(region); - Q_UNUSED(offset); -#endif - - QWidget *win = window(); - - // hw: make sure opacity information is updated before compositing - const bool opaque = isWidgetOpaque(win); - if (opaque != isOpaque()) { - SurfaceFlags flags = Buffered; - if (opaque) - flags |= Opaque; - setSurfaceFlags(flags); - } - -#ifndef QT_NO_DIRECTFB_WM - const quint8 winOpacity = quint8(win->windowOpacity() * 255); - quint8 opacity; - - if (dfbWindow) { - dfbWindow->GetOpacity(dfbWindow, &opacity); - if (winOpacity != opacity) - dfbWindow->SetOpacity(dfbWindow, winOpacity); - } - if (!(flipFlags & DSFLIP_BLIT)) { - dfbSurface->Flip(dfbSurface, 0, flipFlags); - } else { - if (!boundingRectFlip && region.numRects() > 1) { - const QVector rects = region.rects(); - const DFBSurfaceFlipFlags nonWaitFlags = DFBSurfaceFlipFlags(flipFlags & ~DSFLIP_WAIT); - for (int i=0; iFlip(dfbSurface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags); - } - } else { - const QRect r = region.boundingRect(); - const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), - r.x() + r.width() + offset.x(), - r.y() + r.height() + offset.y() }; - dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); - } - } -#endif -#ifdef QT_DIRECTFB_TIMING - enum { Secs = 3 }; - ++frames; - if (timer.elapsed() >= Secs * 1000) { - qDebug("%d fps", int(double(frames) / double(Secs))); - frames = 0; - timer.restart(); - } -#endif -} - - -void QDirectFBSurface::beginPaint(const QRegion &) -{ -} - -void QDirectFBSurface::endPaint(const QRegion &) -{ -#ifdef QT_DIRECTFB_DEBUG_SURFACES - if (bufferImages.count()) { - qDebug("QDirectFBSurface::endPaint() this=%p", this); - - foreach(QImage* bufferImg, bufferImages) - qDebug(" Deleting buffer image %p", bufferImg); - } -#endif - - qDeleteAll(bufferImages); - bufferImages.clear(); - unlockDirectFB(); -} - - -QImage *QDirectFBSurface::buffer(const QWidget *widget) -{ - if (!lockedImage) - return 0; - - const QRect rect = QRect(offset(widget), widget->size()) - & lockedImage->rect(); - if (rect.isEmpty()) - return 0; - - QImage *img = new QImage(lockedImage->scanLine(rect.y()) - + rect.x() * (lockedImage->depth() / 8), - rect.width(), rect.height(), - lockedImage->bytesPerLine(), - lockedImage->format()); - bufferImages.append(img); - -#ifdef QT_DIRECTFB_DEBUG_SURFACES - qDebug("QDirectFBSurface::buffer() Created & returned %p", img); -#endif - - return img; -} - diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h deleted file mode 100644 index c554096..0000000 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDIRECFBWINDOWSURFACE_H -#define QDIRECFBWINDOWSURFACE_H - -#include "qdirectfbpaintengine.h" -#include "qdirectfbpaintdevice.h" -#include "qdirectfbscreen.h" - -#include -#include -#include - -#ifdef QT_DIRECTFB_TIMING -#include -#endif - -QT_BEGIN_HEADER - -QT_MODULE(Gui) - -class QDirectFBSurface : public QWSWindowSurface, public QDirectFBPaintDevice -{ -public: - QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); - QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); - ~QDirectFBSurface(); - - bool isValid() const; - - void setGeometry(const QRect &rect, const QRegion &mask); - - QString key() const { return QLatin1String("directfb"); } - QByteArray permanentState() const; - void setPermanentState(const QByteArray &state); - - bool scroll(const QRegion &area, int dx, int dy); - - bool move(const QPoint &offset); - QRegion move(const QPoint &offset, const QRegion &newClip); - - QImage image() const { return QImage(); } - QPaintDevice *paintDevice() { return this; } - QPaintEngine *paintEngine() const; - - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - - void beginPaint(const QRegion &); - void endPaint(const QRegion &); - - QImage *buffer(const QWidget *widget); - -private: -#ifndef QT_NO_DIRECTFB_WM - void createWindow(); - IDirectFBWindow *dfbWindow; -#endif - QDirectFBPaintEngine *engine; - - bool onscreen; - - QList bufferImages; - DFBSurfaceFlipFlags flipFlags; - bool boundingRectFlip; -#ifdef QT_DIRECTFB_TIMING - int frames; - QTime timer; -#endif -}; - -QT_END_HEADER - -#endif // QDIRECFBWINDOWSURFACE_H diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp new file mode 100644 index 0000000..f1e3c84 --- /dev/null +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -0,0 +1,449 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdirectfbwindowsurface.h" +#include "qdirectfbscreen.h" +#include "qdirectfbpaintengine.h" + +#include +#include +#include + + +//#define QT_DIRECTFB_DEBUG_SURFACES 1 + +QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) + : QDirectFBPaintDevice(scr) +#ifndef QT_NO_DIRECTFB_WM + , dfbWindow(0) +#endif + , engine(0) + , flipFlags(flip) + , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) +{ + setSurfaceFlags(Opaque | Buffered); +#ifdef QT_DIRECTFB_TIMING + frames = 0; + timer.start(); +#endif +} + +QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) + : QWSWindowSurface(widget), QDirectFBPaintDevice(scr) +#ifndef QT_NO_DIRECTFB_WM + , dfbWindow(0) +#endif + , engine(0) + , flipFlags(flip) + , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) +{ + onscreen = widget->testAttribute(Qt::WA_PaintOnScreen); + if (onscreen) + setSurfaceFlags(Opaque | RegionReserved); + else + setSurfaceFlags(Opaque | Buffered); +#ifdef QT_DIRECTFB_TIMING + frames = 0; + timer.start(); +#endif +} + +QDirectFBWindowSurface::~QDirectFBWindowSurface() +{ +} + +bool QDirectFBWindowSurface::isValid() const +{ + return true; +} + +#ifndef QT_NO_DIRECTFB_WM +void QDirectFBWindowSurface::createWindow() +{ +#ifdef QT_NO_DIRECTFB_LAYER +#warning QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM +#else + IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); + if (!layer) + qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); + + DFBWindowDescription description; + description.caps = DFBWindowCapabilities(DWCAPS_NODECORATION); + description.flags = DFBWindowDescriptionFlags(DWDESC_CAPS + |DWDESC_SURFACE_CAPS + |DWDESC_PIXELFORMAT); + + description.surface_caps = DSCAPS_NONE; + if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) + description.surface_caps = DFBSurfaceCapabilities(description.surface_caps|DSCAPS_VIDEOONLY); + const QImage::Format format = screen->pixelFormat(); + description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); + if (QDirectFBScreen::isPremultiplied(format)) + description.surface_caps = DFBSurfaceCapabilities(DSCAPS_PREMULTIPLIED|description.caps); + + DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); + if (result != DFB_OK) + DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result); + + if (dfbSurface) + dfbSurface->Release(dfbSurface); + + dfbWindow->GetSurface(dfbWindow, &dfbSurface); + forceRaster = (format == QImage::Format_RGB32); +#endif +} +#endif // QT_NO_DIRECTFB_WM + +void QDirectFBWindowSurface::setGeometry(const QRect &rect, const QRegion &mask) +{ + if (rect.isNull()) { +#ifndef QT_NO_DIRECTFB_WM + if (dfbWindow) { + dfbWindow->Release(dfbWindow); + dfbWindow = 0; + } +#endif + if (dfbSurface && dfbSurface != screen->dfbSurface()) { + dfbSurface->Release(dfbSurface); + dfbSurface = 0; + } + } else if (rect != geometry()) { + DFBResult result = DFB_OK; + + // If we're in a resize, the surface shouldn't be locked + Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size())); + + if (onscreen) { + IDirectFBSurface *primarySurface = screen->dfbSurface(); + Q_ASSERT(primarySurface); + if (dfbSurface && dfbSurface != primarySurface) + dfbSurface->Release(dfbSurface); + + if (rect == screen->region().boundingRect()) { + dfbSurface = primarySurface; + } else { + const DFBRectangle r = { rect.x(), rect.y(), + rect.width(), rect.height() }; + result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); + } + forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); + } else { + const bool isResize = rect.size() != geometry().size(); +#ifdef QT_NO_DIRECTFB_WM + if (isResize) { + if (dfbSurface) + dfbSurface->Release(dfbSurface); + + IDirectFB *dfb = screen->dfb(); + if (!dfb) { + qFatal("QDirectFBWindowSurface::setGeometry(): " + "Unable to get DirectFB handle!"); + } + + DFBSurfaceDescription description; + description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | + DSDESC_HEIGHT | + DSDESC_PIXELFORMAT); + description.width = rect.width(); + description.height = rect.height(); + QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, + screen->pixelFormat()); + dfbSurface = screen->createDFBSurface(description, false); + forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); + } else { + Q_ASSERT(dfbSurface); + } +#else + const QRect oldRect = geometry(); + const bool isMove = oldRect.isEmpty() || + rect.topLeft() != oldRect.topLeft(); + + if (!dfbWindow) + createWindow(); + + if (isResize && isMove) + result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(), + rect.width(), rect.height()); + else if (isResize) + result = dfbWindow->Resize(dfbWindow, + rect.width(), rect.height()); + else if (isMove) + result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y()); +#endif + } + + if (result != DFB_OK) + DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); + } + + QWSWindowSurface::setGeometry(rect, mask); +} + +QByteArray QDirectFBWindowSurface::permanentState() const +{ + QByteArray array; +#ifdef QT_NO_DIRECTFB_WM + array.resize(sizeof(SurfaceFlags) + sizeof(IDirectFBSurface*)); +#else + array.resize(sizeof(SurfaceFlags)); +#endif + char *ptr = array.data(); + + *reinterpret_cast(ptr) = surfaceFlags(); + ptr += sizeof(SurfaceFlags); + +#ifdef QT_NO_DIRECTFB_WM + *reinterpret_cast(ptr) = dfbSurface; +#endif + return array; +} + +void QDirectFBWindowSurface::setPermanentState(const QByteArray &state) +{ + SurfaceFlags flags; + const char *ptr = state.constData(); + + flags = *reinterpret_cast(ptr); + setSurfaceFlags(flags); + +#ifdef QT_NO_DIRECTFB_WM + ptr += sizeof(SurfaceFlags); + dfbSurface = *reinterpret_cast(ptr); +#endif +} + +bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) +{ + if (!dfbSurface || !(flipFlags & DSFLIP_BLIT)) + return false; + + const QVector rects = region.rects(); + const int n = rects.size(); + + QVarLengthArray dfbRects(n); + QVarLengthArray dfbPoints(n); + + for (int i = 0; i < n; ++i) { + const QRect r = rects.at(i); + dfbRects[i].x = r.x(); + dfbRects[i].y = r.y(); + dfbRects[i].w = r.width(); + dfbRects[i].h = r.height(); + dfbPoints[i].x = r.x() + dx; + dfbPoints[i].y = r.y() + dy; + } + + dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + dfbSurface->BatchBlit(dfbSurface, dfbSurface, + dfbRects.data(), dfbPoints.data(), n); + dfbSurface->ReleaseSource(dfbSurface); + return true; +} + +bool QDirectFBWindowSurface::move(const QPoint &offset) +{ + QWSWindowSurface::move(offset); + +#ifdef QT_NO_DIRECTFB_WM + return true; // buffered +#else + if (!dfbWindow) + return false; + + DFBResult status = dfbWindow->Move(dfbWindow, offset.x(), offset.y()); + return (status == DFB_OK); +#endif +} + +QRegion QDirectFBWindowSurface::move(const QPoint &offset, const QRegion &newClip) +{ +#ifdef QT_NO_DIRECTFB_WM + return QWSWindowSurface::move(offset, newClip); +#else + Q_UNUSED(offset); + Q_UNUSED(newClip); + + // DirectFB handles the entire move, so there's no need to blit. + return QRegion(); +#endif +} + +QPaintEngine* QDirectFBWindowSurface::paintEngine() const +{ + if (!engine) { + QDirectFBWindowSurface *that = const_cast(this); + that->engine = new QDirectFBPaintEngine(that); + return that->engine; + } + return engine; +} + +// hw: XXX: copied from QWidgetPrivate::isOpaque() +inline bool isWidgetOpaque(const QWidget *w) +{ + if (w->testAttribute(Qt::WA_OpaquePaintEvent) + || w->testAttribute(Qt::WA_PaintOnScreen)) + return true; + + const QPalette &pal = w->palette(); + + if (w->autoFillBackground()) { + const QBrush &autoFillBrush = pal.brush(w->backgroundRole()); + if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) + return true; + } + + if (!w->testAttribute(Qt::WA_NoSystemBackground)) { + const QBrush &windowBrush = w->palette().brush(QPalette::Window); + if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) + return true; + } + + return false; +} +void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, + const QPoint &offset) +{ + Q_UNUSED(widget); +#ifdef QT_NO_DIRECTFB_WM + Q_UNUSED(region); + Q_UNUSED(offset); +#endif + + QWidget *win = window(); + + // hw: make sure opacity information is updated before compositing + const bool opaque = isWidgetOpaque(win); + if (opaque != isOpaque()) { + SurfaceFlags flags = Buffered; + if (opaque) + flags |= Opaque; + setSurfaceFlags(flags); + } + +#ifndef QT_NO_DIRECTFB_WM + const quint8 winOpacity = quint8(win->windowOpacity() * 255); + quint8 opacity; + + if (dfbWindow) { + dfbWindow->GetOpacity(dfbWindow, &opacity); + if (winOpacity != opacity) + dfbWindow->SetOpacity(dfbWindow, winOpacity); + } + if (!(flipFlags & DSFLIP_BLIT)) { + dfbSurface->Flip(dfbSurface, 0, flipFlags); + } else { + if (!boundingRectFlip && region.numRects() > 1) { + const QVector rects = region.rects(); + const DFBSurfaceFlipFlags nonWaitFlags = DFBSurfaceFlipFlags(flipFlags & ~DSFLIP_WAIT); + for (int i=0; iFlip(dfbSurface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags); + } + } else { + const QRect r = region.boundingRect(); + const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), + r.x() + r.width() + offset.x(), + r.y() + r.height() + offset.y() }; + dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); + } + } +#endif +#ifdef QT_DIRECTFB_TIMING + enum { Secs = 3 }; + ++frames; + if (timer.elapsed() >= Secs * 1000) { + qDebug("%d fps", int(double(frames) / double(Secs))); + frames = 0; + timer.restart(); + } +#endif +} + + +void QDirectFBWindowSurface::beginPaint(const QRegion &) +{ +} + +void QDirectFBWindowSurface::endPaint(const QRegion &) +{ +#ifdef QT_DIRECTFB_DEBUG_SURFACES + if (bufferImages.count()) { + qDebug("QDirectFBWindowSurface::endPaint() this=%p", this); + + foreach(QImage* bufferImg, bufferImages) + qDebug(" Deleting buffer image %p", bufferImg); + } +#endif + + qDeleteAll(bufferImages); + bufferImages.clear(); + unlockDirectFB(); +} + + +QImage *QDirectFBWindowSurface::buffer(const QWidget *widget) +{ + if (!lockedImage) + return 0; + + const QRect rect = QRect(offset(widget), widget->size()) + & lockedImage->rect(); + if (rect.isEmpty()) + return 0; + + QImage *img = new QImage(lockedImage->scanLine(rect.y()) + + rect.x() * (lockedImage->depth() / 8), + rect.width(), rect.height(), + lockedImage->bytesPerLine(), + lockedImage->format()); + bufferImages.append(img); + +#ifdef QT_DIRECTFB_DEBUG_SURFACES + qDebug("QDirectFBWindowSurface::buffer() Created & returned %p", img); +#endif + + return img; +} + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h new file mode 100644 index 0000000..75998c4 --- /dev/null +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDIRECFBWINDOWSURFACE_H +#define QDIRECFBWINDOWSURFACE_H + +#include "qdirectfbpaintengine.h" +#include "qdirectfbpaintdevice.h" +#include "qdirectfbscreen.h" + +#include +#include +#include + +#ifdef QT_DIRECTFB_TIMING +#include +#endif + +QT_BEGIN_HEADER + +QT_MODULE(Gui) + +class QDirectFBWindowSurface : public QWSWindowSurface, public QDirectFBPaintDevice +{ +public: + QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); + QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); + ~QDirectFBWindowSurface(); + + bool isValid() const; + + void setGeometry(const QRect &rect, const QRegion &mask); + + QString key() const { return QLatin1String("directfb"); } + QByteArray permanentState() const; + void setPermanentState(const QByteArray &state); + + bool scroll(const QRegion &area, int dx, int dy); + + bool move(const QPoint &offset); + QRegion move(const QPoint &offset, const QRegion &newClip); + + QImage image() const { return QImage(); } + QPaintDevice *paintDevice() { return this; } + QPaintEngine *paintEngine() const; + + void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + + void beginPaint(const QRegion &); + void endPaint(const QRegion &); + + QImage *buffer(const QWidget *widget); + +private: +#ifndef QT_NO_DIRECTFB_WM + void createWindow(); + IDirectFBWindow *dfbWindow; +#endif + QDirectFBPaintEngine *engine; + + bool onscreen; + + QList bufferImages; + DFBSurfaceFlipFlags flipFlags; + bool boundingRectFlip; +#ifdef QT_DIRECTFB_TIMING + int frames; + QTime timer; +#endif +}; + +QT_END_HEADER + +#endif // QDIRECFBWINDOWSURFACE_H -- cgit v0.12