Index: trunk/src/openvg/openvg.pro
===================================================================
--- trunk/src/openvg/openvg.pro	(revision 769)
+++ trunk/src/openvg/openvg.pro	(revision 846)
@@ -18,5 +18,6 @@
     qpixmapfilter_vg_p.h \
     qvgcompositionhelper_p.h \
-    qvgimagepool_p.h
+    qvgimagepool_p.h \
+    qvgfontglyphcache_p.h
 SOURCES += \
     qpaintengine_vg.cpp \
@@ -34,5 +35,9 @@
 }
 
-symbian: DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING
+symbian {
+    DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING QVG_SCISSOR_CLIP
+    SOURCES += \
+        qvg_symbian.cpp
+}
 
 include(../qbase.pri)
Index: trunk/src/openvg/qpaintengine_vg.cpp
===================================================================
--- trunk/src/openvg/qpaintengine_vg.cpp	(revision 769)
+++ trunk/src/openvg/qpaintengine_vg.cpp	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -45,23 +45,22 @@
 #include "qvgcompositionhelper_p.h"
 #include "qvgimagepool_p.h"
+#include "qvgfontglyphcache_p.h"
 #if !defined(QT_NO_EGL)
-#include <QtGui/private/qegl_p.h>
+#include <QtGui/private/qeglcontext_p.h>
 #include "qwindowsurface_vgegl_p.h"
 #endif
 #include <QtCore/qvarlengtharray.h>
 #include <QtGui/private/qdrawhelper_p.h>
-#include <QtGui/private/qtextureglyphcache_p.h>
 #include <QtGui/private/qtextengine_p.h>
 #include <QtGui/private/qfontengine_p.h>
 #include <QtGui/private/qpainterpath_p.h>
+#include <QtGui/private/qstatictext_p.h>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtCore/qmath.h>
 #include <QDebug>
 #include <QSet>
 
 QT_BEGIN_NAMESPACE
-
-// vgDrawGlyphs() only exists in OpenVG 1.1 and higher.
-#if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_DRAW_GLYPHS)
-#define QVG_NO_DRAW_GLYPHS 1
-#endif
 
 // vgRenderToMask() only exists in OpenVG 1.1 and higher.
@@ -74,4 +73,7 @@
 #endif
 
+// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
+static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
+
 #if !defined(QVG_NO_DRAW_GLYPHS)
 
@@ -80,23 +82,4 @@
 
 class QVGPaintEnginePrivate;
-
-class QVGFontGlyphCache
-{
-public:
-    QVGFontGlyphCache();
-    ~QVGFontGlyphCache();
-
-    void cacheGlyphs(QVGPaintEnginePrivate *d,
-                     const QTextItemInt &ti,
-                     const QVarLengthArray<glyph_t> &glyphs);
-    void setScaleFromText(const QTextItemInt &ti);
-
-    VGFont font;
-    VGfloat scaleX;
-    VGfloat scaleY;
-    
-    uint cachedGlyphsMask[256 / 32];
-    QSet<glyph_t> cachedGlyphs;
-};
 
 typedef QHash<QFontEngine*, QVGFontGlyphCache*> QVGFontCache;
@@ -120,4 +103,5 @@
 class QVGPaintEnginePrivate : public QPaintEngineExPrivate
 {
+    Q_DECLARE_PUBLIC(QVGPaintEngine)
 public:
     // Extra blending modes from VG_KHR_advanced_blending extension.
@@ -150,5 +134,5 @@
     };
 
-    QVGPaintEnginePrivate();
+    QVGPaintEnginePrivate(QVGPaintEngine *q_ptr);
     ~QVGPaintEnginePrivate();
 
@@ -171,4 +155,5 @@
     void setupColorRamp(const QGradient *grad, VGPaint paint);
     void setImageOptions();
+    void systemStateChanged();
 #if !defined(QVG_SCISSOR_CLIP)
     void ensureMask(QVGPaintEngine *engine, int width, int height);
@@ -259,5 +244,9 @@
     {
         if (!pathTransformSet) {
-            setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, pathTransform);
+            QTransform aliasedTransform = pathTransform;
+            if (renderingQuality == VG_RENDERING_QUALITY_NONANTIALIASED && currentPen != Qt::NoPen)
+                aliasedTransform = aliasedTransform
+                    * QTransform::fromTranslate(aliasedCoordinateDelta, -aliasedCoordinateDelta);
+            setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, aliasedTransform);
             pathTransformSet = true;
         }
@@ -299,4 +288,7 @@
     // Clear all lazily-set modes.
     void clearModes();
+
+private:
+    QVGPaintEngine *q;
 };
 
@@ -314,4 +306,5 @@
         vgSeti(VG_RENDERING_QUALITY, mode);
         renderingQuality = mode;
+        pathTransformSet = false; // need to tweak transform for aliased stroking
     }
 }
@@ -350,5 +343,5 @@
 }
 
-QVGPaintEnginePrivate::QVGPaintEnginePrivate()
+QVGPaintEnginePrivate::QVGPaintEnginePrivate(QVGPaintEngine *q_ptr) : q(q_ptr)
 {
     init();
@@ -968,5 +961,5 @@
         x1, y2 - yRadius,
         x1, y1 + yRadius,                   // LineTo
-        x1, y1 + KAPPA * yRadius,           // CurveTo
+        x1, y1 + (1 - KAPPA) * yRadius,     // CurveTo
         x1 + (1 - KAPPA) * xRadius, y1,
         x1 + xRadius, y1
@@ -1015,5 +1008,5 @@
     int width = sourceImage.width();
     for (int y=0; y<height; ++y) {
-        uchar *source = sourceImage.scanLine(y);
+        const uchar *source = sourceImage.constScanLine(y);
         QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y));
         for (int x=0; x < width; ++x)
@@ -1022,7 +1015,4 @@
     return dest;
 }
-
-// defined in qpixmapdata_vg.cpp.
-const uchar *qt_vg_imageBits(const QImage& image);
 
 static VGImage toVGImage
@@ -1059,5 +1049,5 @@
     }
 
-    const uchar *pixels = qt_vg_imageBits(img);
+    const uchar *pixels = img.constBits();
 
     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
@@ -1103,5 +1093,5 @@
     }
 
-    const uchar *pixels = qt_vg_imageBits(img) + bpp * sr.x() +
+    const uchar *pixels = img.constBits() + bpp * sr.x() +
                           img.bytesPerLine() * sr.y();
 
@@ -1125,5 +1115,5 @@
     painter.end();
 
-    const uchar *pixels = qt_vg_imageBits(img);
+    const uchar *pixels = img.constBits();
 
     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
@@ -1147,5 +1137,5 @@
     painter.end();
 
-    const uchar *pixels = qt_vg_imageBits(img);
+    const uchar *pixels = img.constBits();
 
     VGImage vgImg = QVGImagePool::instance()->createPermanentImage
@@ -1452,5 +1442,5 @@
 
 QVGPaintEngine::QVGPaintEngine()
-    : QPaintEngineEx(*new QVGPaintEnginePrivate)
+    : QPaintEngineEx(*new QVGPaintEnginePrivate(this))
 {
 }
@@ -1513,5 +1503,8 @@
     ensureBrush(brush);
     setFillRule(rule);
+    QPen savedPen = currentPen;
+    currentPen = Qt::NoPen;
     ensurePathTransform();
+    currentPen = savedPen;
     vgDrawPath(path, VG_FILL_PATH);
 }
@@ -1627,9 +1620,49 @@
                     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);
-    }
+        return;
+    }
+
+    // Try converting the path into a QRegion that tightly follows
+    // the outline of the path we want to clip with.
+    QRegion region;
+    if (!path.isEmpty())
+        region = QRegion(path.convertToPainterPath().toFillPolygon(QTransform()).toPolygon());
+
+    switch (op) {
+        case Qt::NoClip:
+        {
+            region = defaultClipRegion();
+        }
+        break;
+
+        case Qt::ReplaceClip:
+        {
+            region = d->transform.map(region);
+        }
+        break;
+
+        case Qt::IntersectClip:
+        {
+            region = s->clipRegion.intersect(d->transform.map(region));
+        }
+        break;
+
+        case Qt::UniteClip:
+        {
+            region = s->clipRegion.unite(d->transform.map(region));
+        }
+        break;
+    }
+    if (region.numRects() <= d->maxScissorRects) {
+        // We haven't reached the maximum scissor count yet, so we can
+        // still make use of this region.
+        s->clipRegion = region;
+        updateScissor();
+        return;
+    }
+
+    // The best we can do is clip to the bounding rectangle
+    // of all control points.
+    clip(path.controlPointRect().toRect(), op);
 }
 
@@ -2169,4 +2202,10 @@
     // Using the scissor to do clipping, so combine the systemClip
     // with the current painting clipRegion.
+
+    if (d->maskValid) {
+        vgSeti(VG_MASKING, VG_FALSE);
+        d->maskValid = false;
+    }
+
     QVGPainterState *s = state();
     if (s->clipEnabled) {
@@ -2218,6 +2257,31 @@
     QVector<QRect> rects = region.rects();
     int count = rects.count();
-    if (count > d->maxScissorRects)
-        count = d->maxScissorRects;
+    if (count > d->maxScissorRects) {
+#if !defined(QVG_SCISSOR_CLIP)
+         count = d->maxScissorRects;
+#else
+        // Use masking
+        int width = paintDevice()->width();
+        int height = paintDevice()->height();
+        vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK,
+                   0, 0, width, height);
+        for (int i = 0; i < rects.size(); ++i) {
+            vgMask(VG_INVALID_HANDLE, VG_FILL_MASK,
+                   rects[i].x(), height - rects[i].y() - rects[i].height(),
+                   rects[i].width(), rects[i].height());
+        }
+
+        vgSeti(VG_SCISSORING, VG_FALSE);
+        vgSeti(VG_MASKING, VG_TRUE);
+        d->maskValid = true;
+        d->maskIsSet = false;
+        d->scissorMask = false;
+        d->scissorActive = false;
+        d->scissorDirty = false;
+        d->scissorRegion = region;
+        return;
+#endif
+    }
+
     QVarLengthArray<VGint> params(count * 4);
     int height = paintDevice()->height();
@@ -2955,4 +3019,9 @@
 }
 
+void QVGPaintEnginePrivate::systemStateChanged()
+{
+    q->updateScissor();
+}
+
 static void drawVGImage(QVGPaintEnginePrivate *d,
                         const QRectF& r, VGImage vgImg,
@@ -3026,4 +3095,19 @@
     d->setImageMode(VG_DRAW_IMAGE_STENCIL);
     vgDrawImage(vgImg);
+}
+
+bool QVGPaintEngine::canVgWritePixels(const QImage &image) const
+{
+    Q_D(const QVGPaintEngine);
+    // vgWritePixels ignores masking, blending and xforms so we can only use it if
+    // ALL of the following conditions are true:
+    // - It is a simple translate, or a scale of -1 on the y-axis (inverted)
+    // - The opacity is totally opaque
+    // - The composition mode is "source" OR "source over" provided the image is opaque
+    return ( d->imageTransform.type() <= QTransform::TxScale
+            && d->imageTransform.m11() == 1.0 && qAbs(d->imageTransform.m22()) == 1.0)
+            && d->opacity == 1.0f
+            && (d->blendMode == VG_BLEND_SRC || (d->blendMode == VG_BLEND_SRC_OVER &&
+                                                !image.hasAlphaChannel()));
 }
 
@@ -3042,7 +3126,16 @@
         else
             drawVGImage(d, r, vgpd->toVGImage(d->opacity), vgpd->size(), sr);
-    } else {
-        drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
-    }
+
+        if(!vgpd->failedToAlloc)
+            return;
+
+        // try to reallocate next time if reasonable small pixmap
+        QSize screenSize = QApplication::desktop()->screenGeometry().size();
+        if (pm.size().width() <= screenSize.width()
+            && pm.size().height() <= screenSize.height())
+            vgpd->failedToAlloc = false;
+    }
+
+    drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
 }
 
@@ -3061,7 +3154,16 @@
         else
             drawVGImage(d, pos, vgpd->toVGImage(d->opacity));
-    } else {
-        drawImage(pos, *(pd->buffer()));
-    }
+
+        if (!vgpd->failedToAlloc)
+            return;
+
+        // try to reallocate next time if reasonable small pixmap
+        QSize screenSize = QApplication::desktop()->screenGeometry().size();
+        if (pm.size().width() <= screenSize.width()
+            && pm.size().height() <= screenSize.height())
+            vgpd->failedToAlloc = false;
+    }
+
+    drawImage(pos, *(pd->buffer()));
 }
 
@@ -3084,7 +3186,29 @@
         }
     } else {
-        // Monochrome images need to use the vgChildImage() path.
-        vgImg = toVGImage(image, flags);
-        drawVGImage(d, r, vgImg, image.size(), sr);
+        if (canVgWritePixels(image) && (r.size() == sr.size()) && !flags) {
+            // Optimization for straight blits, no blending
+            int x = sr.x();
+            int y = sr.y();
+            int bpp = image.depth() >> 3; // bytes
+            int offset = 0;
+            int bpl = image.bytesPerLine();
+            if (d->imageTransform.m22() < 0) {
+                // inverted
+                offset = ((y + sr.height()) * bpl) - ((image.width() - x) * bpp);
+                bpl = -bpl;
+            } else {
+                offset = (y * bpl) + (x * bpp);
+            }
+            const uchar *bits = image.constBits() + offset;
+
+            QPointF mapped = d->imageTransform.map(r.topLeft());
+            vgWritePixels(bits, bpl, qt_vg_image_to_vg_format(image.format()),
+                        mapped.x(), mapped.y() - sr.height(), r.width(), r.height());
+            return;
+        } else {
+            // Monochrome images need to use the vgChildImage() path.
+            vgImg = toVGImage(image, flags);
+            drawVGImage(d, r, vgImg, image.size(), sr);
+        }
     }
     vgDestroyImage(vgImg);
@@ -3095,8 +3219,19 @@
     Q_D(QVGPaintEngine);
     VGImage vgImg;
-    if (d->simpleTransform || d->opacity == 1.0f)
+    if (canVgWritePixels(image)) {
+        // Optimization for straight blits, no blending
+        bool inverted = (d->imageTransform.m22() < 0);
+        const uchar *bits = inverted ? image.constBits() + image.byteCount() : image.constBits();
+        int bpl = inverted ? -image.bytesPerLine() : image.bytesPerLine();
+
+        QPointF mapped = d->imageTransform.map(pos);
+        vgWritePixels(bits, bpl, qt_vg_image_to_vg_format(image.format()),
+                             mapped.x(), mapped.y() - image.height(), image.width(), image.height());
+        return;
+    } else if (d->simpleTransform || d->opacity == 1.0f) {
         vgImg = toVGImage(image);
-    else
+    } else {
         vgImg = toVGImageWithOpacity(image, d->opacity);
+    }
     drawVGImage(d, pos, vgImg);
     vgDestroyImage(vgImg);
@@ -3107,6 +3242,5 @@
 {
     QBrush brush(state()->pen.color(), pixmap);
-    QTransform xform;
-    xform.translate(-s.x(), -s.y());
+    QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y());
     brush.setTransform(xform);
     fillRect(r, brush);
@@ -3117,7 +3251,6 @@
 // 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)
+void QVGPaintEngine::drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount,
+                                         const QPixmap &pixmap, QFlags<QPainter::PixmapFragmentHint> hints)
 {
 #if !defined(QT_SHIVAVG)
@@ -3130,5 +3263,5 @@
         return; // null QPixmap
     if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
-        QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+        QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
         return;
     }
@@ -3154,5 +3287,5 @@
 
     // Select the opacity paint object.
-    if ((hints & QDrawPixmaps::OpaqueHint) != 0 && d->opacity == 1.0f) {
+    if ((hints & QPainter::OpaqueHint) != 0 && d->opacity == 1.0f) {
         d->setImageMode(VG_DRAW_IMAGE_NORMAL);
     }  else {
@@ -3166,10 +3299,11 @@
     for (int i = 0; i < dataCount; ++i) {
         QTransform transform(d->imageTransform);
-        transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
+        transform.translate(drawingData[i].x, drawingData[i].y);
         transform.rotate(drawingData[i].rotation);
 
         VGImage child;
         QSize imageSize = vgpd->size();
-        QRectF sr = drawingData[i].source;
+        QRectF sr(drawingData[i].sourceLeft, drawingData[i].sourceTop,
+                  drawingData[i].width, drawingData[i].height);
         if (sr.topLeft().isNull() && sr.size() == imageSize) {
             child = vgImg;
@@ -3200,5 +3334,5 @@
         d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
 
-        if ((hints & QDrawPixmaps::OpaqueHint) == 0) {
+        if ((hints & QPainter::OpaqueHint) == 0) {
             qreal opacity = d->opacity * drawingData[i].opacity;
             if (opacity != 1.0f) {
@@ -3226,5 +3360,5 @@
         vgDestroyImage(cachedImages[i]);
 #else
-    QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+    QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
 #endif
 }
@@ -3257,4 +3391,5 @@
     font = vgCreateFont(0);
     scaleX = scaleY = 0.0;
+    invertedGlyphs = false;
     memset(cachedGlyphsMask, 0, sizeof(cachedGlyphsMask));
 }
@@ -3266,20 +3401,18 @@
 }
 
-void QVGFontGlyphCache::setScaleFromText(const QTextItemInt &ti)
-{
-    QFontInfo fi(ti.font());
+void QVGFontGlyphCache::setScaleFromText(const QFont &font, QFontEngine *fontEngine)
+{
+    QFontInfo fi(font);
     qreal pixelSize = fi.pixelSize();
-    qreal emSquare = ti.fontEngine->properties().emSquare.toReal();
+    qreal emSquare = fontEngine->properties().emSquare.toReal();
     scaleX = scaleY = static_cast<VGfloat>(pixelSize / emSquare);
 }
 
-void QVGFontGlyphCache::cacheGlyphs
-        (QVGPaintEnginePrivate *d, const QTextItemInt &ti,
-         const QVarLengthArray<glyph_t> &glyphs)
+void QVGFontGlyphCache::cacheGlyphs(QVGPaintEnginePrivate *d,
+                                    QFontEngine *fontEngine,
+                                    const glyph_t *g, int count)
 {
     VGfloat origin[2];
     VGfloat escapement[2];
-    const glyph_t *g = glyphs.constData();
-    int count = glyphs.size();
     glyph_metrics_t metrics;
     // Some Qt font engines don't set yoff in getUnscaledGlyph().
@@ -3300,19 +3433,19 @@
 #if !defined(QVG_NO_IMAGE_GLYPHS)
         Q_UNUSED(d);
-        QImage scaledImage = ti.fontEngine->alphaMapForGlyph(glyph);
+        QImage scaledImage = fontEngine->alphaMapForGlyph(glyph);
         VGImage vgImage = VG_INVALID_HANDLE;
-        metrics = ti.fontEngine->boundingBox(glyph);
+        metrics = fontEngine->boundingBox(glyph);
         if (!scaledImage.isNull()) {  // Not a space character
             if (scaledImage.format() == QImage::Format_Indexed8) {
                 vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER);
-                vgImageSubData(vgImage, qt_vg_imageBits(scaledImage), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height());
+                vgImageSubData(vgImage, scaledImage.constBits(), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height());
             } else if (scaledImage.format() == QImage::Format_Mono) {
                 QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8);
                 vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
-                vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height());
+                vgImageSubData(vgImage, img.constBits(), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height());
             } else {
                 QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
                 vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
-                vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
+                vgImageSubData(vgImage, img.constBits(), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
             }
         }
@@ -3326,5 +3459,5 @@
         // Calculate the path for the glyph and cache it.
         QPainterPath path;
-        ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics);
+        fontEngine->getUnscaledGlyph(glyph, &path, &metrics);
         VGPath vgPath;
         if (!path.isEmpty()) {
@@ -3358,5 +3491,5 @@
         return;
     }
- 
+
     // Get the glyphs and positions associated with the text item.
     QVarLengthArray<QFixedPoint> positions;
@@ -3365,22 +3498,47 @@
     ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
 
+    if (!drawCachedGlyphs(glyphs.size(), glyphs.data(), ti.font(), ti.fontEngine, p, positions.data()))
+        QPaintEngineEx::drawTextItem(p, textItem);
+#else
+    // OpenGL 1.0 does not have support for VGFont and glyphs,
+    // so fall back to the default Qt path stroking algorithm.
+    QPaintEngineEx::drawTextItem(p, textItem);
+#endif
+}
+
+void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
+{
+    drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->font, textItem->fontEngine(),
+                     QPointF(0, 0), textItem->glyphPositions);
+}
+
+ bool QVGPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFont &font,
+                                       QFontEngine *fontEngine, const QPointF &p,
+                                       const QFixedPoint *positions)
+ {
+#if !defined(QVG_NO_DRAW_GLYPHS)
+    Q_D(QVGPaintEngine);
+
     // Find the glyph cache for this font.
-    QVGFontCache::ConstIterator it = d->fontCache.constFind(ti.fontEngine);
+    QVGFontCache::ConstIterator it = d->fontCache.constFind(fontEngine);
     QVGFontGlyphCache *glyphCache;
     if (it != d->fontCache.constEnd()) {
         glyphCache = it.value();
     } else {
+#ifdef Q_OS_SYMBIAN
+        glyphCache = new QSymbianVGFontGlyphCache();
+#else
         glyphCache = new QVGFontGlyphCache();
+#endif
         if (glyphCache->font == VG_INVALID_HANDLE) {
             qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine");
             delete glyphCache;
-            QPaintEngineEx::drawTextItem(p, textItem);
-            return;
-        }
-        glyphCache->setScaleFromText(ti);
-        d->fontCache.insert(ti.fontEngine, glyphCache);
+            return false;
+        }
+        glyphCache->setScaleFromText(font, fontEngine);
+        d->fontCache.insert(fontEngine, glyphCache);
         if (!d->fontEngineCleaner)
             d->fontEngineCleaner = new QVGFontEngineCleaner(d);
-        QObject::connect(ti.fontEngine, SIGNAL(destroyed()),
+        QObject::connect(fontEngine, SIGNAL(destroyed()),
                          d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
     }
@@ -3388,25 +3546,37 @@
     // Set the transformation to use for drawing the current glyphs.
     QTransform glyphTransform(d->pathTransform);
-    glyphTransform.translate(p.x(), p.y());
+    if (d->transform.type() <= QTransform::TxTranslate) {
+        // Prevent blurriness of unscaled, unrotated text by forcing integer coordinates.
+        glyphTransform.translate(
+                floor(p.x() + glyphTransform.dx() + aliasedCoordinateDelta) - glyphTransform.dx(),
+                floor(p.y() - glyphTransform.dy() + aliasedCoordinateDelta) + glyphTransform.dy());
+    } else {
+        glyphTransform.translate(p.x(), p.y());
+    }
 #if defined(QVG_NO_IMAGE_GLYPHS)
     glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
 #endif
+
+    // Some glyph caches can create the VGImage upright
+    if (glyphCache->invertedGlyphs)
+        glyphTransform.scale(1, -1);
+
     d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
 
     // Add the glyphs from the text item into the glyph cache.
-    glyphCache->cacheGlyphs(d, ti, glyphs);
+    glyphCache->cacheGlyphs(d, fontEngine, glyphs, numGlyphs);
 
     // Create the array of adjustments between glyphs
-    QVarLengthArray<VGfloat> adjustments_x(glyphs.size());
-    QVarLengthArray<VGfloat> adjustments_y(glyphs.size());
-    for (int i = 1; i < glyphs.size(); ++i) {
-        adjustments_x[i-1] = (positions[i].x - positions[i-1].x).toReal();
-        adjustments_y[i-1] = (positions[i].y - positions[i-1].y).toReal();
+    QVarLengthArray<VGfloat> adjustments_x(numGlyphs);
+    QVarLengthArray<VGfloat> adjustments_y(numGlyphs);
+    for (int i = 1; i < numGlyphs; ++i) {
+        adjustments_x[i-1] = (positions[i].x - positions[i-1].x).round().toReal();
+        adjustments_y[i-1] = (positions[i].y - positions[i-1].y).round().toReal();
     }
 
     // Set the glyph drawing origin.
     VGfloat origin[2];
-    origin[0] = positions[0].x.toReal();
-    origin[1] = positions[0].y.toReal();
+    origin[0] = positions[0].x.round().toReal();
+    origin[1] = positions[0].y.round().toReal();
     vgSetfv(VG_GLYPH_ORIGIN, 2, origin);
 
@@ -3422,10 +3592,15 @@
     // the Qt pen, not the Qt brush.
     d->ensureBrush(state()->pen.brush());
-    vgDrawGlyphs(glyphCache->font, glyphs.size(), (VGuint*)glyphs.data(),
+    vgDrawGlyphs(glyphCache->font, numGlyphs, (VGuint*)glyphs,
                  adjustments_x.data(), adjustments_y.data(), VG_FILL_PATH, VG_TRUE);
+    return true;
 #else
-    // OpenGL 1.0 does not have support for VGFont and glyphs,
-    // so fall back to the default Qt path stroking algorithm.
-    QPaintEngineEx::drawTextItem(p, textItem);
+    Q_UNUSED(numGlyphs);
+    Q_UNUSED(glyphs);
+    Q_UNUSED(font);
+    Q_UNUSED(fontEngine);
+    Q_UNUSED(p);
+    Q_UNUSED(positions);
+    return false;
 #endif
 }
@@ -3537,4 +3712,5 @@
         d->scissorMask = false;
         d->maskRect = QRect();
+        d->scissorDirty = true;
         clipEnabledChanged();
     }
@@ -3788,5 +3964,5 @@
             return;
         vgImageSubData
-            (vgImage, qt_vg_imageBits(img) + img.bytesPerLine() * (img.height() - 1),
+            (vgImage, img.constBits() + img.bytesPerLine() * (img.height() - 1),
              -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0,
              img.width(), img.height());
Index: trunk/src/openvg/qpaintengine_vg_p.h
===================================================================
--- trunk/src/openvg/qpaintengine_vg_p.h	(revision 769)
+++ trunk/src/openvg/qpaintengine_vg_p.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -55,7 +55,9 @@
 
 #include <QtGui/private/qpaintengineex_p.h>
+#include <QtGui/private/qtextureglyphcache_p.h>
 
 QT_BEGIN_NAMESPACE
 
+class QFixedPoint;
 class QVGPaintEnginePrivate;
 class QPixmapData;
@@ -137,7 +139,12 @@
     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 drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount, const QPixmap &pixmap,
+                             QFlags<QPainter::PixmapFragmentHint> hints);
 
     void drawTextItem(const QPointF &p, const QTextItem &textItem);
+    void drawStaticTextItem(QStaticTextItem *staticTextItem);
+    bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFont &font,
+                          QFontEngine *fontEngine, const QPointF &p,
+                          const QFixedPoint *positions);
 
     void setState(QPainterState *s);
@@ -164,6 +171,6 @@
     bool isDefaultClipRect(const QRect& rect);
     bool clearRect(const QRectF &rect, const QColor &color);
+    bool canVgWritePixels(const QImage &image) const;
 };
-
 
 QT_END_NAMESPACE
Index: trunk/src/openvg/qpixmapdata_vg.cpp
===================================================================
--- trunk/src/openvg/qpixmapdata_vg.cpp	(revision 769)
+++ trunk/src/openvg/qpixmapdata_vg.cpp	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -43,17 +43,12 @@
 #include "qpaintengine_vg_p.h"
 #include <QtGui/private/qdrawhelper_p.h>
+#if !defined(QT_NO_EGL)
+#include <QtGui/private/qegl_p.h>
+#endif
 #include "qvg_p.h"
 #include "qvgimagepool_p.h"
-
-#if defined(Q_OS_SYMBIAN)
-#include <private/qt_s60_p.h>
-#include <fbs.h>
-#endif
-#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
-#include <sgresource/sgimage.h>
-typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*);
-typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR);
-typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR);
-#endif // QT_SYMBIAN_SUPPORTS_SGIMAGE
+#include <QBuffer>
+#include <QImageReader>
+#include <QtGui/private/qimage_p.h>
 
 QT_BEGIN_NAMESPACE
@@ -71,4 +66,5 @@
     inImagePool = false;
     inLRU = false;
+    failedToAlloc = false;
 #if !defined(QT_NO_EGL)
     context = 0;
@@ -161,9 +157,77 @@
         (const QImage &image, Qt::ImageConversionFlags flags)
 {
+    if(image.isNull())
+        return;
+
+    QImage img = image;
+    createPixmapForImage(img, flags, false);
+}
+
+void QVGPixmapData::fromImageReader(QImageReader *imageReader,
+                                 Qt::ImageConversionFlags flags)
+{
+    QImage image = imageReader->read();
+    if (image.isNull())
+        return;
+
+    createPixmapForImage(image, flags, true);
+}
+
+bool QVGPixmapData::fromFile(const QString &filename, const char *format,
+                          Qt::ImageConversionFlags flags)
+{
+    QImage image = QImageReader(filename, format).read();
+    if (image.isNull())
+        return false;
+
+    createPixmapForImage(image, flags, true);
+
+    return !isNull();
+}
+
+bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format,
+                      Qt::ImageConversionFlags flags)
+{
+    QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
+    QBuffer b(&a);
+    b.open(QIODevice::ReadOnly);
+    QImage image = QImageReader(&b, format).read();
+    if (image.isNull())
+        return false;
+
+    createPixmapForImage(image, flags, true);
+
+    return !isNull();
+}
+
+/*!
+    out-of-place conversion (inPlace == false) will always detach()
+ */
+void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
+{
     if (image.size() == QSize(w, h))
         setSerialNumber(++qt_vg_pixmap_serial);
     else
         resize(image.width(), image.height());
-    source = image.convertToFormat(sourceFormat(), flags);
+
+    QImage::Format format = sourceFormat();
+    int d = image.depth();
+    if (d == 1 || d == 16 || d == 24 || (d == 32 && !image.hasAlphaChannel()))
+        format = QImage::Format_RGB32;
+    else if (!(flags & Qt::NoOpaqueDetection) && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())
+        format = sourceFormat();
+    else
+        format = image.hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
+
+    if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
+        source = image;
+    } else {
+        source = image.convertToFormat(format);
+
+        // convertToFormat won't detach the image if format stays the same.
+        if (image.format() == format)
+            source.detach();
+    }
+
     recreate = true;
 }
@@ -234,15 +298,7 @@
 }
 
-// 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.
-const uchar *qt_vg_imageBits(const QImage& image)
-{
-    return image.bits();
-}
-
 VGImage QVGPixmapData::toVGImage()
 {
-    if (!isValid())
+    if (!isValid() || failedToAlloc)
         return VG_INVALID_HANDLE;
 
@@ -260,9 +316,11 @@
     if (vgImage == VG_INVALID_HANDLE) {
         vgImage = QVGImagePool::instance()->createImageForPixmap
-            (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);
+            (qt_vg_image_to_vg_format(source.format()), w, h, VG_IMAGE_QUALITY_FASTER, this);
 
         // Bail out if we run out of GPU memory - try again next time.
-        if (vgImage == VG_INVALID_HANDLE)
+        if (vgImage == VG_INVALID_HANDLE) {
+            failedToAlloc = true;
             return VG_INVALID_HANDLE;
+        }
 
         inImagePool = true;
@@ -274,6 +332,6 @@
         vgImageSubData
             (vgImage,
-             qt_vg_imageBits(source), source.bytesPerLine(),
-             VG_sARGB_8888_PRE, 0, 0, w, h);
+             source.constBits(), source.bytesPerLine(),
+             qt_vg_image_to_vg_format(source.format()), 0, 0, w, h);
     }
 
@@ -429,257 +487,3 @@
 }
 
-#if defined(Q_OS_SYMBIAN)
-
-static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)
-{
-      CFbsBitmap *copy = q_check_ptr(new CFbsBitmap);
-      if(!copy)
-        return 0;
-
-      if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
-          delete copy;
-          copy = 0;
-
-          return 0;
-      }
-
-      CFbsBitmapDevice* bitmapDevice = 0;
-      CFbsBitGc *bitmapGc = 0;
-      QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy));
-      QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
-      bitmapGc->Activate(bitmapDevice);
-
-      bitmapGc->BitBlt(TPoint(), bitmap);
-
-      delete bitmapGc;
-      delete bitmapDevice;
-
-      return copy;
-}
-
-void QVGPixmapData::cleanup()
-{
-    is_null = w = h = 0;
-    recreate = false;
-    source = QImage();
-}
-
-void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
-{
-    if (type == QPixmapData::SgImage && pixmap) {
-#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
-        RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);
-
-        destroyImages();
-        prevSize = QSize();
-
-        TInt err = 0;
-
-        RSgDriver driver;
-        err = driver.Open();
-        if (err != KErrNone) {
-            cleanup();
-            return;
-        }
-
-        if (sgImage->IsNull()) {
-            cleanup();
-            driver.Close();
-            return;
-        }
-
-        TSgImageInfo sgImageInfo;
-        err = sgImage->GetInfo(sgImageInfo);
-        if (err != KErrNone) {
-            cleanup();
-            driver.Close();
-            return;
-        }
-
-        pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
-        pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
-        pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
-
-        if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
-            cleanup();
-            driver.Close();
-            return;
-        }
-
-        const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
-        EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),
-                EGL_NO_CONTEXT,
-                EGL_NATIVE_PIXMAP_KHR,
-                (EGLClientBuffer)sgImage,
-                (EGLint*)KEglImageAttribs);
-
-        if (eglGetError() != EGL_SUCCESS) {
-            cleanup();
-            driver.Close();
-            return;
-        }
-
-        vgImage = vgCreateEGLImageTargetKHR(eglImage);
-        if (vgGetError() != VG_NO_ERROR) {
-            cleanup();
-            eglDestroyImageKHR(QEglContext::display(), eglImage);
-            driver.Close();
-            return;
-        }
-
-        w = sgImageInfo.iSizeInPixels.iWidth;
-        h = sgImageInfo.iSizeInPixels.iHeight;
-        d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
-        is_null = (w <= 0 || h <= 0);
-        source = QImage();
-        recreate = false;
-        prevSize = QSize(w, h);
-        setSerialNumber(++qt_vg_pixmap_serial);
-        // release stuff
-        eglDestroyImageKHR(QEglContext::display(), eglImage);
-        driver.Close();
-#endif
-    } else if (type == QPixmapData::FbsBitmap) {
-        CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
-
-        bool deleteSourceBitmap = false;
-
-#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
-
-        // Rasterize extended bitmaps
-
-        TUid extendedBitmapType = bitmap->ExtendedBitmapType();
-        if (extendedBitmapType != KNullUid) {
-            bitmap = createBlitCopy(bitmap);
-            deleteSourceBitmap = true;
-        }
-#endif
-
-        if (bitmap->IsCompressedInRAM()) {
-            bitmap = createBlitCopy(bitmap);
-            deleteSourceBitmap = true;
-        }
-
-        TDisplayMode displayMode = bitmap->DisplayMode();
-        QImage::Format format = qt_TDisplayMode2Format(displayMode);
-
-        TSize size = bitmap->SizeInPixels();
-
-        bitmap->BeginDataAccess();
-        uchar *bytes = (uchar*)bitmap->DataAddress();
-        QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
-        img = img.copy();
-        bitmap->EndDataAccess();
-
-        if(displayMode == EGray2) {
-            //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
-            //So invert mono bitmaps so that masks work correctly.
-            img.invertPixels();
-        } else if(displayMode == EColor16M) {
-            img = img.rgbSwapped(); // EColor16M is BGR
-        }
-
-        fromImage(img, Qt::AutoColor);
-
-        if(deleteSourceBitmap)
-            delete bitmap;
-    }
-}
-
-void* QVGPixmapData::toNativeType(NativeType type)
-{
-    if (type == QPixmapData::SgImage) {
-#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
-        toVGImage();
-
-        if (!isValid() || vgImage == VG_INVALID_HANDLE)
-            return 0;
-
-        TInt err = 0;
-
-        RSgDriver driver;
-        err = driver.Open();
-        if (err != KErrNone)
-            return 0;
-
-        TSgImageInfo sgInfo;
-        sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
-        sgInfo.iSizeInPixels.SetSize(w, h);
-        sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
-
-        RSgImage *sgImage = q_check_ptr(new RSgImage());
-        err = sgImage->Create(sgInfo, NULL, NULL);
-        if (err != KErrNone) {
-            driver.Close();
-            return 0;
-        }
-
-        pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
-        pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
-        pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
-
-        if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
-            driver.Close();
-            return 0;
-        }
-
-        const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
-        EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),
-                EGL_NO_CONTEXT,
-                EGL_NATIVE_PIXMAP_KHR,
-                (EGLClientBuffer)sgImage,
-                (EGLint*)KEglImageAttribs);
-        if (eglGetError() != EGL_SUCCESS) {
-            sgImage->Close();
-            driver.Close();
-            return 0;
-        }
-
-        VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);
-        if (vgGetError() != VG_NO_ERROR) {
-            eglDestroyImageKHR(QEglContext::display(), eglImage);
-            sgImage->Close();
-            driver.Close();
-            return 0;
-        }
-
-        vgCopyImage(dstVgImage, 0, 0,
-                vgImage, 0, 0,
-                w, h, VG_FALSE);
-
-        if (vgGetError() != VG_NO_ERROR) {
-            sgImage->Close();
-            sgImage = 0;
-        }
-        // release stuff
-        vgDestroyImage(dstVgImage);
-        eglDestroyImageKHR(QEglContext::display(), eglImage);
-        driver.Close();
-        return reinterpret_cast<void*>(sgImage);
-#endif
-    } else if (type == QPixmapData::FbsBitmap) {
-        CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
-
-        if (bitmap) {
-            if (bitmap->Create(TSize(source.width(), source.height()),
-                              EColor16MAP) == KErrNone) {
-                const uchar *sptr = qt_vg_imageBits(source);
-                bitmap->BeginDataAccess();
-
-                uchar *dptr = (uchar*)bitmap->DataAddress();
-                Mem::Copy(dptr, sptr, source.byteCount());
-
-                bitmap->EndDataAccess();
-            } else {
-                delete bitmap;
-                bitmap = 0;
-            }
-        }
-
-        return reinterpret_cast<void*>(bitmap);
-    }
-    return 0;
-}
-#endif //Q_OS_SYMBIAN
-
 QT_END_NAMESPACE
Index: trunk/src/openvg/qpixmapdata_vg_p.h
===================================================================
--- trunk/src/openvg/qpixmapdata_vg_p.h	(revision 769)
+++ trunk/src/openvg/qpixmapdata_vg_p.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -65,4 +65,5 @@
 class QEglContext;
 class QVGImagePool;
+class QImageReader;
 
 #if !defined(QT_NO_EGL)
@@ -88,4 +89,10 @@
     void resize(int width, int height);
     void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+    void fromImageReader(QImageReader *imageReader,
+                          Qt::ImageConversionFlags flags);
+    bool fromFile(const QString &filename, const char *format,
+                          Qt::ImageConversionFlags flags);
+    bool fromData(const uchar *buffer, uint len, const char *format,
+                          Qt::ImageConversionFlags flags);
 
     void fill(const QColor &color);
@@ -127,4 +134,5 @@
 protected:
     int metric(QPaintDevice::PaintDeviceMetric metric) const;
+    void createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace);
 
 #if defined(Q_OS_SYMBIAN)
@@ -136,5 +144,7 @@
     QVGPixmapData *prevLRU;
     bool inLRU;
+    bool failedToAlloc;
     friend class QVGImagePool;
+    friend class QVGPaintEngine;
 
 #if !defined(QT_NO_EGL)
Index: trunk/src/openvg/qpixmapfilter_vg.cpp
===================================================================
--- trunk/src/openvg/qpixmapfilter_vg.cpp	(revision 769)
+++ trunk/src/openvg/qpixmapfilter_vg.cpp	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
Index: trunk/src/openvg/qpixmapfilter_vg_p.h
===================================================================
--- trunk/src/openvg/qpixmapfilter_vg_p.h	(revision 769)
+++ trunk/src/openvg/qpixmapfilter_vg_p.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
Index: trunk/src/openvg/qvg.h
===================================================================
--- trunk/src/openvg/qvg.h	(revision 769)
+++ trunk/src/openvg/qvg.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
Index: trunk/src/openvg/qvg_p.h
===================================================================
--- trunk/src/openvg/qvg_p.h	(revision 769)
+++ trunk/src/openvg/qvg_p.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -56,8 +56,13 @@
 //
 
+// vgDrawGlyphs() only exists in OpenVG 1.1 and higher.
+#if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_DRAW_GLYPHS)
+#define QVG_NO_DRAW_GLYPHS 1
+#endif
+
 #include <QtGui/qimage.h>
 
 #if !defined(QT_NO_EGL)
-#include <QtGui/private/qegl_p.h>
+#include <QtGui/private/qeglcontext_p.h>
 #endif
 
Index: trunk/src/openvg/qvg_symbian.cpp
===================================================================
--- trunk/src/openvg/qvg_symbian.cpp	(revision 846)
+++ trunk/src/openvg/qvg_symbian.cpp	(revision 846)
@@ -0,0 +1,372 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpixmapdata_vg_p.h"
+#include "qvgfontglyphcache_p.h"
+#include <private/qt_s60_p.h>
+
+#include <fbs.h>
+#include <bitdev.h>
+
+#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
+#  include <sgresource/sgimage.h>
+#  ifdef SYMBIAN_FBSERV_GLYPHDATA // defined in fbs.h
+#    define QT_SYMBIAN_HARDWARE_GLYPH_CACHE
+#    include <graphics/fbsglyphdataiterator.h>
+#    include <private/qfontengine_s60_p.h>
+#  endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+typedef VGImage (*_vgCreateEGLImageTargetKHR)(VGeglImageKHR);
+static _vgCreateEGLImageTargetKHR qt_vgCreateEGLImageTargetKHR = 0;
+
+namespace QVG
+{
+    VGImage vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage);
+}
+
+VGImage QVG::vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage)
+{
+    if (!qt_vgCreateEGLImageTargetKHR && QEgl::hasExtension("EGL_KHR_image"))
+        qt_vgCreateEGLImageTargetKHR = (_vgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
+
+    return qt_vgCreateEGLImageTargetKHR ? qt_vgCreateEGLImageTargetKHR(eglImage) : 0;
+}
+
+extern int qt_vg_pixmap_serial;
+
+static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)
+{
+    CFbsBitmap *copy = q_check_ptr(new CFbsBitmap);
+    if(!copy)
+        return 0;
+
+    if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
+        delete copy;
+        copy = 0;
+
+        return 0;
+    }
+
+    CFbsBitmapDevice* bitmapDevice = 0;
+    CFbsBitGc *bitmapGc = 0;
+    QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy));
+    QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
+    bitmapGc->Activate(bitmapDevice);
+
+    bitmapGc->BitBlt(TPoint(), bitmap);
+
+    delete bitmapGc;
+    delete bitmapDevice;
+
+    return copy;
+}
+
+#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
+static VGImage sgImageToVGImage(QEglContext *context, const RSgImage &sgImage)
+{
+    // when "0" used as argument then
+    // default display, context are used
+    if (!context)
+        context = qt_vg_create_context(0, QInternal::Pixmap);
+
+    VGImage vgImage = VG_INVALID_HANDLE;
+
+    if (sgImage.IsNull())
+        return vgImage;
+
+    const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
+    EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
+            EGL_NO_CONTEXT,
+            EGL_NATIVE_PIXMAP_KHR,
+            (EGLClientBuffer)&sgImage,
+            (EGLint*)KEglImageAttribs);
+
+    if (!eglImage)
+        return vgImage;
+
+    vgImage = QVG::vgCreateEGLImageTargetKHR(eglImage);
+
+    QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
+    return vgImage;
+}
+#endif
+
+void QVGPixmapData::cleanup()
+{
+    is_null = w = h = 0;
+    recreate = false;
+    source = QImage();
+}
+
+void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
+{
+    if (type == QPixmapData::SgImage && pixmap) {
+#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
+        RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);
+        destroyImages();
+        prevSize = QSize();
+
+        VGImage vgImage = sgImageToVGImage(context, *sgImage);
+        if (vgImage != VG_INVALID_HANDLE) {
+            w = vgGetParameteri(vgImage, VG_IMAGE_WIDTH);
+            h = vgGetParameteri(vgImage, VG_IMAGE_HEIGHT);
+            d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
+        }
+
+        is_null = (w <= 0 || h <= 0);
+        source = QImage(); // vgGetImageSubData() some day?
+        recreate = false;
+        prevSize = QSize(w, h);
+        //setSerialNumber(++qt_vg_pixmap_serial);
+#endif
+    } else if (type == QPixmapData::FbsBitmap) {
+        CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
+
+        bool deleteSourceBitmap = false;
+#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
+
+        // Rasterize extended bitmaps
+
+        TUid extendedBitmapType = bitmap->ExtendedBitmapType();
+        if (extendedBitmapType != KNullUid) {
+            bitmap = createBlitCopy(bitmap);
+            deleteSourceBitmap = true;
+        }
+#endif
+
+        if (bitmap->IsCompressedInRAM()) {
+            bitmap = createBlitCopy(bitmap);
+            deleteSourceBitmap = true;
+        }
+
+        TDisplayMode displayMode = bitmap->DisplayMode();
+        QImage::Format format = qt_TDisplayMode2Format(displayMode);
+
+        TSize size = bitmap->SizeInPixels();
+        int bytesPerLine = bitmap->ScanLineLength(size.iWidth, displayMode);
+
+        bitmap->BeginDataAccess();
+        uchar *bytes = (uchar*)bitmap->DataAddress();
+        QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format);
+        img = img.copy();
+        bitmap->EndDataAccess();
+
+        if(displayMode == EGray2) {
+            //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+            //So invert mono bitmaps so that masks work correctly.
+            img.invertPixels();
+        } else if(displayMode == EColor16M) {
+            img = img.rgbSwapped(); // EColor16M is BGR
+        }
+
+        fromImage(img, Qt::AutoColor);
+
+        if(deleteSourceBitmap)
+            delete bitmap;
+    }
+}
+
+void* QVGPixmapData::toNativeType(NativeType type)
+{
+    if (type == QPixmapData::SgImage) {
+#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
+        toVGImage();
+
+        if (!isValid() || vgImage == VG_INVALID_HANDLE)
+            return 0;
+
+        TInt err = 0;
+
+        RSgDriver driver;
+        err = driver.Open();
+        if (err != KErrNone)
+            return 0;
+
+        TSgImageInfo sgInfo;
+        sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
+        sgInfo.iSizeInPixels.SetSize(w, h);
+        sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
+
+        QScopedPointer<RSgImage> sgImage(new RSgImage());
+        err = sgImage->Create(sgInfo, NULL, NULL);
+        if (err != KErrNone) {
+            driver.Close();
+            return 0;
+        }
+
+        const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
+        EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
+                EGL_NO_CONTEXT,
+                EGL_NATIVE_PIXMAP_KHR,
+                (EGLClientBuffer)sgImage.data(),
+                (EGLint*)KEglImageAttribs);
+        if (!eglImage || eglGetError() != EGL_SUCCESS) {
+            sgImage->Close();
+            driver.Close();
+            return 0;
+        }
+
+        VGImage dstVgImage = QVG::vgCreateEGLImageTargetKHR(eglImage);
+        if (!dstVgImage || vgGetError() != VG_NO_ERROR) {
+            QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
+            sgImage->Close();
+            driver.Close();
+            return 0;
+        }
+
+        vgCopyImage(dstVgImage, 0, 0,
+                vgImage, 0, 0,
+                w, h, VG_FALSE);
+
+        if (vgGetError() != VG_NO_ERROR) {
+            sgImage->Close();
+            sgImage.reset();
+        }
+
+        // release stuff
+        vgDestroyImage(dstVgImage);
+        QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
+        driver.Close();
+        return reinterpret_cast<void*>(sgImage.take());
+#endif
+    } else if (type == QPixmapData::FbsBitmap) {
+                CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
+
+        if (bitmap) {
+            if (bitmap->Create(TSize(source.width(), source.height()),
+                              EColor16MAP) == KErrNone) {
+                const uchar *sptr = const_cast<const QImage&>(source).bits();
+                bitmap->BeginDataAccess();
+
+                uchar *dptr = (uchar*)bitmap->DataAddress();
+                Mem::Copy(dptr, sptr, source.byteCount());
+
+                bitmap->EndDataAccess();
+            } else {
+                delete bitmap;
+                bitmap = 0;
+            }
+        }
+
+        return reinterpret_cast<void*>(bitmap);
+    }
+    return 0;
+}
+
+QSymbianVGFontGlyphCache::QSymbianVGFontGlyphCache() : QVGFontGlyphCache()
+{
+#ifdef QT_SYMBIAN_HARDWARE_GLYPH_CACHE
+    invertedGlyphs = true;
+#endif
+}
+
+void QSymbianVGFontGlyphCache::cacheGlyphs(QVGPaintEnginePrivate *d,
+                                           QFontEngine *fontEngine,
+                                           const glyph_t *g, int count)
+{
+#ifdef QT_SYMBIAN_HARDWARE_GLYPH_CACHE
+    QFontEngineS60 *s60fontEngine = static_cast<QFontEngineS60*>(fontEngine);
+    if (s60fontEngine->m_activeFont->TypeUid() != KCFbsFontUid)
+            return QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
+
+    QVector<glyph_t> uncachedGlyphs;
+    while (count-- > 0) {
+        // Skip this glyph if we have already cached it before.
+        glyph_t glyph = *g++;
+        if (((glyph < 256) && ((cachedGlyphsMask[glyph / 32] & (1 << (glyph % 32))) != 0))
+            || cachedGlyphs.contains(glyph))
+            continue;
+        if (!uncachedGlyphs.contains(glyph))
+            uncachedGlyphs.append(glyph);
+    }
+
+    if (!uncachedGlyphs.isEmpty()) {
+        CFbsFont *cfbsFont = static_cast<CFbsFont *>(s60fontEngine->m_activeFont);
+        RFbsGlyphDataIterator iter;
+
+        int err = iter.Open(*cfbsFont, (const unsigned int*)uncachedGlyphs.constData(), uncachedGlyphs.count());
+
+        if (err == KErrNotSupported || err == KErrInUse) { // Fallback in possibly supported error cases
+            iter.Close();
+            qWarning("Falling back to default QVGFontGlyphCache");
+            return QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
+        }
+
+        for (; err == KErrNone; err = iter.Next()) {
+            const unsigned int glyph = iter.GlyphCode();
+
+            const RSgImage& image = iter.Image();
+            const TOpenFontCharMetrics& metrics = iter.Metrics();
+
+            TRect glyphBounds;
+            metrics.GetHorizBounds(glyphBounds);
+            VGImage vgImage = sgImageToVGImage(0, image);
+            VGfloat origin[2];
+            VGfloat escapement[2];
+            origin[0] = -glyphBounds.iTl.iX;
+            origin[1] = glyphBounds.iBr.iY;
+            escapement[0] = 0;
+            escapement[1] = 0;
+            vgSetGlyphToImage(font, glyph, vgImage, origin, escapement);
+            vgDestroyImage(vgImage);
+
+            // Add to cache
+            if (glyph < 256)
+                cachedGlyphsMask[glyph / 32] |= (1 << (glyph % 32));
+            else
+                cachedGlyphs.insert(glyph);
+        }
+        iter.Close();
+
+        if (err == KErrNoMemory || err == KErrNoGraphicsMemory)
+            qWarning("Not enough memory to cache glyph");
+        else if (err != KErrNotFound)
+            qWarning("Received error %d from glyph cache", err);
+    }
+#else
+    QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
+#endif
+}
+
+QT_END_NAMESPACE
Index: trunk/src/openvg/qvgcompositionhelper_p.h
===================================================================
--- trunk/src/openvg/qvgcompositionhelper_p.h	(revision 769)
+++ trunk/src/openvg/qvgcompositionhelper_p.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
Index: trunk/src/openvg/qvgfontglyphcache_p.h
===================================================================
--- trunk/src/openvg/qvgfontglyphcache_p.h	(revision 846)
+++ trunk/src/openvg/qvgfontglyphcache_p.h	(revision 846)
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtOpenVG module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVGFONTGLYPHCACHE_H
+#define QVGFONTGLYPHCACHE_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qvarlengtharray.h>
+#include <QtGui/private/qfontengine_p.h>
+
+#include <qvg_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVGPaintEnginePrivate;
+
+#ifndef QVG_NO_DRAW_GLYPHS
+
+class QVGFontGlyphCache
+{
+public:
+    QVGFontGlyphCache();
+    virtual ~QVGFontGlyphCache();
+
+    virtual void cacheGlyphs(QVGPaintEnginePrivate *d,
+                             QFontEngine *fontEngine,
+                             const glyph_t *g, int count);
+    void setScaleFromText(const QFont &font, QFontEngine *fontEngine);
+
+    VGFont font;
+    VGfloat scaleX;
+    VGfloat scaleY;
+    bool invertedGlyphs;
+    uint cachedGlyphsMask[256 / 32];
+    QSet<glyph_t> cachedGlyphs;
+};
+
+#if defined(Q_OS_SYMBIAN)
+class QSymbianVGFontGlyphCache : public QVGFontGlyphCache
+{
+public:
+    QSymbianVGFontGlyphCache();
+    void cacheGlyphs(QVGPaintEnginePrivate *d,
+                     QFontEngine *fontEngine,
+                     const glyph_t *g, int count);
+};
+#endif
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QVGFONTGLYPHCACHE_H
Index: trunk/src/openvg/qvgimagepool.cpp
===================================================================
--- trunk/src/openvg/qvgimagepool.cpp	(revision 769)
+++ trunk/src/openvg/qvgimagepool.cpp	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -155,14 +155,21 @@
     Q_UNUSED(height);
 
-    if (data)
+    bool succeeded = false;
+    bool wasInLRU = false;
+    if (data) {
+        wasInLRU = data->inLRU;
         moveToHeadOfLRU(data);
+    }
 
     QVGPixmapData *lrudata = pixmapLRU();
     if (lrudata && lrudata != data) {
         lrudata->reclaimImages();
-        return true;
+        succeeded = true;
     }
 
-    return false;
+    if (data && !wasInLRU)
+        removeFromLRU(data);
+
+    return succeeded;
 }
 
Index: trunk/src/openvg/qvgimagepool_p.h
===================================================================
--- trunk/src/openvg/qvgimagepool_p.h	(revision 769)
+++ trunk/src/openvg/qvgimagepool_p.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
Index: trunk/src/openvg/qwindowsurface_vg.cpp
===================================================================
--- trunk/src/openvg/qwindowsurface_vg.cpp	(revision 769)
+++ trunk/src/openvg/qwindowsurface_vg.cpp	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -48,5 +48,5 @@
 #if !defined(QT_NO_EGL)
 
-#include <QtGui/private/qegl_p.h>
+#include <QtGui/private/qeglcontext_p.h>
 #include <QtGui/private/qwidget_p.h>
 
Index: trunk/src/openvg/qwindowsurface_vg_p.h
===================================================================
--- trunk/src/openvg/qwindowsurface_vg_p.h	(revision 769)
+++ trunk/src/openvg/qwindowsurface_vg_p.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
Index: trunk/src/openvg/qwindowsurface_vgegl.cpp
===================================================================
--- trunk/src/openvg/qwindowsurface_vgegl.cpp	(revision 769)
+++ trunk/src/openvg/qwindowsurface_vgegl.cpp	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -72,16 +72,11 @@
 QImage::Format qt_vg_config_to_image_format(QEglContext *context)
 {
-    EGLint red = 0;
-    EGLint green = 0;
-    EGLint blue = 0;
-    EGLint alpha = 0;
-    context->configAttrib(EGL_RED_SIZE, &red);
-    context->configAttrib(EGL_GREEN_SIZE, &green);
-    context->configAttrib(EGL_BLUE_SIZE, &blue);
-    context->configAttrib(EGL_ALPHA_SIZE, &alpha);
+    EGLint red = context->configAttrib(EGL_RED_SIZE);
+    EGLint green = context->configAttrib(EGL_GREEN_SIZE);
+    EGLint blue = context->configAttrib(EGL_BLUE_SIZE);
+    EGLint alpha = context->configAttrib(EGL_ALPHA_SIZE);
     QImage::Format argbFormat;
 #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
-    EGLint type = 0;
-    context->configAttrib(EGL_SURFACE_TYPE, &type);
+    EGLint type = context->configAttrib(EGL_SURFACE_TYPE);
     if ((type & EGL_VG_ALPHA_FORMAT_PRE_BIT) != 0)
         argbFormat = QImage::Format_ARGB32_Premultiplied;
@@ -211,9 +206,5 @@
 static bool isPremultipliedContext(const QEglContext *context)
 {
-    EGLint value = 0;
-    if (context->configAttrib(EGL_SURFACE_TYPE, &value))
-        return (value & EGL_VG_ALPHA_FORMAT_PRE_BIT) != 0;
-    else
-        return false;
+    return context->configAttrib(EGL_SURFACE_TYPE) & EGL_VG_ALPHA_FORMAT_PRE_BIT;
 }
 
@@ -231,7 +222,7 @@
     QByteArray interval = qgetenv("QT_VG_SWAP_INTERVAL");
     if (!interval.isEmpty())
-        eglSwapInterval(QEglContext::display(), interval.toInt());
+        eglSwapInterval(QEgl::display(), interval.toInt());
     else
-        eglSwapInterval(QEglContext::display(), 1);
+        eglSwapInterval(QEgl::display(), 1);
 
 #ifdef EGL_RENDERABLE_TYPE
@@ -247,5 +238,5 @@
         EGLConfig cfg;
         if (eglChooseConfig
-                    (QEglContext::display(), properties, &cfg, 1, &matching) &&
+                    (QEgl::display(), properties, &cfg, 1, &matching) &&
                 matching > 0) {
             // Check that the selected configuration actually supports OpenVG
@@ -254,7 +245,7 @@
             EGLint type = 0;
             eglGetConfigAttrib
-                (QEglContext::display(), cfg, EGL_CONFIG_ID, &id);
+                (QEgl::display(), cfg, EGL_CONFIG_ID, &id);
             eglGetConfigAttrib
-                (QEglContext::display(), cfg, EGL_RENDERABLE_TYPE, &type);
+                (QEgl::display(), cfg, EGL_RENDERABLE_TYPE, &type);
             if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) {
                 context->setConfig(cfg);
@@ -277,8 +268,5 @@
     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 |
@@ -335,5 +323,5 @@
     shared->context->doneCurrent();
     if (shared->surface != EGL_NO_SURFACE) {
-        eglDestroySurface(QEglContext::display(), shared->surface);
+        eglDestroySurface(QEgl::display(), shared->surface);
         shared->surface = EGL_NO_SURFACE;
     }
@@ -413,5 +401,5 @@
         }
         shared->surface = eglCreatePbufferSurface
-            (QEglContext::display(), shared->context->config(), attribs);
+            (QEgl::display(), shared->context->config(), attribs);
     }
     return shared->surface;
@@ -556,5 +544,5 @@
             recreateBackBuffer = false;
             if (backBufferSurface != EGL_NO_SURFACE) {
-                eglDestroySurface(QEglContext::display(), backBufferSurface);
+                eglDestroySurface(QEgl::display(), backBufferSurface);
                 backBufferSurface = EGL_NO_SURFACE;
             }
@@ -569,5 +557,5 @@
                 // Create an EGL surface for rendering into the VGImage.
                 backBufferSurface = eglCreatePbufferFromClientBuffer
-                    (QEglContext::display(), EGL_OPENVG_IMAGE,
+                    (QEgl::display(), EGL_OPENVG_IMAGE,
                      (EGLClientBuffer)(backBuffer),
                      context->config(), NULL);
@@ -706,5 +694,5 @@
         // Did we get a direct to window rendering surface?
         EGLint buffer = 0;
-        if (eglQueryContext(QEglContext::display(), context->context(),
+        if (eglQueryContext(QEgl::display(), context->context(),
                             EGL_RENDER_BUFFER, &buffer) &&
                 buffer == EGL_SINGLE_BUFFER) {
@@ -719,8 +707,7 @@
     // Try to force the surface back buffer to preserve its contents.
     if (needToSwap) {
-        eglGetError();  // Clear error state first.
-        eglSurfaceAttrib(QEglContext::display(), windowSurface,
+        bool succeeded = eglSurfaceAttrib(QEgl::display(), windowSurface,
                 EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
-        if (eglGetError() != EGL_SUCCESS) {
+        if (!succeeded && eglGetError() != EGL_SUCCESS) {
             qWarning("QVG: could not enable preserved swap");
         }
Index: trunk/src/openvg/qwindowsurface_vgegl_p.h
===================================================================
--- trunk/src/openvg/qwindowsurface_vgegl_p.h	(revision 769)
+++ trunk/src/openvg/qwindowsurface_vgegl_p.h	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -59,5 +59,5 @@
 #if !defined(QT_NO_EGL)
 
-#include <QtGui/private/qegl_p.h>
+#include <QtGui/private/qeglcontext_p.h>
 
 QT_BEGIN_NAMESPACE
