diff options
author | Jani Hautakangas <ext-jani.hautakangas@nokia.com> | 2009-09-18 11:33:10 (GMT) |
---|---|---|
committer | Jani Hautakangas <ext-jani.hautakangas@nokia.com> | 2009-09-18 11:33:10 (GMT) |
commit | c78dabc55943b76479f7a84bae146f52cbc7bbbf (patch) | |
tree | 5ea4392cf14c1126c82603b9ee614c384f28bd9e /src/gui/painting | |
parent | 6454aca1b273daa2e54a77f83e1f6d4bae83427d (diff) | |
download | Qt-c78dabc55943b76479f7a84bae146f52cbc7bbbf.zip Qt-c78dabc55943b76479f7a84bae146f52cbc7bbbf.tar.gz Qt-c78dabc55943b76479f7a84bae146f52cbc7bbbf.tar.bz2 |
Introduce native Symbian bitmap support to QPixmap
This is done to reduce heap consumption and to give
a possibility to share bitmaps across process. QPixmap
maps to Symbian CFbsBitmap which is stored in Symbian
font and bitmap server.
Reviewed-by: Jason Barron
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/painting.pri | 6 | ||||
-rw-r--r-- | src/gui/painting/qgraphicssystem.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_s60.cpp | 73 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_s60_p.h | 54 | ||||
-rw-r--r-- | src/gui/painting/qwindowsurface_s60.cpp | 158 | ||||
-rw-r--r-- | src/gui/painting/qwindowsurface_s60_p.h | 8 |
6 files changed, 196 insertions, 112 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 8343cb9..c35c33a 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -14,7 +14,7 @@ HEADERS += \ painting/qoutlinemapper_p.h \ painting/qpaintdevice.h \ painting/qpaintengine.h \ - painting/qpaintengine_p.h \ + painting/qpaintengine_p.h \ painting/qpaintengine_alpha_p.h \ painting/qpaintengine_preview_p.h \ painting/qpaintengineex_p.h \ @@ -179,8 +179,12 @@ embedded { symbian { SOURCES += \ + painting/qpaintengine_s60.cpp \ painting/qregion_s60.cpp \ painting/qcolormap_s60.cpp + + HEADERS += \ + painting/qpaintengine_s60_p.h } x11|embedded { diff --git a/src/gui/painting/qgraphicssystem.cpp b/src/gui/painting/qgraphicssystem.cpp index 20d6f22..2d9603d 100644 --- a/src/gui/painting/qgraphicssystem.cpp +++ b/src/gui/painting/qgraphicssystem.cpp @@ -44,12 +44,15 @@ #ifdef Q_WS_X11 # include <private/qpixmap_x11_p.h> #endif -#if defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) +#if defined(Q_WS_WIN) # include <private/qpixmap_raster_p.h> #endif #ifdef Q_WS_MAC # include <private/qpixmap_mac_p.h> #endif +#ifdef Q_WS_S60 +# include <private/qpixmap_s60_p.h> +#endif QT_BEGIN_NAMESPACE @@ -64,10 +67,12 @@ QPixmapData *QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixelType typ #endif #if defined(Q_WS_X11) return new QX11PixmapData(type); -#elif defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) +#elif defined(Q_WS_WIN) return new QRasterPixmapData(type); #elif defined(Q_WS_MAC) return new QMacPixmapData(type); +#elif defined(Q_WS_S60) + return new QS60PixmapData(type); #elif !defined(Q_WS_QWS) #error QGraphicsSystem::createDefaultPixmapData() not implemented #endif diff --git a/src/gui/painting/qpaintengine_s60.cpp b/src/gui/painting/qpaintengine_s60.cpp new file mode 100644 index 0000000..2aa179a --- /dev/null +++ b/src/gui/painting/qpaintengine_s60.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <private/qpaintengine_s60_p.h> +#include <private/qpixmap_s60_p.h> +#include <private/qt_s60_p.h> + +QT_BEGIN_NAMESPACE + +class QS60PaintEnginePrivate : public QRasterPaintEnginePrivate +{ +public: + QS60PaintEnginePrivate(QS60PaintEngine *engine) { } +}; + +QS60PaintEngine::QS60PaintEngine(QPaintDevice *device, QS60PixmapData *data) + : QRasterPaintEngine(*(new QS60PaintEnginePrivate(this)), device), pixmapData(data) +{ +} + +bool QS60PaintEngine::begin(QPaintDevice *device) +{ + pixmapData->beginDataAccess(); + return QRasterPaintEngine::begin(device); +} + +bool QS60PaintEngine::end() +{ + bool ret = QRasterPaintEngine::end(); + pixmapData->endDataAccess(); + return ret; +} + +void QS60PaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm) +{ + QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); + srcData->beginDataAccess(); + QRasterPaintEngine::drawPixmap(p, pm); + srcData->endDataAccess(); +} + +void QS60PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) +{ + QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); + srcData->beginDataAccess(); + QRasterPaintEngine::drawPixmap(r, pm, sr); + srcData->endDataAccess(); +} + +void QS60PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) +{ + QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); + srcData->beginDataAccess(); + QRasterPaintEngine::drawTiledPixmap(r, pm, sr); + srcData->endDataAccess(); +} + +void QS60PaintEngine::prepare(QImage *image) +{ + QRasterBuffer *buffer = d_func()->rasterBuffer.data(); + if (buffer) + buffer->prepare(image); +} + +QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_s60_p.h b/src/gui/painting/qpaintengine_s60_p.h new file mode 100644 index 0000000..b38ef93 --- /dev/null +++ b/src/gui/painting/qpaintengine_s60_p.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#ifndef QPAINTENGINE_S60_P_H +#define QPAINTENGINE_S60_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 "private/qpaintengine_raster_p.h" + +QT_BEGIN_NAMESPACE + +class QS60PaintEnginePrivate; +class QS60PixmapData; + +class QS60PaintEngine : public QRasterPaintEngine +{ + Q_DECLARE_PRIVATE(QS60PaintEngine) + +public: + QS60PaintEngine(QPaintDevice *device, QS60PixmapData* data); + bool begin(QPaintDevice *device); + bool end(); + + void drawPixmap(const QPointF &p, const QPixmap &pm); + void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); + void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr); + + void prepare(QImage* image); + +private: + QS60PixmapData *pixmapData; +}; + +QT_END_NAMESPACE + +#endif // QPAINTENGINE_S60_P_H diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index f56902a..664ad48 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -44,6 +44,7 @@ #include <QtGui/qpaintdevice.h> #include <private/qwidget_p.h> #include "qwindowsurface_s60_p.h" +#include "qpixmap_s60_p.h" #include "qt_s60_p.h" #include "private/qdrawhelper_p.h" @@ -51,20 +52,13 @@ QT_BEGIN_NAMESPACE struct QS60WindowSurfacePrivate { - QImage device; - CFbsBitmap *bitmap; - uchar* bytes; - - // Since only one CFbsBitmap is allowed to be locked at a time, this is static. - static QS60WindowSurface* lockedSurface; + QPixmap device; + QList<QImage*> bufferImages; }; -QS60WindowSurface* QS60WindowSurfacePrivate::lockedSurface = NULL; QS60WindowSurface::QS60WindowSurface(QWidget* widget) : QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate) { - d_ptr->bytes = 0; - d_ptr->bitmap = 0; TDisplayMode mode = S60->screenDevice()->DisplayMode(); bool isOpaque = qt_widget_private(widget)->isOpaque; @@ -73,39 +67,27 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget) else if (mode == EColor16MU && !isOpaque) mode = EColor16MA; // Try for transparency anyway - // We create empty CFbsBitmap here -> it will be resized in setGeometry - d_ptr->bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new - qt_symbian_throwIfError( d_ptr->bitmap->Create(TSize(0, 0), mode ) ); - - updatePaintDeviceOnBitmap(); - + CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new + qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) ); + + QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType); + data->fromSymbianBitmap(bitmap); + d_ptr->device = QPixmap(data); + setStaticContentsSupport(true); } - QS60WindowSurface::~QS60WindowSurface() { - if (QS60WindowSurfacePrivate::lockedSurface == this) - unlockBitmapHeap(); - - delete d_ptr->bitmap; delete d_ptr; } void QS60WindowSurface::beginPaint(const QRegion &rgn) { - if(!d_ptr->bitmap) - return; - - if (QS60WindowSurfacePrivate::lockedSurface) - unlockBitmapHeap(); - - QS60WindowSurfacePrivate::lockedSurface = this; - lockBitmapHeap(); - if (!qt_widget_private(window())->isOpaque) { - QRgb *data = reinterpret_cast<QRgb *>(d_ptr->device.bits()); - const int row_stride = d_ptr->device.bytesPerLine() / 4; + QImage image = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image; + QRgb *data = reinterpret_cast<QRgb *>(image.bits()); + const int row_stride = image.bytesPerLine() / 4; const QVector<QRect> rects = rgn.rects(); for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { @@ -124,6 +106,38 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn) } } +void QS60WindowSurface::endPaint(const QRegion &) +{ + qDeleteAll(d_ptr->bufferImages); + d_ptr->bufferImages.clear(); +} + +QImage* QS60WindowSurface::buffer(const QWidget *widget) +{ + if (widget->window() != window()) + return 0; + + QPaintDevice *pdev = paintDevice(); + if (!pdev) + return 0; + + const QPoint off = offset(widget); + QImage *img = &(static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image); + + QRect rect(off, widget->size()); + rect &= QRect(QPoint(), img->size()); + + if (rect.isEmpty()) + return 0; + + img = new QImage(img->scanLine(rect.y()) + rect.x() * img->depth() / 8, + rect.width(), rect.height(), + img->bytesPerLine(), img->format()); + d_ptr->bufferImages.append(img); + + return img; +} + void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &) { const QVector<QRect> subRects = region.rects(); @@ -143,28 +157,10 @@ bool QS60WindowSurface::scroll(const QRegion &area, int dx, int dy) if (d_ptr->device.isNull()) return false; - CFbsBitmapDevice *bitmapDevice = 0; - QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(d_ptr->bitmap)); - CBitmapContext *bitmapContext; - TInt err = bitmapDevice->CreateBitmapContext(bitmapContext); - if (err != KErrNone) { - CBase::Delete(bitmapDevice); - return false; - } - bitmapContext->CopyRect(TPoint(dx, dy), qt_QRect2TRect(rect)); - CBase::Delete(bitmapContext); - CBase::Delete(bitmapDevice); - return true; -} - -void QS60WindowSurface::endPaint(const QRegion & /* rgn */) -{ - if(!d_ptr->bitmap) - return; + QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); + data->scroll(dx, dy, rect); - Q_ASSERT(QS60WindowSurfacePrivate::lockedSurface); - unlockBitmapHeap(); - QS60WindowSurfacePrivate::lockedSurface = NULL; + return true; } QPaintDevice* QS60WindowSurface::paintDevice() @@ -177,61 +173,17 @@ void QS60WindowSurface::setGeometry(const QRect& rect) if (rect == geometry()) return; - QWindowSurface::setGeometry(rect); - - TRect nativeRect(qt_QRect2TRect(rect)); - qt_symbian_throwIfError(d_ptr->bitmap->Resize(nativeRect.Size())); - - if (!rect.isNull()) - updatePaintDeviceOnBitmap(); -} - -void QS60WindowSurface::lockBitmapHeap() -{ - if (!QS60WindowSurfacePrivate::lockedSurface) - return; - - // Get some local variables to make later code lines more clear to read - CFbsBitmap*& bitmap = QS60WindowSurfacePrivate::lockedSurface->d_ptr->bitmap; - QImage& device = QS60WindowSurfacePrivate::lockedSurface->d_ptr->device; - uchar*& bytes = QS60WindowSurfacePrivate::lockedSurface->d_ptr->bytes; - - bitmap->LockHeap(); - uchar *newBytes = (uchar*)bitmap->DataAddress(); - if (newBytes != bytes) { - bytes = newBytes; - - // Get some values for QImage creation - TDisplayMode mode = bitmap->DisplayMode(); - if (mode == EColor16MA - && qt_widget_private(QS60WindowSurfacePrivate::lockedSurface->window())->isOpaque) - mode = EColor16MU; - QImage::Format format = qt_TDisplayMode2Format( mode ); - TSize bitmapSize = bitmap->SizeInPixels(); - int bytesPerLine = CFbsBitmap::ScanLineLength( bitmapSize.iWidth, mode); - - device = QImage( bytes, bitmapSize.iWidth, bitmapSize.iHeight, bytesPerLine, format ); - } -} - -void QS60WindowSurface::unlockBitmapHeap() -{ - if (!QS60WindowSurfacePrivate::lockedSurface) - return; - - QS60WindowSurfacePrivate::lockedSurface->d_ptr->bitmap->UnlockHeap(); -} + QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); + data->resize(rect.width(), rect.height()); -void QS60WindowSurface::updatePaintDeviceOnBitmap() -{ - // This forces the actual device to be updated based on CFbsBitmap - beginPaint(QRegion()); - endPaint(QRegion()); + QWindowSurface::setGeometry(rect); } -CFbsBitmap *QS60WindowSurface::symbianBitmap() const +CFbsBitmap* QS60WindowSurface::symbianBitmap() const { - return d_ptr->bitmap; + QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); + return data->cfbsBitmap; } QT_END_NAMESPACE + diff --git a/src/gui/painting/qwindowsurface_s60_p.h b/src/gui/painting/qwindowsurface_s60_p.h index f9b6b60..3c4059f 100644 --- a/src/gui/painting/qwindowsurface_s60_p.h +++ b/src/gui/painting/qwindowsurface_s60_p.h @@ -75,17 +75,13 @@ public: void beginPaint(const QRegion &); void endPaint(const QRegion &); - void setGeometry(const QRect &rect); + QImage* buffer(const QWidget *widget); - static void lockBitmapHeap(); - static void unlockBitmapHeap(); + void setGeometry(const QRect &rect); CFbsBitmap *symbianBitmap() const; private: - void updatePaintDeviceOnBitmap(); - -private: QS60WindowSurfacePrivate* d_ptr; }; |