From e6557220bccbdbbc218dc9eab0eb426ba774435e Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 20 May 2010 11:20:21 +0300 Subject: Fix replacement functions in platform_paths.prf Clearing epocroot_prefix at the end of the file caused it to be empty at the time replacement functions were resolved. Reviewed-by: Janne Koskinen --- mkspecs/features/symbian/platform_paths.prf | 2 -- 1 file changed, 2 deletions(-) diff --git a/mkspecs/features/symbian/platform_paths.prf b/mkspecs/features/symbian/platform_paths.prf index f05a885..0e8770d 100644 --- a/mkspecs/features/symbian/platform_paths.prf +++ b/mkspecs/features/symbian/platform_paths.prf @@ -473,5 +473,3 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { STLLIB_USAGE_DEFINES = _WCHAR_T_DECLARED } - -epocroot_prefix = -- cgit v0.12 From 98972c1b271de1292b4e46484fe689d62a8b8e62 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Thu, 20 May 2010 12:46:46 +0300 Subject: QRuntimeGraphicsSystem QRuntimeGraphicsSystem is a proxy graphics system which can dynamically switch underlying graphics system on runtime. For example, switch from hardware accelerated graphics system to raster graphics system on low GPU memory situation. This feature is currently supported on Symbian platform. Task-number: QT-3276 Reviewed-by: Jason Barron --- src/corelib/global/qglobal.h | 1 + src/gui/image/qpixmap.cpp | 40 ++- src/gui/image/qpixmap.h | 2 - src/gui/image/qpixmapcache_p.h | 5 +- src/gui/image/qpixmapdata_p.h | 5 +- src/gui/kernel/qapplication.cpp | 13 +- src/gui/kernel/qapplication_s60.cpp | 66 +++- src/gui/kernel/qt_s60_p.h | 1 + src/gui/kernel/qwidget.cpp | 9 +- src/gui/painting/painting.pri | 2 + src/gui/painting/qgraphicssystem_runtime.cpp | 443 +++++++++++++++++++++++++++ src/gui/painting/qgraphicssystem_runtime_p.h | 197 ++++++++++++ src/gui/painting/qgraphicssystemfactory.cpp | 7 + src/gui/painting/qpaintengine_raster.cpp | 20 +- src/gui/painting/qwindowsurface.cpp | 2 - src/gui/painting/qwindowsurface_s60.cpp | 31 +- tools/configure/configureapp.cpp | 19 +- 17 files changed, 821 insertions(+), 42 deletions(-) create mode 100644 src/gui/painting/qgraphicssystem_runtime.cpp create mode 100644 src/gui/painting/qgraphicssystem_runtime_p.h diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 8359637..cba50a2 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2433,6 +2433,7 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); #if defined(Q_OS_SYMBIAN) #ifdef SYMBIAN_BUILD_GCE +#define Q_SYMBIAN_SUPPORTS_SURFACES //RWsPointerCursor is fixed, so don't use low performance sprites #define Q_SYMBIAN_FIXED_POINTER_CURSORS #define Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 474cd2e..21216f8 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -635,17 +635,21 @@ void QPixmap::resize_helper(const QSize &s) if (size() == s) return; + // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get + // the actual underlaying runtime pixmap data. + QPixmapData *pd = pixmapData(); + // Create new pixmap - QPixmap pm(QSize(w, h), data ? data->type : QPixmapData::PixmapType); + QPixmap pm(QSize(w, h), pd ? pd->type : QPixmapData::PixmapType); bool uninit = false; #if defined(Q_WS_X11) - QX11PixmapData *x11Data = data && data->classId() == QPixmapData::X11Class ? static_cast(data.data()) : 0; + QX11PixmapData *x11Data = pd && pd->classId() == QPixmapData::X11Class ? static_cast(pd) : 0; if (x11Data) { pm.x11SetScreen(x11Data->xinfo.screen()); uninit = x11Data->flags & QX11PixmapData::Uninitialized; } #elif defined(Q_WS_MAC) - QMacPixmapData *macData = data && data->classId() == QPixmapData::MacClass ? static_cast(data.data()) : 0; + QMacPixmapData *macData = pd && pd->classId() == QPixmapData::MacClass ? static_cast(pd) : 0; if (macData) uninit = macData->uninit; #endif @@ -659,7 +663,7 @@ void QPixmap::resize_helper(const QSize &s) #if defined(Q_WS_X11) if (x11Data && x11Data->x11_mask) { - QX11PixmapData *pmData = static_cast(pm.data.data()); + QX11PixmapData *pmData = static_cast(pd); pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display, RootWindow(x11Data->xinfo.display(), x11Data->xinfo.screen()), @@ -1163,8 +1167,9 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect) Qt::HANDLE QPixmap::handle() const { #if defined(Q_WS_X11) - if (data && data->classId() == QPixmapData::X11Class) - return static_cast(data.constData())->handle(); + const QPixmapData *pd = pixmapData(); + if (pd && pd->classId() == QPixmapData::X11Class) + return static_cast(pd)->handle(); #endif return 0; } @@ -1944,17 +1949,20 @@ void QPixmap::detach() if (!data) return; - QPixmapData::ClassId id = data->classId(); + // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get + // the actual underlaying runtime pixmap data. + QPixmapData *pd = pixmapData(); + QPixmapData::ClassId id = pd->classId(); if (id == QPixmapData::RasterClass) { - QRasterPixmapData *rasterData = static_cast(data.data()); + QRasterPixmapData *rasterData = static_cast(pd); rasterData->image.detach(); } if (data->is_cached && data->ref == 1) - QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data()); + QImagePixmapCleanupHooks::executePixmapDataModificationHooks(pd); #if defined(Q_WS_MAC) - QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast(data.data()) : 0; + QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast(pd) : 0; if (macData) { if (macData->cg_mask) { CGImageRelease(macData->cg_mask); @@ -1969,8 +1977,8 @@ void QPixmap::detach() ++data->detach_no; #if defined(Q_WS_X11) - if (data->classId() == QPixmapData::X11Class) { - QX11PixmapData *d = static_cast(data.data()); + if (pd->classId() == QPixmapData::X11Class) { + QX11PixmapData *d = static_cast(pd); d->flags &= ~QX11PixmapData::Uninitialized; // reset the cache data @@ -2060,9 +2068,15 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) */ QPixmapData* QPixmap::pixmapData() const { - return data.data(); + if (data) { + QPixmapData* pm = data.data(); + return pm->runtimeData() ? pm->runtimeData() : pm; + } + + return 0; } + /*! \enum QPixmap::HBitmapFormat diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 180af3b..82546da 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -271,9 +271,7 @@ private: friend class QX11PaintEngine; friend class QCoreGraphicsPaintEngine; friend class QWidgetPrivate; - friend class QRasterPaintEngine; friend class QRasterBuffer; - friend class QPixmapCacheEntry; #if !defined(QT_NO_DATASTREAM) friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPixmap &); #endif diff --git a/src/gui/image/qpixmapcache_p.h b/src/gui/image/qpixmapcache_p.h index 86a1b78..0ed083c 100644 --- a/src/gui/image/qpixmapcache_p.h +++ b/src/gui/image/qpixmapcache_p.h @@ -81,8 +81,9 @@ class QPixmapCacheEntry : public QPixmap public: QPixmapCacheEntry(const QPixmapCache::Key &key, const QPixmap &pix) : QPixmap(pix), key(key) { - if (data && data->classId() == QPixmapData::RasterClass) { - QRasterPixmapData *d = static_cast(data.data()); + QPixmapData *pd = pixmapData(); + if (pd && pd->classId() == QPixmapData::RasterClass) { + QRasterPixmapData *d = static_cast(pd); if (!d->image.isNull() && d->image.d->paintEngine && !d->image.d->paintEngine->isActive()) { diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index 827fa18..60ed26a 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -73,7 +73,7 @@ public: }; #endif enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass, - OpenGLClass, OpenVGClass, CustomClass = 1024 }; + OpenGLClass, OpenVGClass, RuntimeClass, CustomClass = 1024 }; QPixmapData(PixelType pixelType, int classId); virtual ~QPixmapData(); @@ -133,7 +133,10 @@ public: static QPixmapData *create(int w, int h, PixelType type); + virtual QPixmapData *runtimeData() const { return 0; } + protected: + void setSerialNumber(int serNo); int w; int h; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index ec635d4..590b000 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -70,6 +70,10 @@ #include "qmessagebox.h" #include +#ifdef QT_GRAPHICSSYSTEM_RUNTIME +#include "private/qgraphicssystem_runtime_p.h" +#endif + #include "qinputcontext.h" #include "qkeymapper_p.h" @@ -1561,7 +1565,14 @@ QStyle* QApplication::setStyle(const QString& style) void QApplication::setGraphicsSystem(const QString &system) { - QApplicationPrivate::graphics_system_name = system; +#ifdef QT_GRAPHICSSYSTEM_RUNTIME + if (QApplicationPrivate::graphics_system_name == QLatin1String("runtime")) { + QRuntimeGraphicsSystem *r = + static_cast(QApplicationPrivate::graphics_system); + r->setGraphicsSystem(system); + } else +#endif + QApplicationPrivate::graphics_system_name = system; } /*! diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index f4c7304..1134a9b 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -62,6 +62,10 @@ #include "qpaintengine.h" #include "private/qmenubar_p.h" #include "private/qsoftkeymanager_p.h" +#ifdef QT_GRAPHICSSYSTEM_RUNTIME +#include "private/qgraphicssystem_runtime_p.h" +#endif + #include "apgwgnam.h" // For CApaWindowGroupName #include // For CMdaAudioToneUtility @@ -83,6 +87,10 @@ QT_BEGIN_NAMESPACE +// Goom Events through Window Server +static const int KGoomMemoryLowEvent = 0x10282DBF; +static const int KGoomMemoryGoodEvent = 0x20026790; + #if defined(QT_DEBUG) static bool appNoGrab = false; // Grabbing enabled #endif @@ -855,7 +863,16 @@ void QSymbianControl::Draw(const TRect& controlRect) const const TRect backingStoreRect(TPoint(backingStoreBase.x(), backingStoreBase.y()), controlRect.Size()); if (engine->type() == QPaintEngine::Raster) { - QS60WindowSurface *s60Surface = static_cast(qwidget->windowSurface()); + QS60WindowSurface *s60Surface; +#ifdef QT_GRAPHICSSYSTEM_RUNTIME + if (QApplicationPrivate::graphics_system_name == QLatin1String("runtime")) { + QRuntimeWindowSurface *rtSurface = + static_cast(qwidget->windowSurface()); + s60Surface = static_cast(rtSurface->m_windowSurface); + } else +#endif + s60Surface = static_cast(qwidget->windowSurface()); + CFbsBitmap *bitmap = s60Surface->symbianBitmap(); CWindowGc &gc = SystemGc(); @@ -1738,6 +1755,53 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent } #endif break; + case KGoomMemoryLowEvent: +#ifdef QT_DEBUG + qDebug() << "QApplicationPrivate::symbianProcessWsEvent - KGoomMemoryLowEvent"; +#endif + if (callSymbianEventFilters(symbianEvent)) + return 1; +#ifdef QT_GRAPHICSSYSTEM_RUNTIME + if(QApplicationPrivate::graphics_system_name == QLatin1String("runtime")) { + bool switchToSwRendering(false); + + foreach (QWidget *w, QApplication::topLevelWidgets()) { + if(w->d_func()->topData()->backingStore) { + switchToSwRendering = true; + break; + } + } + + if (switchToSwRendering) { + QRuntimeGraphicsSystem *gs = + static_cast(QApplicationPrivate::graphics_system); + + uint memoryUsage = gs->memoryUsage(); + uint memoryForFullscreen = ( S60->screenDepth / 8 ) + * S60->screenWidthInPixels + * S60->screenHeightInPixels; + + S60->memoryLimitForHwRendering = memoryUsage - memoryForFullscreen; + gs->setGraphicsSystem(QLatin1String("raster")); + } + } +#endif + break; + case KGoomMemoryGoodEvent: +#ifdef QT_DEBUG + qDebug() << "QApplicationPrivate::symbianProcessWsEvent - KGoomMemoryGoodEvent"; +#endif + if (callSymbianEventFilters(symbianEvent)) + return 1; +#ifdef QT_GRAPHICSSYSTEM_RUNTIME + if(QApplicationPrivate::graphics_system_name == QLatin1String("runtime")) { + QRuntimeGraphicsSystem *gs = + static_cast(QApplicationPrivate::graphics_system); + gs->setGraphicsSystem(QLatin1String("openvg"), S60->memoryLimitForHwRendering); + S60->memoryLimitForHwRendering = 0; + } +#endif + break; default: break; } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 58da302..645e969 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -123,6 +123,7 @@ public: int supportsPremultipliedAlpha : 1; int avkonComponentsSupportTransparency : 1; int menuBeingConstructed : 1; + int memoryLimitForHwRendering; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type static inline void updateScreenSize(); static inline RWsSession& wsSession(); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 60f38f2..064bf03 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -248,9 +248,14 @@ QWidgetPrivate::~QWidgetPrivate() QWindowSurface *QWidgetPrivate::createDefaultWindowSurface() { Q_Q(QWidget); + + QWindowSurface *surface; if (QApplicationPrivate::graphicsSystem()) - return QApplicationPrivate::graphicsSystem()->createWindowSurface(q); - return createDefaultWindowSurface_sys(); + surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q); + else + surface = createDefaultWindowSurface_sys(); + + return surface; } /*! diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index ed8ee76..123af1c 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -118,12 +118,14 @@ embedded { } else { HEADERS += \ painting/qgraphicssystem_raster_p.h \ + painting/qgraphicssystem_runtime_p.h \ painting/qgraphicssystemfactory_p.h \ painting/qgraphicssystemplugin_p.h \ painting/qwindowsurface_raster_p.h \ SOURCES += \ painting/qgraphicssystem_raster.cpp \ + painting/qgraphicssystem_runtime.cpp \ painting/qgraphicssystemfactory.cpp \ painting/qgraphicssystemplugin.cpp \ painting/qwindowsurface_raster.cpp \ diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp new file mode 100644 index 0000000..dfa9bd3 --- /dev/null +++ b/src/gui/painting/qgraphicssystem_runtime.cpp @@ -0,0 +1,443 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#define READBACK(f) \ + m_graphicsSystem->decreaseMemoryUsage(memoryUsage()); \ + f \ + readBackInfo(); \ + m_graphicsSystem->increaseMemoryUsage(memoryUsage()); \ + + +class QDeferredGraphicsSystemChange : public QObject +{ + Q_OBJECT + +public: + QDeferredGraphicsSystemChange(QRuntimeGraphicsSystem *gs, const QString& graphicsSystemName) + : m_graphicsSystem(gs), m_graphicsSystemName(graphicsSystemName) + { + } + + void launch() + { + QTimer::singleShot(0, this, SLOT(doChange())); + } + +private slots: + + void doChange() + { + m_graphicsSystem->setGraphicsSystem(m_graphicsSystemName); + deleteLater(); + } + +private: + + QRuntimeGraphicsSystem *m_graphicsSystem; + QString m_graphicsSystemName; +}; + +QRuntimePixmapData::QRuntimePixmapData(const QRuntimeGraphicsSystem *gs, PixelType type) + : QPixmapData(type, RuntimeClass), m_graphicsSystem(gs) +{ + setSerialNumber((int)this); +} + +QRuntimePixmapData::~QRuntimePixmapData() +{ + m_graphicsSystem->removePixmapData(this); + delete m_data; +} + +void QRuntimePixmapData::readBackInfo() +{ + w = m_data->width(); + h = m_data->height(); + d = m_data->depth(); + is_null = m_data->isNull(); +} + + +QPixmapData *QRuntimePixmapData::createCompatiblePixmapData() const +{ + QRuntimePixmapData *rtData = new QRuntimePixmapData(m_graphicsSystem, pixelType()); + rtData->m_data = m_data->createCompatiblePixmapData(); + return rtData; +} + + +void QRuntimePixmapData::resize(int width, int height) +{ + READBACK( + m_data->resize(width, height); + ) +} + + +void QRuntimePixmapData::fromImage(const QImage &image, + Qt::ImageConversionFlags flags) +{ + READBACK( + m_data->fromImage(image, flags); + ) +} + + +bool QRuntimePixmapData::fromFile(const QString &filename, const char *format, + Qt::ImageConversionFlags flags) +{ + bool success(false); + READBACK( + success = m_data->fromFile(filename, format, flags); + ) + return success; +} + +bool QRuntimePixmapData::fromData(const uchar *buffer, uint len, const char *format, + Qt::ImageConversionFlags flags) +{ + bool success(false); + READBACK( + success = m_data->fromData(buffer, len, format, flags); + ) + return success; +} + + +void QRuntimePixmapData::copy(const QPixmapData *data, const QRect &rect) +{ + if (data->runtimeData()) { + READBACK( + m_data->copy(data->runtimeData(), rect); + ) + } else { + READBACK( + m_data->copy(data, rect); + ) + } +} + +bool QRuntimePixmapData::scroll(int dx, int dy, const QRect &rect) +{ + return m_data->scroll(dx, dy, rect); +} + + +int QRuntimePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const +{ + return m_data->metric(metric); +} + +void QRuntimePixmapData::fill(const QColor &color) +{ + return m_data->fill(color); +} + +QBitmap QRuntimePixmapData::mask() const +{ + return m_data->mask(); +} + +void QRuntimePixmapData::setMask(const QBitmap &mask) +{ + READBACK( + m_data->setMask(mask); + ) +} + +bool QRuntimePixmapData::hasAlphaChannel() const +{ + return m_data->hasAlphaChannel(); +} + +QPixmap QRuntimePixmapData::transformed(const QTransform &matrix, + Qt::TransformationMode mode) const +{ + return m_data->transformed(matrix, mode); +} + +void QRuntimePixmapData::setAlphaChannel(const QPixmap &alphaChannel) +{ + READBACK( + m_data->setAlphaChannel(alphaChannel); + ) +} + +QPixmap QRuntimePixmapData::alphaChannel() const +{ + return m_data->alphaChannel(); +} + +QImage QRuntimePixmapData::toImage() const +{ + return m_data->toImage(); +} + +QPaintEngine* QRuntimePixmapData::paintEngine() const +{ + return m_data->paintEngine(); +} + +QImage* QRuntimePixmapData::buffer() +{ + return m_data->buffer(); +} + +#if defined(Q_OS_SYMBIAN) +void* QRuntimePixmapData::toNativeType(NativeType type) +{ + return m_data->toNativeType(type); +} + +void QRuntimePixmapData::fromNativeType(void *pixmap, NativeType type) +{ + m_data->fromNativeType(pixmap, type); + readBackInfo(); +} +#endif + +QPixmapData* QRuntimePixmapData::runtimeData() const +{ + return m_data; +} + +uint QRuntimePixmapData::memoryUsage() const +{ + if(is_null || d == 0) + return 0; + return w * h * (d / 8); +} + + +QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window) + : QWindowSurface(window), m_windowSurface(0), m_pendingWindowSurface(0), m_graphicsSystem(gs) +{ + +} + +QRuntimeWindowSurface::~QRuntimeWindowSurface() +{ + m_graphicsSystem->removeWindowSurface(this); + delete m_windowSurface; +} + +QPaintDevice *QRuntimeWindowSurface::paintDevice() +{ + return m_windowSurface->paintDevice(); +} + +void QRuntimeWindowSurface::flush(QWidget *widget, const QRegion ®ion, + const QPoint &offset) +{ + m_windowSurface->flush(widget, region, offset); + + int destroyPolicy = m_graphicsSystem->windowSurfaceDestroyPolicy(); + if(m_pendingWindowSurface && + destroyPolicy == QRuntimeGraphicsSystem::DestroyAfterFirstFlush) { +#ifdef QT_DEBUG + qDebug() << "QRuntimeWindowSurface::flush() - destroy pending window surface"; +#endif + delete m_pendingWindowSurface; + m_pendingWindowSurface = 0; + } +} + +void QRuntimeWindowSurface::setGeometry(const QRect &rect) +{ + m_graphicsSystem->decreaseMemoryUsage(memoryUsage()); + m_windowSurface->setGeometry(rect); + m_graphicsSystem->increaseMemoryUsage(memoryUsage()); +} + +bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy) +{ + return m_windowSurface->scroll(area, dx, dy); +} + +void QRuntimeWindowSurface::beginPaint(const QRegion &rgn) +{ + m_windowSurface->beginPaint(rgn); +} + +void QRuntimeWindowSurface::endPaint(const QRegion &rgn) +{ + m_windowSurface->endPaint(rgn); +} + +QImage* QRuntimeWindowSurface::buffer(const QWidget *widget) +{ + return m_windowSurface->buffer(widget); +} + +QPixmap QRuntimeWindowSurface::grabWidget(const QWidget *widget, const QRect& rectangle) const +{ + return m_windowSurface->grabWidget(widget, rectangle); +} + +QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const +{ + return m_windowSurface->offset(widget); +} + +uint QRuntimeWindowSurface::memoryUsage() const +{ + QPaintDevice *pdev = m_windowSurface->paintDevice(); + if (pdev && pdev->depth() != 0) + return pdev->width() * pdev->height() * (pdev->depth()/8); + + return 0; +} + +QRuntimeGraphicsSystem::QRuntimeGraphicsSystem() + : m_memoryUsage(0), m_windowSurfaceDestroyPolicy(DestroyImmediately), + m_graphicsSystem(0), m_graphicsSystemChangeMemoryLimit(0) +{ + QApplicationPrivate::graphics_system_name = QLatin1String("runtime"); + +#ifdef Q_OS_SYMBIAN + m_graphicsSystemName = QLatin1String("openvg"); + m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush; +#else + m_graphicsSystemName = QLatin1String("raster"); +#endif + + m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName); +} + + +QPixmapData *QRuntimeGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const +{ + Q_ASSERT(m_graphicsSystem); + QPixmapData *data = m_graphicsSystem->createPixmapData(type); + + QRuntimePixmapData *rtData = new QRuntimePixmapData(this, type); + rtData->m_data = data; + m_pixmapDatas << rtData; + + return rtData; +} + +QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) const +{ + Q_ASSERT(m_graphicsSystem); + QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget); + rtSurface->m_windowSurface = m_graphicsSystem->createWindowSurface(widget); + widget->setWindowSurface(rtSurface); + m_windowSurfaces << rtSurface; + increaseMemoryUsage(rtSurface->memoryUsage()); + return rtSurface; +} + +/*! + Sets graphics system when resource memory consumption is under /a memoryUsageLimit. +*/ +void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name, uint memoryUsageLimit) +{ +#ifdef QT_DEBUG + qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( "<< name <<", " << memoryUsageLimit << ")"; + qDebug() << " current approximated graphics system memory usage " << memoryUsage() << " bytes"; +#endif + if (memoryUsage() >= memoryUsageLimit) { + m_graphicsSystemChangeMemoryLimit = memoryUsageLimit; + m_pendingGraphicsSystemName = name; + } else { + setGraphicsSystem(name); + } +} + +void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name) +{ + if (m_graphicsSystemName == name) + return; +#ifdef QT_DEBUG + qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )"; + qDebug() << " current approximated graphics system memory usage "<< memoryUsage() << " bytes"; +#endif + delete m_graphicsSystem; + m_graphicsSystem = QGraphicsSystemFactory::create(name); + m_graphicsSystemName = name; + + Q_ASSERT(m_graphicsSystem); + + m_graphicsSystemChangeMemoryLimit = 0; + m_pendingGraphicsSystemName = QString(); + + for (int i = 0; i < m_pixmapDatas.size(); ++i) { + QRuntimePixmapData *proxy = m_pixmapDatas.at(i); + QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data->pixelType()); + // ### TODO Optimize. Openvg and s60raster graphics systems could switch internal ARGB32_PRE QImage buffers. + newData->fromImage(proxy->m_data->toImage(), Qt::AutoColor | Qt::OrderedAlphaDither); + delete proxy->m_data; + proxy->m_data = newData; + proxy->readBackInfo(); + } + + for (int i = 0; i < m_windowSurfaces.size(); ++i) { + QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i); + QWidget *widget = proxy->m_windowSurface->window(); + + if(m_windowSurfaceDestroyPolicy == DestroyImmediately) { + delete proxy->m_windowSurface; + proxy->m_pendingWindowSurface = 0; + } else { + proxy->m_pendingWindowSurface = proxy->m_windowSurface; + } + + proxy->m_windowSurface = m_graphicsSystem->createWindowSurface(widget); + qt_widget_private(widget)->invalidateBuffer(widget->rect()); + } +} + +void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const +{ + int index = m_pixmapDatas.lastIndexOf(pixmapData); + m_pixmapDatas.removeAt(index); + decreaseMemoryUsage(pixmapData->memoryUsage(), true); +} + +void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const +{ + int index = m_windowSurfaces.lastIndexOf(windowSurface); + m_windowSurfaces.removeAt(index); + decreaseMemoryUsage(windowSurface->memoryUsage(), true); +} + +void QRuntimeGraphicsSystem::increaseMemoryUsage(uint amount) const +{ + m_memoryUsage += amount; + + if (m_graphicsSystemChangeMemoryLimit && + m_memoryUsage < m_graphicsSystemChangeMemoryLimit) { + + QRuntimeGraphicsSystem *gs = const_cast(this); + QDeferredGraphicsSystemChange *deferredChange = + new QDeferredGraphicsSystemChange(gs, m_pendingGraphicsSystemName); + deferredChange->launch(); + } +} + +void QRuntimeGraphicsSystem::decreaseMemoryUsage(uint amount, bool persistent) const +{ + m_memoryUsage -= amount; + + if (persistent && m_graphicsSystemChangeMemoryLimit && + m_memoryUsage < m_graphicsSystemChangeMemoryLimit) { + + QRuntimeGraphicsSystem *gs = const_cast(this); + QDeferredGraphicsSystemChange *deferredChange = + new QDeferredGraphicsSystemChange(gs, m_pendingGraphicsSystemName); + deferredChange->launch(); + } +} + +#include "qgraphicssystem_runtime.moc" + +QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystem_runtime_p.h b/src/gui/painting/qgraphicssystem_runtime_p.h new file mode 100644 index 0000000..445f83d --- /dev/null +++ b/src/gui/painting/qgraphicssystem_runtime_p.h @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSYSTEM_RUNTIME_P_H +#define QGRAPHICSSYSTEM_RUNTIME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qgraphicssystem_p.h" + +#include + +QT_BEGIN_NAMESPACE + +class QRuntimeGraphicsSystem; + +class QRuntimePixmapData : public QPixmapData { +public: + QRuntimePixmapData(const QRuntimeGraphicsSystem *gs, PixelType type); + ~QRuntimePixmapData(); + + virtual QPixmapData *createCompatiblePixmapData() const; + virtual void resize(int width, int height); + virtual void fromImage(const QImage &image, + Qt::ImageConversionFlags flags); + + virtual bool fromFile(const QString &filename, const char *format, + Qt::ImageConversionFlags flags); + virtual bool fromData(const uchar *buffer, uint len, const char *format, + Qt::ImageConversionFlags flags); + + virtual void copy(const QPixmapData *data, const QRect &rect); + virtual bool scroll(int dx, int dy, const QRect &rect); + + virtual int metric(QPaintDevice::PaintDeviceMetric metric) const; + virtual void fill(const QColor &color); + virtual QBitmap mask() const; + virtual void setMask(const QBitmap &mask); + virtual bool hasAlphaChannel() const; + virtual QPixmap transformed(const QTransform &matrix, + Qt::TransformationMode mode) const; + virtual void setAlphaChannel(const QPixmap &alphaChannel); + virtual QPixmap alphaChannel() const; + virtual QImage toImage() const; + virtual QPaintEngine *paintEngine() const; + + virtual QImage *buffer(); + + void readBackInfo(); + + QPixmapData *m_data; + +#if defined(Q_OS_SYMBIAN) + void* toNativeType(NativeType type); + void fromNativeType(void* pixmap, NativeType type); +#endif + + virtual QPixmapData *runtimeData() const; + + virtual uint memoryUsage() const; + +private: + const QRuntimeGraphicsSystem *m_graphicsSystem; + +}; + +class QRuntimeWindowSurface : public QWindowSurface { +public: + QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window); + ~QRuntimeWindowSurface(); + + virtual QPaintDevice *paintDevice(); + virtual void flush(QWidget *widget, const QRegion ®ion, + const QPoint &offset); + virtual void setGeometry(const QRect &rect); + + virtual bool scroll(const QRegion &area, int dx, int dy); + + virtual void beginPaint(const QRegion &); + virtual void endPaint(const QRegion &); + + virtual QImage* buffer(const QWidget *widget); + virtual QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const; + + virtual QPoint offset(const QWidget *widget) const; + + virtual uint memoryUsage() const; + + QWindowSurface *m_windowSurface; + QWindowSurface *m_pendingWindowSurface; + +private: + const QRuntimeGraphicsSystem *m_graphicsSystem; +}; + +class QRuntimeGraphicsSystem : public QGraphicsSystem +{ +public: + + enum WindowSurfaceDestroyPolicy + { + DestroyImmediately, + DestroyAfterFirstFlush + }; + +public: + QRuntimeGraphicsSystem(); + + QPixmapData *createPixmapData(QPixmapData::PixelType type) const; + QWindowSurface *createWindowSurface(QWidget *widget) const; + + void removePixmapData(QRuntimePixmapData *pixmapData) const; + void removeWindowSurface(QRuntimeWindowSurface *windowSurface) const; + + void setGraphicsSystem(const QString &name, uint memoryUsageLimit); + void setGraphicsSystem(const QString &name); + QString graphicsSystemName() const { return m_graphicsSystemName; } + + void setWindowSurfaceDestroyPolicy(WindowSurfaceDestroyPolicy policy) + { + m_windowSurfaceDestroyPolicy = policy; + } + + int windowSurfaceDestroyPolicy() const { return m_windowSurfaceDestroyPolicy; } + + int memoryUsage() const { return m_memoryUsage; } + +private: + + void increaseMemoryUsage(uint amount) const; + void decreaseMemoryUsage(uint amount, bool persistent = false) const; + +private: + mutable uint m_memoryUsage; + int m_windowSurfaceDestroyPolicy; + QGraphicsSystem *m_graphicsSystem; + mutable QList m_pixmapDatas; + mutable QList m_windowSurfaces; + QString m_graphicsSystemName; + + uint m_graphicsSystemChangeMemoryLimit; + QString m_pendingGraphicsSystemName; + + friend class QRuntimePixmapData; + friend class QRuntimeWindowSurface; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index 3c09894..ee6fbd8 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -46,6 +46,7 @@ #include "qapplication.h" #include "qgraphicssystem_raster_p.h" +#include "qgraphicssystem_runtime_p.h" #include "qdebug.h" QT_BEGIN_NAMESPACE @@ -68,6 +69,10 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) if (system.isEmpty()) { system = QLatin1String("openvg"); } +#elif defined (QT_GRAPHICSSYSTEM_RUNTIME) + if (system.isEmpty()) { + system = QLatin1String("runtime"); + } #elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) if (system.isEmpty()) { system = QLatin1String("raster"); @@ -76,6 +81,8 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) if (system == QLatin1String("raster")) return new QRasterGraphicsSystem; + else if (system == QLatin1String("runtime")) + return new QRuntimeGraphicsSystem; else if (system.isEmpty() || system == QLatin1String("native")) return 0; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 6f395f6..48974e8 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -441,8 +441,9 @@ bool QRasterPaintEngine::begin(QPaintDevice *device) if (device->devType() == QInternal::Pixmap) { QPixmap *pixmap = static_cast(device); - if (pixmap->data->classId() == QPixmapData::RasterClass) - d->device = pixmap->data->buffer(); + QPixmapData *pd = pixmap->pixmapData(); + if (pd->classId() == QPixmapData::RasterClass) + d->device = pd->buffer(); } else { d->device = device; } @@ -2358,8 +2359,9 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap) qDebug() << " - QRasterPaintEngine::drawPixmap(), pos=" << pos << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth(); #endif - if (pixmap.data->classId() == QPixmapData::RasterClass) { - const QImage &image = static_cast(pixmap.data.data())->image; + QPixmapData *pd = pixmap.pixmapData(); + if (pd->classId() == QPixmapData::RasterClass) { + const QImage &image = static_cast(pd)->image; if (image.depth() == 1) { Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); @@ -2398,8 +2400,9 @@ void QRasterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, cons qDebug() << " - QRasterPaintEngine::drawPixmap(), r=" << r << " sr=" << sr << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth(); #endif - if (pixmap.data->classId() == QPixmapData::RasterClass) { - const QImage &image = static_cast(pixmap.data.data())->image; + QPixmapData* pd = pixmap.pixmapData(); + if (pd->classId() == QPixmapData::RasterClass) { + const QImage &image = static_cast(pd)->image; if (image.depth() == 1) { Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); @@ -2703,8 +2706,9 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, QImage image; - if (pixmap.data->classId() == QPixmapData::RasterClass) { - image = static_cast(pixmap.data.data())->image; + QPixmapData *pd = pixmap.pixmapData(); + if (pd->classId() == QPixmapData::RasterClass) { + image = static_cast(pd)->image; } else { image = pixmap.toImage(); } diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp index e18ea3f..2fe9036 100644 --- a/src/gui/painting/qwindowsurface.cpp +++ b/src/gui/painting/qwindowsurface.cpp @@ -116,8 +116,6 @@ public: QWindowSurface::QWindowSurface(QWidget *window) : d_ptr(new QWindowSurfacePrivate(window)) { - if (window) - window->setWindowSurface(this); } /*! diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index b25dce5..93d4d18 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -43,10 +43,15 @@ #include #include -#include "qwindowsurface_s60_p.h" +#include #include #include -#include "private/qdrawhelper_p.h" +#include +#include + +#ifdef QT_GRAPHICSSYSTEM_RUNTIME +#include +#endif QT_BEGIN_NAMESPACE @@ -79,13 +84,35 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget) setStaticContentsSupport(true); } + QS60WindowSurface::~QS60WindowSurface() { +#if defined(QT_GRAPHICSSYSTEM_RUNTIME) && defined(Q_SYMBIAN_SUPPORTS_SURFACES) + if(QApplicationPrivate::graphics_system_name == QLatin1String("runtime")) { + QRuntimeGraphicsSystem *runtimeGraphicsSystem = + static_cast(QApplicationPrivate::graphics_system); + if(runtimeGraphicsSystem->graphicsSystemName() == QLatin1String("openvg")) { + + // Graphics system has been switched from raster to openvg. + // Issue empty redraw to clear the UI surface + + QWidget *w = window(); + RWindow *const window = static_cast(w->winId()->DrawableWindow()); + window->BeginRedraw(); + window->EndRedraw(); + } + } +#endif + delete d_ptr; } void QS60WindowSurface::beginPaint(const QRegion &rgn) { +#ifdef Q_SYMBIAN_SUPPORTS_SURFACES + S60->wsSession().Finish(); +#endif + if (!qt_widget_private(window())->isOpaque) { QS60PixmapData *pixmapData = static_cast(d_ptr->device.data_ptr().data()); pixmapData->beginDataAccess(); diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index bfa7445..ea89734 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1135,7 +1135,8 @@ void Configure::parseCmdLine() QString system = configCmdLine.at(i); if (system == QLatin1String("raster") || system == QLatin1String("opengl") - || system == QLatin1String("openvg")) + || system == QLatin1String("openvg") + || system == QLatin1String("runtime")) dictionary["GRAPHICS_SYSTEM"] = configCmdLine.at(i); } @@ -1605,7 +1606,7 @@ bool Configure::displayHelp() "[-no-multimedia] [-multimedia] [-no-audio-backend] [-audio-backend]\n" "[-no-mediaservices] [-mediaservices] [-no-media-backend] [-media-backend]\n" "[-no-script] [-script] [-no-scripttools] [-scripttools]\n" - "[-no-webkit] [-webkit] [-graphicssystem raster|opengl|openvg]\n\n", 0, 7); + "[-no-webkit] [-webkit] [-graphicssystem raster|opengl|openvg|runtime]\n\n", 0, 7); desc("Installation options:\n\n"); @@ -1708,9 +1709,10 @@ bool Configure::displayHelp() #endif desc( "-graphicssystem ", "Specify which graphicssystem should be used.\n" "Available values for :"); - desc("GRAPHICS_SYSTEM", "raster", "", " raster - Software rasterizer", ' '); - desc("GRAPHICS_SYSTEM", "opengl", "", " opengl - Using OpenGL acceleration, experimental!", ' '); - desc("GRAPHICS_SYSTEM", "openvg", "", " openvg - Using OpenVG acceleration, experimental!", ' '); + desc("GRAPHICS_SYSTEM", "raster", "", " raster - Software rasterizer", ' '); + desc("GRAPHICS_SYSTEM", "opengl", "", " opengl - Using OpenGL acceleration, experimental!", ' '); + desc("GRAPHICS_SYSTEM", "openvg", "", " openvg - Using OpenVG acceleration, experimental!", ' '); + desc("GRAPHICS_SYSTEM", "runtime", "", " runtime - Runtime switching of graphics sytems", ' '); desc( "-help, -h, -?", "Display this information.\n"); @@ -3075,9 +3077,10 @@ void Configure::generateConfigfiles() if(dictionary["SQL_SQLITE2"] == "yes") qconfigList += "QT_SQL_SQLITE2"; if(dictionary["SQL_IBASE"] == "yes") qconfigList += "QT_SQL_IBASE"; - if (dictionary["GRAPHICS_SYSTEM"] == "openvg") qconfigList += "QT_GRAPHICSSYSTEM_OPENVG"; - if (dictionary["GRAPHICS_SYSTEM"] == "opengl") qconfigList += "QT_GRAPHICSSYSTEM_OPENGL"; - if (dictionary["GRAPHICS_SYSTEM"] == "raster") qconfigList += "QT_GRAPHICSSYSTEM_RASTER"; + if (dictionary["GRAPHICS_SYSTEM"] == "openvg") qconfigList += "QT_GRAPHICSSYSTEM_OPENVG"; + if (dictionary["GRAPHICS_SYSTEM"] == "opengl") qconfigList += "QT_GRAPHICSSYSTEM_OPENGL"; + if (dictionary["GRAPHICS_SYSTEM"] == "raster") qconfigList += "QT_GRAPHICSSYSTEM_RASTER"; + if (dictionary["GRAPHICS_SYSTEM"] == "runtime") qconfigList += "QT_GRAPHICSSYSTEM_RUNTIME"; if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) { // These features are not ported to Symbian (yet) -- cgit v0.12 From a20f6367824dec6c8e48200cc86f9eb7903b6bcb Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 20 May 2010 15:44:29 +0300 Subject: Fix build error on S60 3.1 environments Fixed build error in Symbian environments where SNAP_FUNCTIONALITY_AVAILABLE is not defined. Reviewed-by: Janne Koskinen --- src/plugins/bearer/symbian/qnetworksession_impl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h index 9767293..1d30dd5 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.h +++ b/src/plugins/bearer/symbian/qnetworksession_impl.h @@ -73,9 +73,9 @@ QT_BEGIN_NAMESPACE class ConnectionProgressNotifier; class SymbianEngine; -class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive, +class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive #ifdef SNAP_FUNCTIONALITY_AVAILABLE - public MMobilityProtocolResp + , public MMobilityProtocolResp #endif { Q_OBJECT -- cgit v0.12 From 1f1ff85bb9841d1b040b25af9a5c99a5c1f87e58 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 21 May 2010 17:54:17 +1000 Subject: Add missing license header. Reviewed-by: Trust Me --- src/gui/painting/qgraphicssystem_runtime.cpp | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp index dfa9bd3..ceb16ed 100644 --- a/src/gui/painting/qgraphicssystem_runtime.cpp +++ b/src/gui/painting/qgraphicssystem_runtime.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include #include #include -- cgit v0.12 From 24b811e53b30546279346ab7b16799be119ab8c4 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 20 May 2010 11:25:47 +0200 Subject: Enable QTouchEvent for S60 5.0 Symbian OS doesn't support advanced pointer events before Symbian^3 Advanced pointer events are required for multitouch, and are used to generate QTouchEvents. This change enables sending of a single touch point QTouchEvent on touchscreen phones based on earlier Symbian OS versions. i.e. S60 5th edition On devices without advanced pointers, or where the hardware does not support pressure detection, the pressure is set to 1.0 in the touch event. This is consistent with the Mac port. Task-number: QTBUG-5668 Reviewed-by: Bradley T. Hughes --- src/gui/kernel/qapplication_p.h | 3 ++- src/gui/kernel/qapplication_s60.cpp | 53 +++++++++++++++++++++++++++++-------- src/gui/kernel/qt_s60_p.h | 1 + 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 01abe54..e30b6be 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -581,7 +581,8 @@ public: void _q_readRX71MultiTouchEvents(); #endif -#if defined(Q_WS_S60) +#if defined(Q_OS_SYMBIAN) + int pressureSupported; int maxTouchPressure; QList appAllTouchPoints; #endif diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 803241e..7e270aa 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -416,25 +416,44 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event) { QApplicationPrivate *d = QApplicationPrivate::instance(); + QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY)); + qreal pressure; + if(d->pressureSupported + && event->Pressure() > 0) //workaround for misconfigured HAL + pressure = event->Pressure() / qreal(d->maxTouchPressure); + else + pressure = qreal(1.0); + processTouchEvent(event->PointerNumber(), event->iType, screenPos, pressure); +} +#endif +void QSymbianControl::processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure) +{ QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget); - while (d->appAllTouchPoints.count() <= event->PointerNumber()) - d->appAllTouchPoints.append(QTouchEvent::TouchPoint(d->appAllTouchPoints.count())); + QApplicationPrivate *d = QApplicationPrivate::instance(); + + QList points = d->appAllTouchPoints; + while (points.count() <= pointerNumber) + points.append(QTouchEvent::TouchPoint(points.count())); Qt::TouchPointStates allStates = 0; - for (int i = 0; i < d->appAllTouchPoints.count(); ++i) { - QTouchEvent::TouchPoint &touchPoint = d->appAllTouchPoints[i]; + for (int i = 0; i < points.count(); ++i) { + QTouchEvent::TouchPoint &touchPoint = points[i]; - if (touchPoint.id() == event->PointerNumber()) { + if (touchPoint.id() == pointerNumber) { Qt::TouchPointStates state; - switch (event->iType) { + switch (type) { case TPointerEvent::EButton1Down: +#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER case TPointerEvent::EEnterHighPressure: +#endif state = Qt::TouchPointPressed; break; case TPointerEvent::EButton1Up: +#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER case TPointerEvent::EExitCloseProximity: +#endif state = Qt::TouchPointReleased; break; case TPointerEvent::EDrag: @@ -445,16 +464,15 @@ void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent state = Qt::TouchPointStationary; break; } - if (event->PointerNumber() == 0) + if (pointerNumber == 0) state |= Qt::TouchPointPrimary; touchPoint.setState(state); - QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY)); touchPoint.setScreenPos(screenPos); touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(), screenPos.y() / screenGeometry.height())); - touchPoint.setPressure(event->Pressure() / qreal(d->maxTouchPressure)); + touchPoint.setPressure(pressure); } else if (touchPoint.state() != Qt::TouchPointReleased) { // all other active touch points should be marked as stationary touchPoint.setState(Qt::TouchPointStationary); @@ -466,13 +484,14 @@ void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) { // all touch points released d->appAllTouchPoints.clear(); + } else { + d->appAllTouchPoints = points; } QApplicationPrivate::translateRawTouchEvent(qwidget, QTouchEvent::TouchScreen, - d->appAllTouchPoints); + points); } -#endif void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) { @@ -546,6 +565,13 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) qt_symbian_move_cursor_sprite(); #endif +//Generate single touch event for S60 5.0 (has touchscreen, does not have advanced pointers) +#ifndef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER + if (S60->hasTouchscreen) { + processTouchEvent(0, pEvent.iType, QPointF(globalPos), 1.0); + } +#endif + sendMouseEvent(receiver, type, globalPos, button, modifiers); } @@ -2047,8 +2073,13 @@ TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym) void QApplicationPrivate::initializeMultitouch_sys() { #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER + if (HAL::Get(HALData::EPointer3DPressureSupported, pressureSupported) != KErrNone) + pressureSupported = 0; if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone) maxTouchPressure = KMaxTInt; +#else + pressureSupported = 0; + maxTouchPressure = KMaxTInt; #endif } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 232e9b3..fe3fa57 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -217,6 +217,7 @@ private: const QPoint &globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers); + void processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure); void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation ); #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); -- cgit v0.12