diff options
author | Sami Merila <sami.merila@nokia.com> | 2009-12-16 10:21:14 (GMT) |
---|---|---|
committer | Sami Merila <sami.merila@nokia.com> | 2009-12-16 10:21:14 (GMT) |
commit | 989895e84806b88f0b1e0d75ce6dbf6c482357b6 (patch) | |
tree | 95066131a2356d68479d2a4ad9fe719edf49e2fa /src/gui/image/qpixmap_s60.cpp | |
parent | a43868ca114562502618b4e9c3dd096c65c2e192 (diff) | |
parent | 6e527912d719b0448b91eba1d6a99b9cbe58170a (diff) | |
download | Qt-989895e84806b88f0b1e0d75ce6dbf6c482357b6.zip Qt-989895e84806b88f0b1e0d75ce6dbf6c482357b6.tar.gz Qt-989895e84806b88f0b1e0d75ce6dbf6c482357b6.tar.bz2 |
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt-s60-public into 4.6
Diffstat (limited to 'src/gui/image/qpixmap_s60.cpp')
-rw-r--r-- | src/gui/image/qpixmap_s60.cpp | 90 |
1 files changed, 54 insertions, 36 deletions
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 666d608..610317d 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the QtGui of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -73,27 +73,27 @@ const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08, used to lock the global bitmap heap. Only used in S60 v3.1 and S60 v3.2. */ +_LIT(KFBSERVLargeBitmapAccessName,"FbsLargeBitmapAccess"); class QSymbianFbsClient { public: - QSymbianFbsClient() : heapLock(0), heapLocked(false) + QSymbianFbsClient() : heapLocked(false) { - QT_TRAP_THROWING(heapLock = new(ELeave) CFbsBitmap); - heapLock->Create(TSize(0,0), S60->screenDevice()->DisplayMode()); + heapLock.OpenGlobal(KFBSERVLargeBitmapAccessName); } ~QSymbianFbsClient() { - delete heapLock; + heapLock.Close(); } bool lockHeap() { bool wasLocked = heapLocked; - if (heapLock && !heapLocked) { - heapLock->LockHeap(ETrue); + if (heapLock.Handle() && !heapLocked) { + heapLock.Wait(); heapLocked = true; } @@ -104,8 +104,8 @@ public: { bool wasLocked = heapLocked; - if (heapLock && heapLocked) { - heapLock->UnlockHeap(ETrue); + if (heapLock.Handle() && heapLocked) { + heapLock.Signal(); heapLocked = false; } @@ -115,7 +115,7 @@ public: private: - CFbsBitmap *heapLock; + RMutex heapLock; bool heapLocked; }; @@ -169,7 +169,7 @@ public: inline void beginDataAccess(CFbsBitmap *bitmap) { - if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) + if (symbianVersion == QSysInfo::SV_9_2) heapWasLocked = qt_symbianFbsClient()->lockHeap(); else bitmap->LockHeap(ETrue); @@ -177,7 +177,7 @@ public: inline void endDataAccess(CFbsBitmap *bitmap) { - if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) { + if (symbianVersion == QSysInfo::SV_9_2) { if (!heapWasLocked) qt_symbianFbsClient()->unlockHeap(); } else { @@ -311,7 +311,7 @@ QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h) CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const { QPixmapData *data = pixmapData(); - if (data->isNull()) + if (!data || data->isNull()) return 0; return reinterpret_cast<CFbsBitmap*>(data->toNativeType(QPixmapData::FbsBitmap)); @@ -337,8 +337,9 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) if (!bitmap) return QPixmap(); - QPixmap pixmap; - pixmap.pixmapData()->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap); + QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType)); + data->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap); + QPixmap pixmap(data.take()); return pixmap; } @@ -348,7 +349,8 @@ QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type), bitmapDevice(0), bitmapGc(0), pengine(0), - bytes(0) + bytes(0), + formatLocked(false) { } @@ -424,11 +426,12 @@ void QS60PixmapData::release() } /*! - * Takes ownership of bitmap + * Takes ownership of bitmap. Used by window surface */ void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap) { cfbsBitmap = bitmap; + formatLocked = true; if(!initSymbianBitmapContext()) { qWarning("Could not create CBitmapContext"); @@ -442,7 +445,7 @@ void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap) // Create default palette if needed if (cfbsBitmap->DisplayMode() == EGray2) { - image.setNumColors(2); + image.setColorCount(2); image.setColor(0, QColor(Qt::color0).rgba()); image.setColor(1, QColor(Qt::color1).rgba()); @@ -525,13 +528,13 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags const uchar *sptr = const_cast<const QImage &>(sourceImage).bits(); symbianBitmapDataAccess->beginDataAccess(cfbsBitmap); uchar *dptr = (uchar*)cfbsBitmap->DataAddress(); - Mem::Copy(dptr, sptr, sourceImage.numBytes()); + Mem::Copy(dptr, sptr, sourceImage.byteCount()); symbianBitmapDataAccess->endDataAccess(cfbsBitmap); UPDATE_BUFFER(); if (destFormat == QImage::Format_MonoLSB) { - image.setNumColors(2); + image.setColorCount(2); image.setColor(0, QColor(Qt::color0).rgba()); image.setColor(1, QColor(Qt::color1).rgba()); } else { @@ -684,19 +687,20 @@ void QS60PixmapData::beginDataAccess() uchar* newBytes = (uchar*)cfbsBitmap->DataAddress(); - if (newBytes == bytes) - return; + TSize size = cfbsBitmap->SizeInPixels(); + if (newBytes == bytes && image.width() == size.iWidth && image.height() == size.iHeight) + return; bytes = newBytes; TDisplayMode mode = cfbsBitmap->DisplayMode(); QImage::Format format = qt_TDisplayMode2Format(mode); - //on S60 3.1, premultiplied alpha pixels are stored in a bitmap with 16MA type - if (format == QImage::Format_ARGB32) + // On S60 3.1, premultiplied alpha pixels are stored in a bitmap with 16MA type. + // S60 window surface needs backing store pixmap for transparent window in ARGB32 format. + // In that case formatLocked is true. + if (!formatLocked && format == QImage::Format_ARGB32) format = QImage::Format_ARGB32_Premultiplied; // pixel data is actually in premultiplied format - TSize size = cfbsBitmap->SizeInPixels(); - QVector<QRgb> savedColorTable; if (!image.isNull()) savedColorTable = image.colorTable(); @@ -752,9 +756,9 @@ QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage) if (!sgImage) return QPixmap(); - QPixmap pixmap; - pixmap.pixmapData()->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage); - + QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType)); + data->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage); + QPixmap pixmap(data.take()); return pixmap; } @@ -816,7 +820,9 @@ void* QS60PixmapData::toNativeType(NativeType type) if(displayMode == EGray2) { //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid //So invert mono bitmaps so that masks work correctly. + beginDataAccess(); image.invertPixels(); + endDataAccess(); needsCopy = true; } @@ -824,7 +830,9 @@ void* QS60PixmapData::toNativeType(NativeType type) QImage source; if (convertToArgb32) { + beginDataAccess(); source = image.convertToFormat(QImage::Format_ARGB32); + endDataAccess(); displayMode = EColor16MA; } else { source = image; @@ -835,7 +843,7 @@ void* QS60PixmapData::toNativeType(NativeType type) symbianBitmapDataAccess->beginDataAccess(newBitmap); uchar *dptr = (uchar*)newBitmap->DataAddress(); - Mem::Copy(dptr, sptr, source.numBytes()); + Mem::Copy(dptr, sptr, source.byteCount()); symbianBitmapDataAccess->endDataAccess(newBitmap); @@ -854,7 +862,9 @@ void* QS60PixmapData::toNativeType(NativeType type) if(displayMode == EGray2) { // restore pixels + beginDataAccess(); image.invertPixels(); + endDataAccess(); } return reinterpret_cast<void*>(bitmap); @@ -935,18 +945,21 @@ void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType) da.beginDataAccess(sourceBitmap); uchar *bytes = (uchar*)sourceBitmap->DataAddress(); QImage img = QImage(bytes, size.iWidth, size.iHeight, format); + img = img.copy(); da.endDataAccess(sourceBitmap); - fromImage(img, Qt::AutoColor); - - if(deleteSourceBitmap) - delete sourceBitmap; - if(displayMode == EGray2) { //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid //So invert mono bitmaps so that masks work correctly. - image.invertPixels(); + img.invertPixels(); + } else if(displayMode == EColor16M) { + img = img.rgbSwapped(); // EColor16M is BGR } + + fromImage(img, Qt::AutoColor); + + if(deleteSourceBitmap) + delete sourceBitmap; } else { CFbsBitmap* duplicate = 0; QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap); @@ -970,4 +983,9 @@ void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType) } } +QPixmapData *QS60PixmapData::createCompatiblePixmapData() const +{ + return new QS60PixmapData(pixelType()); +} + QT_END_NAMESPACE |