summaryrefslogtreecommitdiffstats
path: root/src/openvg
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvg')
-rw-r--r--src/openvg/qpaintengine_vg.cpp26
-rw-r--r--src/openvg/qpaintengine_vg_p.h2
-rw-r--r--src/openvg/qpixmapdata_vg.cpp177
-rw-r--r--src/openvg/qpixmapdata_vg_p.h26
-rw-r--r--src/openvg/qvg_symbian.cpp180
-rw-r--r--src/openvg/qvgfontglyphcache_p.h2
-rw-r--r--src/openvg/qvgimagepool.cpp15
-rw-r--r--src/openvg/qwindowsurface_vgegl.cpp5
8 files changed, 284 insertions, 149 deletions
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index 22cbbf5..44dceea 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -2333,6 +2333,7 @@ bool QVGPaintEngine::isDefaultClipRect(const QRect& rect)
void QVGPaintEngine::clipEnabledChanged()
{
#if defined(QVG_SCISSOR_CLIP)
+ vgSeti(VG_MASKING, VG_FALSE); // disable mask fallback
updateScissor();
#else
Q_D(QVGPaintEngine);
@@ -3134,9 +3135,13 @@ void QVGPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF
if (pm.size().width() <= screenSize.width()
&& pm.size().height() <= screenSize.height())
vgpd->failedToAlloc = false;
- }
- drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
+ vgpd->source.beginDataAccess();
+ drawImage(r, vgpd->source.imageRef(), sr, Qt::AutoColor);
+ vgpd->source.endDataAccess(true);
+ } else {
+ drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
+ }
}
void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
@@ -3162,9 +3167,13 @@ void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
if (pm.size().width() <= screenSize.width()
&& pm.size().height() <= screenSize.height())
vgpd->failedToAlloc = false;
- }
- drawImage(pos, *(pd->buffer()));
+ vgpd->source.beginDataAccess();
+ drawImage(pos, vgpd->source.imageRef());
+ vgpd->source.endDataAccess();
+ } else {
+ drawImage(pos, *(pd->buffer()));
+ }
}
void QVGPaintEngine::drawImage
@@ -3172,6 +3181,8 @@ void QVGPaintEngine::drawImage
Qt::ImageConversionFlags flags)
{
Q_D(QVGPaintEngine);
+ if (image.isNull())
+ return;
VGImage vgImg;
if (d->simpleTransform || d->opacity == 1.0f)
vgImg = toVGImageSubRect(image, sr.toRect(), flags);
@@ -3217,6 +3228,8 @@ void QVGPaintEngine::drawImage
void QVGPaintEngine::drawImage(const QPointF &pos, const QImage &image)
{
Q_D(QVGPaintEngine);
+ if (image.isNull())
+ return;
VGImage vgImg;
if (canVgWritePixels(image)) {
// Optimization for straight blits, no blending
@@ -4010,6 +4023,8 @@ VGImageFormat qt_vg_image_to_vg_format(QImage::Format format)
switch (format) {
case QImage::Format_MonoLSB:
return VG_BW_1;
+ case QImage::Format_Indexed8:
+ return VG_sL_8;
case QImage::Format_ARGB32_Premultiplied:
return VG_sARGB_8888_PRE;
case QImage::Format_RGB32:
@@ -4020,7 +4035,8 @@ VGImageFormat qt_vg_image_to_vg_format(QImage::Format format)
return VG_sRGB_565;
case QImage::Format_ARGB4444_Premultiplied:
return VG_sARGB_4444;
- default: break;
+ default:
+ break;
}
return VG_sARGB_8888; // XXX
}
diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h
index 85583cc..1e9103b 100644
--- a/src/openvg/qpaintengine_vg_p.h
+++ b/src/openvg/qpaintengine_vg_p.h
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
-class QFixedPoint;
+struct QFixedPoint;
class QVGPaintEnginePrivate;
class QPixmapData;
class QVGEGLWindowSurfacePrivate;
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp
index 732b484..3f67c79 100644
--- a/src/openvg/qpixmapdata_vg.cpp
+++ b/src/openvg/qpixmapdata_vg.cpp
@@ -50,6 +50,7 @@
#include <QBuffer>
#include <QImageReader>
#include <QtGui/private/qimage_p.h>
+#include <QtGui/private/qnativeimagehandleprovider_p.h>
QT_BEGIN_NAMESPACE
@@ -66,11 +67,15 @@ QVGPixmapData::QVGPixmapData(PixelType type)
inImagePool = false;
inLRU = false;
failedToAlloc = false;
+#if defined(Q_OS_SYMBIAN)
+ nativeImageHandleProvider = 0;
+ nativeImageHandle = 0;
+#endif
#if !defined(QT_NO_EGL)
context = 0;
qt_vg_register_pixmap(this);
#endif
- setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
}
QVGPixmapData::~QVGPixmapData()
@@ -98,6 +103,10 @@ void QVGPixmapData::destroyImages()
vgImage = VG_INVALID_HANDLE;
vgImageOpacity = VG_INVALID_HANDLE;
inImagePool = false;
+
+#if defined(Q_OS_SYMBIAN)
+ releaseNativeImageHandle();
+#endif
}
void QVGPixmapData::destroyImageAndContext()
@@ -105,6 +114,8 @@ void QVGPixmapData::destroyImageAndContext()
if (vgImage != VG_INVALID_HANDLE) {
// We need to have a context current to destroy the image.
#if !defined(QT_NO_EGL)
+ if (!context)
+ context = qt_vg_create_context(0, QInternal::Pixmap);
if (context->isCurrent()) {
destroyImages();
} else {
@@ -118,6 +129,10 @@ void QVGPixmapData::destroyImageAndContext()
#else
destroyImages();
#endif
+ } else {
+#if defined(Q_OS_SYMBIAN)
+ releaseNativeImageHandle();
+#endif
}
#if !defined(QT_NO_EGL)
if (context) {
@@ -138,25 +153,31 @@ bool QVGPixmapData::isValid() const
return (w > 0 && h > 0);
}
+void QVGPixmapData::updateSerial()
+{
+ setSerialNumber(++qt_vg_pixmap_serial);
+}
+
void QVGPixmapData::resize(int wid, int ht)
{
- if (w == wid && h == ht)
+ if (w == wid && h == ht) {
+ updateSerial();
return;
+ }
w = wid;
h = ht;
d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
is_null = (w <= 0 || h <= 0);
- source = QImage();
+ source = QVolatileImage();
recreate = true;
- setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
}
-void QVGPixmapData::fromImage
- (const QImage &image, Qt::ImageConversionFlags flags)
+void QVGPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
{
- if(image.isNull())
+ if (image.isNull())
return;
QImage img = image;
@@ -200,33 +221,34 @@ bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format,
return !isNull();
}
-/*!
- out-of-place conversion (inPlace == false) will always detach()
- */
-void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+QImage::Format QVGPixmapData::idealFormat(QImage *image, Qt::ImageConversionFlags flags) const
{
- if (image.size() == QSize(w, h))
- setSerialNumber(++qt_vg_pixmap_serial);
- else
- resize(image.width(), image.height());
-
QImage::Format format = sourceFormat();
- int d = image.depth();
- if (d == 1 || d == 16 || d == 24 || (d == 32 && !image.hasAlphaChannel()))
+ int d = image->depth();
+ if (d == 1 || d == 16 || d == 24 || (d == 32 && !image->hasAlphaChannel()))
format = QImage::Format_RGB32;
- else if (!(flags & Qt::NoOpaqueDetection) && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())
+ else if (!(flags & Qt::NoOpaqueDetection) && image->data_ptr()->checkForAlphaPixels())
format = sourceFormat();
else
- format = image.hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
+ format = image->hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
+ return format;
+}
+
+void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+{
+ resize(image.width(), image.height());
+
+ QImage::Format format = idealFormat(&image, flags);
if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
- source = image;
+ source = QVolatileImage(image);
} else {
- source = image.convertToFormat(format);
-
- // convertToFormat won't detach the image if format stays the same.
- if (image.format() == format)
- source.detach();
+ QImage convertedImage = image.convertToFormat(format);
+ // convertToFormat won't detach the image if format stays the
+ // same. Detaching is needed to prevent issues with painting
+ // onto this QPixmap later on.
+ convertedImage.detach();
+ source = QVolatileImage(convertedImage);
}
recreate = true;
@@ -236,27 +258,23 @@ void QVGPixmapData::fill(const QColor &color)
{
if (!isValid())
return;
-
- if (source.isNull())
- source = QImage(w, h, sourceFormat());
-
+ forceToImage();
if (source.depth() == 1) {
// Pick the best approximate color in the image's colortable.
int gray = qGray(color.rgba());
- if (qAbs(qGray(source.color(0)) - gray) < qAbs(qGray(source.color(1)) - gray))
+ if (qAbs(qGray(source.imageRef().color(0)) - gray)
+ < qAbs(qGray(source.imageRef().color(1)) - gray))
source.fill(0);
else
source.fill(1);
} else {
source.fill(PREMUL(color.rgba()));
}
-
- // Re-upload the image to VG the next time toVGImage() is called.
- recreate = true;
}
bool QVGPixmapData::hasAlphaChannel() const
{
+ ensureReadback(true);
if (!source.isNull())
return source.hasAlphaChannel();
else
@@ -265,27 +283,52 @@ bool QVGPixmapData::hasAlphaChannel() const
void QVGPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
{
+ if (!isValid())
+ return;
forceToImage();
- source.setAlphaChannel(alphaChannel.toImage());
+ source.setAlphaChannel(alphaChannel);
}
QImage QVGPixmapData::toImage() const
{
if (!isValid())
return QImage();
-
+ ensureReadback(true);
if (source.isNull()) {
- source = QImage(w, h, sourceFormat());
+ source = QVolatileImage(w, h, sourceFormat());
recreate = true;
}
+ return source.toImage();
+}
- return source;
+void QVGPixmapData::copy(const QPixmapData *data, const QRect &rect)
+{
+ // toImage() is potentially expensive with QVolatileImage so provide a
+ // more efficient implementation of copy() that does not rely on it.
+ if (!data) {
+ return;
+ }
+ if (data->classId() != OpenVGClass) {
+ fromImage(data->toImage(rect), Qt::NoOpaqueDetection);
+ return;
+ }
+ const QVGPixmapData *pd = static_cast<const QVGPixmapData *>(data);
+ QRect r = rect;
+ if (r.isNull() || r.contains(QRect(0, 0, pd->w, pd->h))) {
+ r = QRect(0, 0, pd->w, pd->h);
+ }
+ resize(r.width(), r.height());
+ recreate = true;
+ if (!pd->source.isNull()) {
+ source = QVolatileImage(r.width(), r.height(), pd->source.format());
+ source.copyFrom(&pd->source, r);
+ }
}
QImage *QVGPixmapData::buffer()
{
- forceToImage();
- return &source;
+ // Cannot be safely implemented and QVGPixmapData is not (must not be) RasterClass anyway.
+ return 0;
}
QPaintEngine* QVGPixmapData::paintEngine() const
@@ -313,6 +356,12 @@ VGImage QVGPixmapData::toVGImage()
else if (recreate)
cachedOpacity = -1.0f; // Force opacity image to be refreshed later.
+#if defined(Q_OS_SYMBIAN)
+ if (recreate && nativeImageHandleProvider && !nativeImageHandle) {
+ createFromNativeImageHandleProvider();
+ }
+#endif
+
if (vgImage == VG_INVALID_HANDLE) {
vgImage = QVGImagePool::instance()->createImageForPixmap
(qt_vg_image_to_vg_format(source.format()), w, h, VG_IMAGE_QUALITY_FASTER, this);
@@ -329,10 +378,12 @@ VGImage QVGPixmapData::toVGImage()
}
if (!source.isNull() && recreate) {
+ source.beginDataAccess();
vgImageSubData
(vgImage,
source.constBits(), source.bytesPerLine(),
qt_vg_image_to_vg_format(source.format()), 0, 0, w, h);
+ source.endDataAccess(true);
}
recreate = false;
@@ -395,9 +446,16 @@ void QVGPixmapData::detachImageFromPool()
void QVGPixmapData::hibernate()
{
- // If the image was imported (e.g, from an SgImage under Symbian),
- // then we cannot copy it back to main memory for storage.
- if (vgImage != VG_INVALID_HANDLE && source.isNull())
+ // If the image was imported (e.g, from an SgImage under Symbian), then
+ // skip the hibernation, there is no sense in copying it back to main
+ // memory because the data is most likely shared between several processes.
+ bool skipHibernate = (vgImage != VG_INVALID_HANDLE && source.isNull());
+#if defined(Q_OS_SYMBIAN)
+ // However we have to proceed normally if the image was retrieved via
+ // a handle provider.
+ skipHibernate &= !nativeImageHandleProvider;
+#endif
+ if (skipHibernate)
return;
forceToImage();
@@ -442,18 +500,47 @@ int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
}
}
-// Force the pixmap data to be in QImage format.
+// Ensures that the pixmap is backed by some valid data and forces the data to
+// be re-uploaded to the VGImage when toVGImage() is called next time.
void QVGPixmapData::forceToImage()
{
if (!isValid())
return;
+ ensureReadback(false);
+
if (source.isNull())
- source = QImage(w, h, sourceFormat());
+ source = QVolatileImage(w, h, sourceFormat());
recreate = true;
}
+void QVGPixmapData::ensureReadback(bool readOnly) const
+{
+ if (vgImage != VG_INVALID_HANDLE && source.isNull()) {
+ source = QVolatileImage(w, h, sourceFormat());
+ source.beginDataAccess();
+ vgGetImageSubData(vgImage, source.bits(), source.bytesPerLine(),
+ qt_vg_image_to_vg_format(source.format()),
+ 0, 0, w, h);
+ source.endDataAccess();
+ if (readOnly) {
+ recreate = false;
+ } else {
+ // Once we did a readback, the original VGImage must be destroyed
+ // because it may be shared (e.g. created via SgImage) and a subsequent
+ // upload of the image data may produce unexpected results.
+ const_cast<QVGPixmapData *>(this)->destroyImages();
+#if defined(Q_OS_SYMBIAN)
+ // There is now an own copy of the data so drop the handle provider,
+ // otherwise toVGImage() would request the handle again, which is wrong.
+ nativeImageHandleProvider = 0;
+#endif
+ recreate = true;
+ }
+ }
+}
+
QImage::Format QVGPixmapData::sourceFormat() const
{
return QImage::Format_ARGB32_Premultiplied;
diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h
index 58e69db..15ff889 100644
--- a/src/openvg/qpixmapdata_vg_p.h
+++ b/src/openvg/qpixmapdata_vg_p.h
@@ -54,7 +54,8 @@
//
#include <QtGui/private/qpixmap_raster_p.h>
-#include <private/qvg_p.h>
+#include <QtGui/private/qvolatileimage_p.h>
+#include "qvg_p.h"
#if defined(Q_OS_SYMBIAN)
class RSGImage;
@@ -75,6 +76,8 @@ void qt_vg_unregister_pixmap(QVGPixmapData *pd);
void qt_vg_hibernate_pixmaps(QVGSharedContext *context);
#endif
+class QNativeImageHandleProvider;
+
class Q_OPENVG_EXPORT QVGPixmapData : public QPixmapData
{
public:
@@ -99,6 +102,7 @@ public:
bool hasAlphaChannel() const;
void setAlphaChannel(const QPixmap &alphaChannel);
QImage toImage() const;
+ void copy(const QPixmapData *data, const QRect &rect);
QImage *buffer();
QPaintEngine* paintEngine() const;
@@ -124,11 +128,21 @@ public:
// VGImage objects to reuse storage.
virtual void reclaimImages();
+ // If vgImage is valid but source is null, copies pixel data from GPU back
+ // into main memory and destroys vgImage. For a normal pixmap this function
+ // does nothing, however if the pixmap was created directly from a VGImage
+ // (e.g. via SgImage on Symbian) then by doing the readback this ensures
+ // that QImage-based functions can operate too.
+ virtual void ensureReadback(bool readOnly) const;
+
QSize size() const { return QSize(w, h); }
#if defined(Q_OS_SYMBIAN)
void* toNativeType(NativeType type);
void fromNativeType(void* pixmap, NativeType type);
+ bool initFromNativeImageHandle(void *handle, const QString &type);
+ void createFromNativeImageHandleProvider();
+ void releaseNativeImageHandle();
#endif
protected:
@@ -161,15 +175,23 @@ protected:
VGImage vgImage;
VGImage vgImageOpacity;
qreal cachedOpacity;
- mutable QImage source;
+ mutable QVolatileImage source;
mutable bool recreate;
bool inImagePool;
#if !defined(QT_NO_EGL)
mutable QEglContext *context;
#endif
+#if defined(Q_OS_SYMBIAN)
+ mutable QNativeImageHandleProvider *nativeImageHandleProvider;
+ void *nativeImageHandle;
+ QString nativeImageType;
+#endif
+
void forceToImage();
QImage::Format sourceFormat() const;
+ QImage::Format idealFormat(QImage *image, Qt::ImageConversionFlags flags) const;
+ void updateSerial();
void destroyImageAndContext();
void destroyImages();
diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp
index 2ea38c1..0d2ed9e 100644
--- a/src/openvg/qvg_symbian.cpp
+++ b/src/openvg/qvg_symbian.cpp
@@ -41,10 +41,10 @@
#include "qpixmapdata_vg_p.h"
#include "qvgfontglyphcache_p.h"
+#include <QtGui/private/qnativeimagehandleprovider_p.h>
#include <private/qt_s60_p.h>
#include <fbs.h>
-#include <bitdev.h>
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
# include <sgresource/sgimage.h>
@@ -75,33 +75,6 @@ VGImage QVG::vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage)
extern int qt_vg_pixmap_serial;
-static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)
-{
- CFbsBitmap *copy = q_check_ptr(new CFbsBitmap);
- if(!copy)
- return 0;
-
- if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
- delete copy;
- copy = 0;
-
- return 0;
- }
-
- CFbsBitmapDevice* bitmapDevice = 0;
- CFbsBitGc *bitmapGc = 0;
- QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy));
- QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
- bitmapGc->Activate(bitmapDevice);
-
- bitmapGc->BitBlt(TPoint(), bitmap);
-
- delete bitmapGc;
- delete bitmapDevice;
-
- return copy;
-}
-
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
static VGImage sgImageToVGImage(QEglContext *context, const RSgImage &sgImage)
{
@@ -136,7 +109,59 @@ void QVGPixmapData::cleanup()
{
is_null = w = h = 0;
recreate = false;
- source = QImage();
+ source = QVolatileImage();
+}
+
+bool QVGPixmapData::initFromNativeImageHandle(void *handle, const QString &type)
+{
+ if (type == QLatin1String("RSgImage")) {
+ fromNativeType(handle, QPixmapData::SgImage);
+ return true;
+ } else if (type == QLatin1String("CFbsBitmap")) {
+ fromNativeType(handle, QPixmapData::FbsBitmap);
+ return true;
+ }
+ return false;
+}
+
+void QVGPixmapData::createFromNativeImageHandleProvider()
+{
+ void *handle = 0;
+ QString type;
+ nativeImageHandleProvider->get(&handle, &type);
+ if (handle) {
+ if (initFromNativeImageHandle(handle, type)) {
+ nativeImageHandle = handle;
+ nativeImageType = type;
+ } else {
+ qWarning("QVGPixmapData: Unknown native image type '%s'", qPrintable(type));
+ }
+ } else {
+ qWarning("QVGPixmapData: Native handle is null");
+ }
+}
+
+void QVGPixmapData::releaseNativeImageHandle()
+{
+ if (nativeImageHandleProvider && nativeImageHandle) {
+ nativeImageHandleProvider->release(nativeImageHandle, nativeImageType);
+ nativeImageHandle = 0;
+ nativeImageType = QString();
+ }
+}
+
+static inline bool conversionLessFormat(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_RGB16: // EColor64K
+ case QImage::Format_RGB32: // EColor16MU
+ case QImage::Format_ARGB32: // EColor16MA
+ case QImage::Format_ARGB32_Premultiplied: // EColor16MAP
+ case QImage::Format_Indexed8: // EGray256, EColor256
+ return true;
+ default:
+ return false;
+ }
}
void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
@@ -155,55 +180,37 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
}
is_null = (w <= 0 || h <= 0);
- source = QImage(); // vgGetImageSubData() some day?
+ source = QVolatileImage(); // readback will be done later, only when needed
recreate = false;
prevSize = QSize(w, h);
- //setSerialNumber(++qt_vg_pixmap_serial);
+ updateSerial();
#endif
- } else if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
-
- bool deleteSourceBitmap = false;
-#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
-
- // Rasterize extended bitmaps
-
- TUid extendedBitmapType = bitmap->ExtendedBitmapType();
- if (extendedBitmapType != KNullUid) {
- bitmap = createBlitCopy(bitmap);
- deleteSourceBitmap = true;
+ } else if (type == QPixmapData::FbsBitmap && pixmap) {
+ CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
+ QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
+ resize(size.width(), size.height());
+ source = QVolatileImage(bitmap); // duplicates only, if possible
+ if (source.isNull())
+ return;
+ if (!conversionLessFormat(source.format())) {
+ // Here we may need to copy if the formats do not match.
+ // (e.g. for display modes other than EColor16MAP and EColor16MU)
+ source.beginDataAccess();
+ QImage::Format format = idealFormat(&source.imageRef(), Qt::AutoColor);
+ source.endDataAccess(true);
+ source.ensureFormat(format);
}
-#endif
-
- if (bitmap->IsCompressedInRAM()) {
- bitmap = createBlitCopy(bitmap);
- deleteSourceBitmap = true;
- }
-
- TDisplayMode displayMode = bitmap->DisplayMode();
- QImage::Format format = qt_TDisplayMode2Format(displayMode);
-
- TSize size = bitmap->SizeInPixels();
- int bytesPerLine = bitmap->ScanLineLength(size.iWidth, displayMode);
-
- bitmap->BeginDataAccess();
- uchar *bytes = (uchar*)bitmap->DataAddress();
- QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format);
- img = img.copy();
- bitmap->EndDataAccess();
-
- 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.
- img.invertPixels();
- } else if(displayMode == EColor16M) {
- img = img.rgbSwapped(); // EColor16M is BGR
- }
-
- fromImage(img, Qt::AutoColor);
-
- if(deleteSourceBitmap)
- delete bitmap;
+ recreate = true;
+ } else if (type == QPixmapData::VolatileImage && pixmap) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
+ resize(img->width(), img->height());
+ source = *img;
+ recreate = true;
+ } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
+ destroyImages();
+ nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
+ // Cannot defer the retrieval, we need at least the size right away.
+ createFromNativeImageHandleProvider();
}
}
@@ -270,26 +277,13 @@ void* QVGPixmapData::toNativeType(NativeType type)
driver.Close();
return reinterpret_cast<void*>(sgImage.take());
#endif
- } else if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
-
- if (bitmap) {
- if (bitmap->Create(TSize(source.width(), source.height()),
- EColor16MAP) == KErrNone) {
- const uchar *sptr = const_cast<const QImage&>(source).bits();
- bitmap->BeginDataAccess();
-
- uchar *dptr = (uchar*)bitmap->DataAddress();
- Mem::Copy(dptr, sptr, source.byteCount());
-
- bitmap->EndDataAccess();
- } else {
- delete bitmap;
- bitmap = 0;
- }
+ } else if (type == QPixmapData::FbsBitmap && isValid()) {
+ ensureReadback(true);
+ if (source.isNull()) {
+ source = QVolatileImage(w, h, sourceFormat());
}
-
- return reinterpret_cast<void*>(bitmap);
+ // Just duplicate the bitmap handle, no data copying happens.
+ return source.duplicateNativeImage();
}
return 0;
}
diff --git a/src/openvg/qvgfontglyphcache_p.h b/src/openvg/qvgfontglyphcache_p.h
index 9a105ec..ce12301 100644
--- a/src/openvg/qvgfontglyphcache_p.h
+++ b/src/openvg/qvgfontglyphcache_p.h
@@ -56,7 +56,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtGui/private/qfontengine_p.h>
-#include <qvg_p.h>
+#include "qvg_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/openvg/qvgimagepool.cpp b/src/openvg/qvgimagepool.cpp
index a2b1c4e..7a7ec78 100644
--- a/src/openvg/qvgimagepool.cpp
+++ b/src/openvg/qvgimagepool.cpp
@@ -175,8 +175,19 @@ bool QVGImagePool::reclaimSpace(VGImageFormat format,
void QVGImagePool::hibernate()
{
- // Nothing to do here at the moment since the pool does not
- // retain VGImage's after they have been released.
+ Q_D(QVGImagePool);
+ QVGPixmapData *pd = d->lruLast;
+ while (pd) {
+ QVGPixmapData *prevLRU = pd->prevLRU;
+ pd->inImagePool = false;
+ pd->inLRU = false;
+ pd->nextLRU = 0;
+ pd->prevLRU = 0;
+ pd->hibernate();
+ pd = prevLRU;
+ }
+ d->lruFirst = 0;
+ d->lruLast = 0;
}
void QVGImagePool::moveToHeadOfLRU(QVGPixmapData *data)
diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp
index ca80886..866453f 100644
--- a/src/openvg/qwindowsurface_vgegl.cpp
+++ b/src/openvg/qwindowsurface_vgegl.cpp
@@ -768,6 +768,11 @@ bool QVGEGLWindowSurfaceDirect::scroll(QWidget *widget, const QRegion& area, int
context->lazyDoneCurrent();
return true;
}
+#else
+ Q_UNUSED(widget);
+ Q_UNUSED(area);
+ Q_UNUSED(dx);
+ Q_UNUSED(dy);
#endif
return false;
}