带有QOpenGL的QGraphicsView在Intel集成显卡上闪烁

时间:2016-12-08 08:12:28

标签: qt qgraphicsview qglwidget vsync

我有自己的类,它继承自Qt5.6 QGraphcisView。

我在场景中也有一个QGraphicsPixmapItem。 (忘了说)ANGLE已启用!

CMyGraphicsView::CMyGraphicsView(QWidget *parent) : QGraphcisView(parent)
{
    QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
    QGLFormat fmt(QGL::SampleBuffers);
    fmt.setSwapInterval(2);
    gl = new QGLWidget(fmt);
    setViewport(gl);
....
}

我经常更新pixmap以制作像视频一样的动画。事实上它是视频,因为我为QMediaPlayer实现了我自己的QAbstractVideoSurface,并且我收到了我在现场更新的视频帧。

bool MyPlayer::present(const QVideoFrame &Frame)
{
    MyPlayer* player = reinterpret_cast<MyPlayer*>(parent());
    if (Frame.isValid())
    {
        QVideoFrame myframe(Frame);

        if (!myframe.map(QAbstractVideoBuffer::ReadOnly))
            return false;

        QImage image(
            (const unsigned char*)myframe.bits(),
            myframe.width(),
            myframe.height(),
            myframe.bytesPerLine(),
            QVideoFrame::imageFormatFromPixelFormat( myframe.pixelFormat() )
        );

        QPixmap pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion);
        pixmap_frame_->setPixmap(pixmap);
        myframe.unmap();
        return true;
    }
    return false;
}

问题是,在英特尔集成视频卡上,我看到动画闪烁,就像更新与显示器VSYNC不同步。

在NVIDIA显卡上似乎一切正常,没有问题。

我从Qt文档中读到,制作fmt.setSwapInterval(2)应该允许我每隔2次VSYNC刷新更新屏幕,所以我期望在60Hz显示器上有平滑的30fps动画。除此之外,似乎setSwapInterval()对英特尔和NVIDIA都没有任何作用:

在英特尔卡上,它总是闪烁,在NVIDIA卡上,它总是流畅的,不依赖于swapInterval()或任何其他QGLFormat选项。

我也尝试fmt.setDoubleBuffer(true);,但对于英特尔卡也无济于事。我该如何解决闪烁问题?

原因我可以直接放在场景QGraphicsVideoItem - 然后就可以了,但是我不能使用这个选项,因为后来我需要动态修改帧像素 - 因为我需要QAbstractVideoSurface。

0 个答案:

没有答案