diff options
author | Laszlo Agocs <laszlo.p.agocs@nokia.com> | 2011-03-07 12:45:24 (GMT) |
---|---|---|
committer | Laszlo Agocs <laszlo.p.agocs@nokia.com> | 2011-03-07 12:45:24 (GMT) |
commit | cee7a42f5bf6473cecafc2bf98e9b383cb3edede (patch) | |
tree | cb9abed47016d03d956e59407eb43bf00dc3cae9 /src/openvg/qpixmapdata_vg.cpp | |
parent | dda11ee48e323f4f4c6490822aa8921d5d6e3e69 (diff) | |
download | Qt-cee7a42f5bf6473cecafc2bf98e9b383cb3edede.zip Qt-cee7a42f5bf6473cecafc2bf98e9b383cb3edede.tar.gz Qt-cee7a42f5bf6473cecafc2bf98e9b383cb3edede.tar.bz2 |
VGImage readback support in QPixmap on OpenVG.
Enable readback of pixel data for pixmaps that are constructed directly
from a VGImage. These do not have any backing data in main memory
(i.e. 'source' is null), however certain operations, like toImage(),
fill(), or painting into the pixmap do not work without it. With this
patch the data is read back via vgGetImageSubData when needed.
Task-number: QT-4669
Reviewed-by: Jani Hautakangas
Diffstat (limited to 'src/openvg/qpixmapdata_vg.cpp')
-rw-r--r-- | src/openvg/qpixmapdata_vg.cpp | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index c5da115..47de5ab 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -105,6 +105,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 { @@ -243,10 +245,7 @@ void QVGPixmapData::fill(const QColor &color) { if (!isValid()) return; - - if (source.isNull()) - source = QVolatileImage(w, h, sourceFormat()); - + forceToImage(); if (source.depth() == 1) { // Pick the best approximate color in the image's colortable. int gray = qGray(color.rgba()); @@ -258,13 +257,11 @@ void QVGPixmapData::fill(const QColor &color) } 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 @@ -273,6 +270,8 @@ bool QVGPixmapData::hasAlphaChannel() const void QVGPixmapData::setAlphaChannel(const QPixmap &alphaChannel) { + if (!isValid()) + return; forceToImage(); source.setAlphaChannel(alphaChannel); } @@ -281,12 +280,11 @@ QImage QVGPixmapData::toImage() const { if (!isValid()) return QImage(); - + ensureReadback(true); if (source.isNull()) { source = QVolatileImage(w, h, sourceFormat()); recreate = true; } - return source.toImage(); } @@ -476,18 +474,42 @@ int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const } } -// Force the pixmap data to be backed by some valid data. +// 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 = 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(); + recreate = true; + } + } +} + QImage::Format QVGPixmapData::sourceFormat() const { return QImage::Format_ARGB32_Premultiplied; |