summaryrefslogtreecommitdiffstats
path: root/src/openvg
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@trolltech.com>2009-10-19 06:58:20 +0200
committerGunnar Sletta <gunnar@trolltech.com>2009-10-19 06:58:20 +0200
commit91e133d9eeba0b7ea87a3ddb3f10d2a2b345473d (patch)
tree499f3a3e0ba67c76da18a33fd331569670578a79 /src/openvg
parent4a0e3170c779a6a37954c3dfcfd0b9f0ce144701 (diff)
parentc3bab81d5966c9bd3a42d9c5cbb9d8ad35a1b330 (diff)
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt into 4.6
Diffstat (limited to 'src/openvg')
-rw-r--r--src/openvg/qpaintengine_vg.cpp122
-rw-r--r--src/openvg/qpaintengine_vg_p.h2
-rw-r--r--src/openvg/qpixmapfilter_vg.cpp86
-rw-r--r--src/openvg/qpixmapfilter_vg_p.h5
-rw-r--r--src/openvg/qwindowsurface_vg.cpp2
-rw-r--r--src/openvg/qwindowsurface_vgegl.cpp4
6 files changed, 166 insertions, 55 deletions
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index b129164954..fdd61ea812 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -1554,6 +1554,10 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
QRectF rect(points[0], points[1], points[2] - points[0],
points[5] - points[1]);
clip(rect.toRect(), op);
+ } else {
+ // The best we can do is clip to the bounding rectangle
+ // of all control points.
+ clip(path.controlPointRect().toRect(), op);
}
}
@@ -2949,6 +2953,121 @@ void QVGPaintEngine::drawTiledPixmap
fillRect(r, brush);
}
+// Best performance will be achieved with QDrawPixmaps::OpaqueHint
+// (i.e. no opacity), no rotation or scaling, and drawing the full
+// pixmap rather than parts of the pixmap. Even having just one of
+// these conditions will improve performance.
+void QVGPaintEngine::drawPixmaps
+ (const QDrawPixmaps::Data *drawingData, int dataCount,
+ const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints)
+{
+#if !defined(QT_SHIVAVG)
+ Q_D(QVGPaintEngine);
+
+ // If the pixmap is not VG, or the transformation is projective,
+ // then fall back to the default implementation.
+ QPixmapData *pd = pixmap.pixmapData();
+ if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
+ QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+ return;
+ }
+
+ // Bail out if nothing to do.
+ if (dataCount <= 0)
+ return;
+
+ // Bail out if we don't have a usable VGImage for the pixmap.
+ QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
+ if (!vgpd->isValid())
+ return;
+ VGImage vgImg = vgpd->toVGImage();
+ if (vgImg == VG_INVALID_HANDLE)
+ return;
+
+ // We cache the results of any vgChildImage() calls because the
+ // same child is very likely to be used over and over in particle
+ // systems. However, performance is even better if vgChildImage()
+ // isn't needed at all, so use full source rects where possible.
+ QVarLengthArray<VGImage> cachedImages;
+ QVarLengthArray<QRect> cachedSources;
+
+ // Select the opacity paint object.
+ if ((hints & QDrawPixmaps::OpaqueHint) != 0 && d->opacity == 1.0f) {
+ d->setImageMode(VG_DRAW_IMAGE_NORMAL);
+ } else {
+ hints = 0;
+ if (d->fillPaint != d->opacityPaint) {
+ vgSetPaint(d->opacityPaint, VG_FILL_PATH);
+ d->fillPaint = d->opacityPaint;
+ }
+ }
+
+ for (int i = 0; i < dataCount; ++i) {
+ QTransform transform(d->imageTransform);
+ transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
+ transform.rotate(drawingData[i].rotation);
+
+ VGImage child;
+ QSize imageSize = vgpd->size();
+ QRectF sr = drawingData[i].source;
+ if (sr.topLeft().isNull() && sr.size() == imageSize) {
+ child = vgImg;
+ } else {
+ // Look for a previous child with the same source rectangle
+ // to avoid constantly calling vgChildImage()/vgDestroyImage().
+ QRect src = sr.toRect();
+ int j;
+ for (j = 0; j < cachedSources.size(); ++j) {
+ if (cachedSources[j] == src)
+ break;
+ }
+ if (j < cachedSources.size()) {
+ child = cachedImages[j];
+ } else {
+ child = vgChildImage
+ (vgImg, src.x(), src.y(), src.width(), src.height());
+ cachedImages.append(child);
+ cachedSources.append(src);
+ }
+ }
+
+ VGfloat scaleX = drawingData[i].scaleX;
+ VGfloat scaleY = drawingData[i].scaleY;
+ transform.translate(-0.5 * scaleX * sr.width(),
+ -0.5 * scaleY * sr.height());
+ transform.scale(scaleX, scaleY);
+ d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
+
+ if ((hints & QDrawPixmaps::OpaqueHint) == 0) {
+ qreal opacity = d->opacity * drawingData[i].opacity;
+ if (opacity != 1.0f) {
+ if (d->paintOpacity != opacity) {
+ VGfloat values[4];
+ values[0] = 1.0f;
+ values[1] = 1.0f;
+ values[2] = 1.0f;
+ values[3] = opacity;
+ d->paintOpacity = opacity;
+ vgSetParameterfv
+ (d->opacityPaint, VG_PAINT_COLOR, 4, values);
+ }
+ d->setImageMode(VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ d->setImageMode(VG_DRAW_IMAGE_NORMAL);
+ }
+ }
+
+ vgDrawImage(child);
+ }
+
+ // Destroy the cached child sub-images.
+ for (int i = 0; i < cachedImages.size(); ++i)
+ vgDestroyImage(cachedImages[i]);
+#else
+ QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+#endif
+}
+
QVGFontEngineCleaner::QVGFontEngineCleaner(QVGPaintEnginePrivate *d)
: QObject(), d_ptr(d)
{
@@ -3209,9 +3328,6 @@ QPixmapFilter *QVGPaintEngine::pixmapFilter(int type, const QPixmapFilter *proto
d->convolutionFilter.reset(new QVGPixmapConvolutionFilter);
return d->convolutionFilter.data();
case QPixmapFilter::ColorizeFilter:
- // Strength parameter does not work with current implementation.
- if ((static_cast<const QPixmapColorizeFilter *>(prototype))->strength() != 1.0f)
- break;
if (!d->colorizeFilter)
d->colorizeFilter.reset(new QVGPixmapColorizeFilter);
return d->colorizeFilter.data();
diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h
index a3487dcc13..1202b55d43 100644
--- a/src/openvg/qpaintengine_vg_p.h
+++ b/src/openvg/qpaintengine_vg_p.h
@@ -136,6 +136,8 @@ public:
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+ void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints);
+
void drawTextItem(const QPointF &p, const QTextItem &textItem);
void setState(QPainterState *s);
diff --git a/src/openvg/qpixmapfilter_vg.cpp b/src/openvg/qpixmapfilter_vg.cpp
index 613f4eaf0b..3305bbb695 100644
--- a/src/openvg/qpixmapfilter_vg.cpp
+++ b/src/openvg/qpixmapfilter_vg.cpp
@@ -123,8 +123,7 @@ void QVGPixmapConvolutionFilter::draw
}
QVGPixmapColorizeFilter::QVGPixmapColorizeFilter()
- : QPixmapColorizeFilter(),
- firstTime(true)
+ : QPixmapColorizeFilter()
{
}
@@ -136,7 +135,7 @@ void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const
{
if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
// The pixmap data is not an instance of QVGPixmapData, so fall
- // back to the default convolution filter implementation.
+ // back to the default colorize filter implementation.
QPixmapColorizeFilter::draw(painter, dest, src, srcRect);
return;
}
@@ -154,50 +153,45 @@ void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const
if (dstImage == VG_INVALID_HANDLE)
return;
- // Recompute the color matrix if the color has changed.
+ // Determine the weights for the matrix from the color and strength.
QColor c = color();
- if (c != prevColor || firstTime) {
- prevColor = c;
-
- // Determine the weights for the matrix from the color.
- VGfloat weights[3];
- VGfloat invweights[3];
- VGfloat alpha = c.alphaF();
- weights[0] = c.redF() * alpha;
- weights[1] = c.greenF() * alpha;
- weights[2] = c.blueF() * alpha;
- invweights[0] = 1.0f - weights[0];
- invweights[1] = 1.0f - weights[1];
- invweights[2] = 1.0f - weights[2];
-
- // Grayscale weights.
- static const VGfloat redGray = 11.0f / 32.0f;
- static const VGfloat greenGray = 16.0f / 32.0f;
- static const VGfloat blueGray = 1.0f - (redGray + greenGray);
-
- matrix[0][0] = redGray * invweights[0];
- matrix[0][1] = redGray * invweights[1];
- matrix[0][2] = redGray * invweights[2];
- matrix[0][3] = 0.0f;
- matrix[1][0] = greenGray * invweights[0];
- matrix[1][1] = greenGray * invweights[1];
- matrix[1][2] = greenGray * invweights[2];
- matrix[1][3] = 0.0f;
- matrix[2][0] = blueGray * invweights[0];
- matrix[2][1] = blueGray * invweights[1];
- matrix[2][2] = blueGray * invweights[2];
- matrix[2][3] = 0.0f;
- matrix[3][0] = 0.0f;
- matrix[3][1] = 0.0f;
- matrix[3][2] = 0.0f;
- matrix[3][3] = 1.0f;
- matrix[4][0] = weights[0];
- matrix[4][1] = weights[1];
- matrix[4][2] = weights[2];
- matrix[4][3] = 0.0f;
- }
-
- firstTime = false;
+ VGfloat strength = this->strength();
+ VGfloat weights[3];
+ VGfloat invweights[3];
+ VGfloat alpha = c.alphaF();
+ weights[0] = c.redF() * alpha;
+ weights[1] = c.greenF() * alpha;
+ weights[2] = c.blueF() * alpha;
+ invweights[0] = (1.0f - weights[0]) * strength;
+ invweights[1] = (1.0f - weights[1]) * strength;
+ invweights[2] = (1.0f - weights[2]) * strength;
+
+ // Grayscale weights.
+ static const VGfloat redGray = 11.0f / 32.0f;
+ static const VGfloat greenGray = 16.0f / 32.0f;
+ static const VGfloat blueGray = 1.0f - (redGray + greenGray);
+
+ VGfloat matrix[5][4];
+ matrix[0][0] = redGray * invweights[0] + (1.0f - strength);
+ matrix[0][1] = redGray * invweights[1];
+ matrix[0][2] = redGray * invweights[2];
+ matrix[0][3] = 0.0f;
+ matrix[1][0] = greenGray * invweights[0];
+ matrix[1][1] = greenGray * invweights[1] + (1.0f - strength);
+ matrix[1][2] = greenGray * invweights[2];
+ matrix[1][3] = 0.0f;
+ matrix[2][0] = blueGray * invweights[0];
+ matrix[2][1] = blueGray * invweights[1];
+ matrix[2][2] = blueGray * invweights[2] + (1.0f - strength);
+ matrix[2][3] = 0.0f;
+ matrix[3][0] = 0.0f;
+ matrix[3][1] = 0.0f;
+ matrix[3][2] = 0.0f;
+ matrix[3][3] = 1.0f;
+ matrix[4][0] = weights[0] * strength;
+ matrix[4][1] = weights[1] * strength;
+ matrix[4][2] = weights[2] * strength;
+ matrix[4][3] = 0.0f;
vgColorMatrix(dstImage, srcImage, matrix[0]);
diff --git a/src/openvg/qpixmapfilter_vg_p.h b/src/openvg/qpixmapfilter_vg_p.h
index 58111ec2f8..f79b6c2cd3 100644
--- a/src/openvg/qpixmapfilter_vg_p.h
+++ b/src/openvg/qpixmapfilter_vg_p.h
@@ -79,11 +79,6 @@ public:
~QVGPixmapColorizeFilter();
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const;
-
-private:
- mutable VGfloat matrix[5][4];
- mutable QColor prevColor;
- mutable bool firstTime;
};
class Q_OPENVG_EXPORT QVGPixmapDropShadowFilter : public QPixmapDropShadowFilter
diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp
index 6cc2e273fa..661e06acca 100644
--- a/src/openvg/qwindowsurface_vg.cpp
+++ b/src/openvg/qwindowsurface_vg.cpp
@@ -111,7 +111,7 @@ QPaintEngine *QVGWindowSurface::paintEngine() const
int QVGWindowSurface::metric(PaintDeviceMetric met) const
{
- return window()->metric(met);
+ return qt_paint_device_metric(window(), met);
}
QT_END_NAMESPACE
diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp
index 3ae911fe84..d622c1fca5 100644
--- a/src/openvg/qwindowsurface_vgegl.cpp
+++ b/src/openvg/qwindowsurface_vgegl.cpp
@@ -211,6 +211,10 @@ static QEglContext *createContext(QPaintDevice *device)
int redSize = configProps.value(EGL_RED_SIZE);
if (redSize == EGL_DONT_CARE || redSize == 0)
configProps.setPixelFormat(QImage::Format_ARGB32); // XXX
+#ifndef QVG_SCISSOR_CLIP
+ // If we are using the mask to clip, then explicitly request a mask.
+ configProps.setValue(EGL_ALPHA_MASK_SIZE, 1);
+#endif
#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT |
EGL_VG_ALPHA_FORMAT_PRE_BIT);