void tst_NativeImageHandleProvider::hibernate()
{
#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_OPENVG)
    QPixmap tmp(10, 20);
    if (tmp.pixmapData()->classId() == QPixmapData::OpenVGClass) {
        BitmapProvider prov;
        prov.bmp = new CFbsBitmap;
        QCOMPARE(prov.bmp->Create(TSize(prov.w, prov.h), EColor16MAP), KErrNone);

        QPixmap pm = pixmapFromNativeImageHandleProvider(&prov);
        QCOMPARE(prov.refCount, 1);

        QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pm.pixmapData());
        vgpd->hibernate();
        QCOMPARE(prov.refCount, 0);

        // Calling toVGImage() may cause some warnings as we don't have a gui initialized,
        // but the only thing we care about here is get() being called.
        vgpd->toVGImage();
        QCOMPARE(prov.refCount, 1);

        pm = QPixmap();
        QCOMPARE(prov.refCount, 0);
        delete prov.bmp;
    } else {
         QSKIP("Not openvg", SkipSingle);
    }
#else
    QSKIP("Not applicable", SkipSingle);
#endif
}
void qt_vg_hibernate_pixmaps(QVGSharedContext *shared)
{
    // Artificially increase the reference count to prevent the
    // context from being destroyed until after we have finished
    // the hibernation process.
    ++(shared->refCount);

    // We need a context current to hibernate the VGImage objects.
    shared->context->makeCurrent(qt_vg_shared_surface());

    // Scan all QVGPixmapData objects in the system and hibernate them.
    QVGPixmapData *pd = shared->firstPixmap;
    while (pd != 0) {
        pd->hibernate();
        pd = pd->next;
    }

    // Hibernate any remaining VGImage's in the image pool.
    QVGImagePool::instance()->hibernate();

    // Don't need the current context any more.
    shared->context->lazyDoneCurrent();

    // Decrease the reference count and destroy the context if necessary.
    if (--(shared->refCount) <= 0)
        qt_vg_destroy_shared_context(shared);
}
Example #3
0
bool QVGImagePool::reclaimSpace(VGImageFormat format,
                                VGint width, VGint height,
                                QVGPixmapData *data)
{
    Q_UNUSED(format);   // For future use in picking the best image to eject.
    Q_UNUSED(width);
    Q_UNUSED(height);

    bool succeeded = false;
    bool wasInLRU = false;
    if (data) {
        wasInLRU = data->inLRU;
        moveToHeadOfLRU(data);
    }

    QVGPixmapData *lrudata = pixmapLRU();
    if (lrudata && lrudata != data) {
        lrudata->reclaimImages();
        succeeded = true;
    }

    if (data && !wasInLRU)
        removeFromLRU(data);

    return succeeded;
}
void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default drop shadow filter implementation.
        QPixmapDropShadowFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_A_8, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    // Clamp the radius range.  We divide by 2 because the OpenVG blur
    // is "too blurry" compared to the default raster implementation.
    VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
    VGfloat radiusF = VGfloat(blurRadius()) / 2.0f;
    if (radiusF < 0.001f)
        radiusF = 0.001f;
    else if (radiusF > maxRadius)
        radiusF = maxRadius;

    // Blur the blackened source image.
    vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);

    VGImage child = VG_INVALID_HANDLE;

    QRect srect;
    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
        srect = QRect(0, 0, size.width(), size.height());
    } else {
        srect = srcRect.toRect();
        child = vgChildImage(dstImage, srect.x(), srect.y(), srect.width(), srect.height());
    }

    qt_vg_drawVGImageStencil(painter, dest + offset(), child, color());

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);

    // Now draw the actual pixmap over the top.
    painter->drawPixmap(dest, src, srect);
}
Example #5
0
/*
    \internal

    Returns the VGImage that is storing the contents of \a pixmap.
    Returns VG_INVALID_HANDLE if \a pixmap is not owned by the OpenVG
    graphics system or \a pixmap is invalid.

    This function is typically used to access the backing store
    for a pixmap when executing raw OpenVG calls.  It must only
    be used when a QPainter is active and the OpenVG paint engine
    is in use by the QPainter.

    \sa {QtOpenVG Module}
*/
Q_OPENVG_EXPORT VGImage qPixmapToVGImage(const QPixmap& pixmap)
{
    QPixmapData *pd = pixmap.pixmapData();
    if (!pd)
        return VG_INVALID_HANDLE; // null QPixmap
    if (pd->classId() == QPixmapData::OpenVGClass) {
        QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
        if (vgpd->isValid())
            return vgpd->toVGImage();
    }
    return VG_INVALID_HANDLE;
}
void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default blur filter implementation.
        QPixmapBlurFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_sARGB_8888_PRE, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    // Clamp the radius range.  We divide by 2 because the OpenVG blur
    // is "too blurry" compared to the default raster implementation.
    VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
    VGfloat radiusF = VGfloat(radius()) / 2.0f;
    if (radiusF < 0.001f)
        radiusF = 0.001f;
    else if (radiusF > maxRadius)
        radiusF = maxRadius;

    vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);

    VGImage child = VG_INVALID_HANDLE;

    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
    } else {
        QRect src = srcRect.toRect();
        child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
    }

    qt_vg_drawVGImage(painter, dest, child);

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);
}
Example #7
0
void QVGImagePool::hibernate()
{
    Q_D(QVGImagePool);
    QVGPixmapData *pd = d->lruLast;
    while (pd) {
        QVGPixmapData *prevLRU = pd->prevLRU;
        pd->inImagePool = false;
        pd->inLRU = false;
        pd->nextLRU = 0;
        pd->prevLRU = 0;
        pd->hibernate();
        pd = prevLRU;
    }
    d->lruFirst = 0;
    d->lruLast = 0;
}
bool QVGImagePool::reclaimSpace(VGImageFormat format,
                                VGint width, VGint height,
                                QVGPixmapData *data)
{
    Q_UNUSED(format);   // For future use in picking the best image to eject.
    Q_UNUSED(width);
    Q_UNUSED(height);

    if (data)
        moveToHeadOfLRU(data);

    QVGPixmapData *lrudata = pixmapLRU();
    if (lrudata && lrudata != data) {
        lrudata->reclaimImages();
        return true;
    }

    return false;
}
void QVGPixmapConvolutionFilter::draw
        (QPainter *painter, const QPointF &dest,
         const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default convolution filter implementation.
        QPixmapConvolutionFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_sARGB_8888_PRE, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    int kernelWidth = rows();
    int kernelHeight = columns();
    const qreal *kern = convolutionKernel();
    QVarLengthArray<VGshort> kernel;
    for (int i = 0; i < kernelWidth; ++i) {
        for (int j = 0; j < kernelHeight; ++j) {
            kernel.append((VGshort)(kern[j * kernelWidth + i] * 1024.0f));
        }
    }

    VGfloat values[4];
    values[0] = 0.0f;
    values[1] = 0.0f;
    values[2] = 0.0f;
    values[3] = 0.0f;
    vgSetfv(VG_TILE_FILL_COLOR, 4, values);

    vgConvolve(dstImage, srcImage,
               kernelWidth, kernelHeight, 0, 0,
               kernel.constData(), 1.0f / 1024.0f, 0.0f,
               VG_TILE_FILL);

    VGImage child = VG_INVALID_HANDLE;

    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
    } else {
        QRect src = srcRect.toRect();
        child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
    }

    qt_vg_drawVGImage(painter, dest, child);

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);
}
void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default colorize filter implementation.
        QPixmapColorizeFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_sARGB_8888_PRE, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    // Determine the weights for the matrix from the color and strength.
    QColor c = color();
    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]);

    VGImage child = VG_INVALID_HANDLE;

    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
    } else {
        QRect src = srcRect.toRect();
        child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
    }

    qt_vg_drawVGImage(painter, dest, child);

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);
}