diff options
Diffstat (limited to 'src/openvg')
-rw-r--r-- | src/openvg/qpaintengine_vg.cpp | 28 | ||||
-rw-r--r-- | src/openvg/qpaintengine_vg_p.h | 2 | ||||
-rw-r--r-- | src/openvg/qpixmapdata_vg.cpp | 53 | ||||
-rw-r--r-- | src/openvg/qpixmapdata_vg_p.h | 1 | ||||
-rw-r--r-- | src/openvg/qwindowsurface_vg.cpp | 14 |
5 files changed, 60 insertions, 38 deletions
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 75b7fa5..fda4b10 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -3407,6 +3407,34 @@ void QVGPaintEngine::restoreState(QPaintEngine::DirtyFlags dirty) #endif } +void QVGPaintEngine::fillRegion + (const QRegion& region, const QColor& color, const QSize& surfaceSize) +{ + Q_D(QVGPaintEngine); + if (d->clearColor != color || d->clearOpacity != 1.0f) { + VGfloat values[4]; + values[0] = color.redF(); + values[1] = color.greenF(); + values[2] = color.blueF(); + values[3] = color.alphaF(); + vgSetfv(VG_CLEAR_COLOR, 4, values); + d->clearColor = color; + d->clearOpacity = 1.0f; + } + if (region.rectCount() == 1) { + QRect r = region.boundingRect(); + vgClear(r.x(), surfaceSize.height() - r.y() - r.height(), + r.width(), r.height()); + } else { + const QVector<QRect> rects = region.rects(); + for (int i = 0; i < rects.size(); ++i) { + QRect r = rects.at(i); + vgClear(r.x(), surfaceSize.height() - r.y() - r.height(), + r.width(), r.height()); + } + } +} + #if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QT_NO_EGL) QVGCompositionHelper::QVGCompositionHelper() diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h index 1202b55..86a522a 100644 --- a/src/openvg/qpaintengine_vg_p.h +++ b/src/openvg/qpaintengine_vg_p.h @@ -151,6 +151,8 @@ public: QVGPaintEnginePrivate *vgPrivate() { Q_D(QVGPaintEngine); return d; } + void fillRegion(const QRegion& region, const QColor& color, const QSize& surfaceSize); + protected: QVGPaintEngine(QVGPaintEnginePrivate &data); diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 3254aa3..19c90ed 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -92,7 +92,6 @@ QVGPixmapData::~QVGPixmapData() vgDestroyImage(vgImage); if (vgImageOpacity != VG_INVALID_HANDLE) vgDestroyImage(vgImageOpacity); - } else { #endif } #if !defined(QT_NO_EGL) @@ -202,6 +201,14 @@ QPaintEngine* QVGPixmapData::paintEngine() const return source.paintEngine(); } +// This function works around QImage::bits() making a deep copy if the +// QImage is not const. We force it to be const and then get the bits. +// XXX: Should add a QImage::constBits() in the future to replace this. +static inline const uchar *qt_vg_imageBits(const QImage& image) +{ + return image.bits(); +} + VGImage QVGPixmapData::toVGImage() { if (!isValid()) @@ -213,7 +220,7 @@ VGImage QVGPixmapData::toVGImage() context = qt_vg_create_context(0); #endif - if (recreate) { + if (recreate && prevSize != QSize(w, h)) { if (vgImage != VG_INVALID_HANDLE) { vgDestroyImage(vgImage); vgImage = VG_INVALID_HANDLE; @@ -222,6 +229,8 @@ VGImage QVGPixmapData::toVGImage() vgDestroyImage(vgImageOpacity); vgImageOpacity = VG_INVALID_HANDLE; } + } else if (recreate) { + cachedOpacity = -1.0f; // Force opacity image to be refreshed later. } if (vgImage == VG_INVALID_HANDLE) { @@ -232,11 +241,12 @@ VGImage QVGPixmapData::toVGImage() if (!source.isNull() && recreate) { vgImageSubData (vgImage, - source.bits(), source.bytesPerLine(), + qt_vg_imageBits(source), source.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, w, h); } recreate = false; + prevSize = QSize(w, h); return vgImage; } @@ -244,43 +254,14 @@ VGImage QVGPixmapData::toVGImage() VGImage QVGPixmapData::toVGImage(qreal opacity) { #if !defined(QT_SHIVAVG) - if (!isValid()) + // Force the primary VG image to be recreated if necessary. + if (toVGImage() == VG_INVALID_HANDLE) return VG_INVALID_HANDLE; -#if !defined(QT_NO_EGL) - // Increase the reference count on the shared context. - if (!context) - context = qt_vg_create_context(0); -#endif - - if (recreate) { - if (vgImage != VG_INVALID_HANDLE) { - vgDestroyImage(vgImage); - vgImage = VG_INVALID_HANDLE; - } - if (vgImageOpacity != VG_INVALID_HANDLE) { - vgDestroyImage(vgImageOpacity); - vgImageOpacity = VG_INVALID_HANDLE; - } - } - - if (vgImage == VG_INVALID_HANDLE) { - vgImage = vgCreateImage - (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER); - } - - if (!source.isNull() && recreate) { - vgImageSubData - (vgImage, - source.bits(), source.bytesPerLine(), - VG_sARGB_8888_PRE, 0, 0, w, h); - } - - recreate = false; - if (opacity == 1.0f) return vgImage; + // Create an alternative image for the selected opacity. if (vgImageOpacity == VG_INVALID_HANDLE || cachedOpacity != opacity) { if (vgImageOpacity == VG_INVALID_HANDLE) { vgImageOpacity = vgCreateImage @@ -405,6 +386,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) vgDestroyImage(vgImageOpacity); vgImageOpacity = VG_INVALID_HANDLE; } + prevSize = QSize(); TInt err = 0; @@ -465,6 +447,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) is_null = (w <= 0 || h <= 0); source = QImage(); recreate = false; + prevSize = QSize(w, h); setSerialNumber(++qt_vg_pixmap_serial); // release stuff eglDestroyImageKHR(context->display(), eglImage); diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h index f6fac88..fe19f35 100644 --- a/src/openvg/qpixmapdata_vg_p.h +++ b/src/openvg/qpixmapdata_vg_p.h @@ -109,6 +109,7 @@ protected: #endif protected: + QSize prevSize; VGImage vgImage; VGImage vgImageOpacity; qreal cachedOpacity; diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp index f8486a6..a1301e3 100644 --- a/src/openvg/qwindowsurface_vg.cpp +++ b/src/openvg/qwindowsurface_vg.cpp @@ -48,6 +48,7 @@ #if !defined(QT_NO_EGL) #include <QtGui/private/qegl_p.h> +#include <QtGui/private/qwidget_p.h> QT_BEGIN_NAMESPACE @@ -71,7 +72,6 @@ QVGWindowSurface::~QVGWindowSurface() QPaintDevice *QVGWindowSurface::paintDevice() { - d_ptr->beginPaint(window()); return this; } @@ -94,8 +94,16 @@ bool QVGWindowSurface::scroll(const QRegion &area, int dx, int dy) void QVGWindowSurface::beginPaint(const QRegion ®ion) { - // Nothing to do here. - Q_UNUSED(region); + d_ptr->beginPaint(window()); + + // If the window is not opaque, then fill the region we are about + // to paint with the transparent color. + if (!qt_widget_private(window())->isOpaque && + window()->testAttribute(Qt::WA_TranslucentBackground)) { + QVGPaintEngine *engine = static_cast<QVGPaintEngine *> + (d_ptr->paintEngine()); + engine->fillRegion(region, Qt::transparent, d_ptr->surfaceSize()); + } } void QVGWindowSurface::endPaint(const QRegion ®ion) |