diff options
author | Gunnar Sletta <gunnar@trolltech.com> | 2009-10-19 04:58:20 (GMT) |
---|---|---|
committer | Gunnar Sletta <gunnar@trolltech.com> | 2009-10-19 04:58:20 (GMT) |
commit | 91e133d9eeba0b7ea87a3ddb3f10d2a2b345473d (patch) | |
tree | 499f3a3e0ba67c76da18a33fd331569670578a79 /src/openvg | |
parent | 4a0e3170c779a6a37954c3dfcfd0b9f0ce144701 (diff) | |
parent | c3bab81d5966c9bd3a42d9c5cbb9d8ad35a1b330 (diff) | |
download | Qt-91e133d9eeba0b7ea87a3ddb3f10d2a2b345473d.zip Qt-91e133d9eeba0b7ea87a3ddb3f10d2a2b345473d.tar.gz Qt-91e133d9eeba0b7ea87a3ddb3f10d2a2b345473d.tar.bz2 |
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.cpp | 122 | ||||
-rw-r--r-- | src/openvg/qpaintengine_vg_p.h | 2 | ||||
-rw-r--r-- | src/openvg/qpixmapfilter_vg.cpp | 86 | ||||
-rw-r--r-- | src/openvg/qpixmapfilter_vg_p.h | 5 | ||||
-rw-r--r-- | src/openvg/qwindowsurface_vg.cpp | 2 | ||||
-rw-r--r-- | src/openvg/qwindowsurface_vgegl.cpp | 4 |
6 files changed, 166 insertions, 55 deletions
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index b129164..fdd61ea 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 a3487dc..1202b55 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 613f4ea..3305bbb 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 58111ec..f79b6c2 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 6cc2e27..661e06a 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 3ae911f..d622c1f 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); |