summaryrefslogtreecommitdiffstats
path: root/src/openvg/qpixmapdata_vg.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2011-03-07 12:45:24 (GMT)
committerLaszlo Agocs <laszlo.p.agocs@nokia.com>2011-03-07 12:45:24 (GMT)
commitcee7a42f5bf6473cecafc2bf98e9b383cb3edede (patch)
treecb9abed47016d03d956e59407eb43bf00dc3cae9 /src/openvg/qpixmapdata_vg.cpp
parentdda11ee48e323f4f4c6490822aa8921d5d6e3e69 (diff)
downloadQt-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.cpp42
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;