diff options
author | Laszlo Agocs <laszlo.p.agocs@nokia.com> | 2011-03-08 14:59:31 (GMT) |
---|---|---|
committer | Laszlo Agocs <laszlo.p.agocs@nokia.com> | 2011-03-08 14:59:31 (GMT) |
commit | a870c5e10fe83b6b8df254ec760ac50020738aaa (patch) | |
tree | 9db282a0027e5ccf7e79049b6fab1a6faf4c2e64 /src/openvg | |
parent | cb7ce0b2cb0f47e7ef51e7c7f034dda39cc410ad (diff) | |
download | Qt-a870c5e10fe83b6b8df254ec760ac50020738aaa.zip Qt-a870c5e10fe83b6b8df254ec760ac50020738aaa.tar.gz Qt-a870c5e10fe83b6b8df254ec760ac50020738aaa.tar.bz2 |
Added native image handle provider support in pixmaps on openvg.
QNativeImageHandleProvider is a thin interface consisting of get()
and release() functions. Pixmaps constructed with such a provider
will call these functions to acquire and release a native handle,
e.g. a CFbsBitmap or RSgImage pointer in case of Symbian. The behavior
is largely similar to constructing pixmaps via fromSymbianCFbsBitmap
or fromSymbianRSgImage, with the exception of pixmap hibernation:
release() (and subsequently get()) is guaranteed to be called also
in case of hibernation, allowing more fine-grained tracking of
the usage and lifetime of image data.
Task-number: QT-4632
Reviewed-by: Jani Hautakangas
Diffstat (limited to 'src/openvg')
-rw-r--r-- | src/openvg/qpixmapdata_vg.cpp | 37 | ||||
-rw-r--r-- | src/openvg/qpixmapdata_vg_p.h | 11 | ||||
-rw-r--r-- | src/openvg/qvg_symbian.cpp | 45 |
3 files changed, 90 insertions, 3 deletions
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 47de5ab..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,6 +67,10 @@ 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); @@ -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() @@ -120,6 +129,10 @@ void QVGPixmapData::destroyImageAndContext() #else destroyImages(); #endif + } else { +#if defined(Q_OS_SYMBIAN) + releaseNativeImageHandle(); +#endif } #if !defined(QT_NO_EGL) if (context) { @@ -343,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); @@ -427,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(); @@ -505,6 +531,11 @@ void QVGPixmapData::ensureReadback(bool readOnly) const // 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; } } diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h index 80ff1cb..15ff889 100644 --- a/src/openvg/qpixmapdata_vg_p.h +++ b/src/openvg/qpixmapdata_vg_p.h @@ -76,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: @@ -138,6 +140,9 @@ public: #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: @@ -177,6 +182,12 @@ protected: 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; diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp index c6521fd..5eb64bd 100644 --- a/src/openvg/qvg_symbian.cpp +++ b/src/openvg/qvg_symbian.cpp @@ -41,6 +41,7 @@ #include "qpixmapdata_vg_p.h" #include "qvgfontglyphcache_p.h" +#include <QtGui/private/qnativeimagehandleprovider_p.h> #include <private/qt_s60_p.h> #include <fbs.h> @@ -111,6 +112,44 @@ void QVGPixmapData::cleanup() 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(); + } +} + void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) { if (type == QPixmapData::SgImage && pixmap) { @@ -149,6 +188,11 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) source = *img; source.ensureFormat(idealFormat(&source.imageRef(), Qt::AutoColor)); 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(); } } @@ -216,6 +260,7 @@ void* QVGPixmapData::toNativeType(NativeType type) return reinterpret_cast<void*>(sgImage.take()); #endif } else if (type == QPixmapData::FbsBitmap && isValid()) { + ensureReadback(true); if (source.isNull()) { source = QVolatileImage(w, h, sourceFormat()); } |