summaryrefslogtreecommitdiffstats
path: root/src/openvg
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvg')
-rw-r--r--src/openvg/qpixmapdata_vg.cpp42
-rw-r--r--src/openvg/qpixmapdata_vg_p.h9
-rw-r--r--src/openvg/qvg_symbian.cpp2
3 files changed, 41 insertions, 12 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;
diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h
index c4fd47f..80ff1cb 100644
--- a/src/openvg/qpixmapdata_vg_p.h
+++ b/src/openvg/qpixmapdata_vg_p.h
@@ -55,7 +55,7 @@
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/private/qvolatileimage_p.h>
-#include <private/qvg_p.h>
+#include "qvg_p.h"
#if defined(Q_OS_SYMBIAN)
class RSGImage;
@@ -126,6 +126,13 @@ 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)
diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp
index 22cbb3c..c6521fd 100644
--- a/src/openvg/qvg_symbian.cpp
+++ b/src/openvg/qvg_symbian.cpp
@@ -127,7 +127,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
}
is_null = (w <= 0 || h <= 0);
- source = QVolatileImage(); // vgGetImageSubData() some day?
+ source = QVolatileImage(); // readback will be done later, only when needed
recreate = false;
prevSize = QSize(w, h);
updateSerial();