Qt Quick:DropShadow在半径变化时非常慢

时间:2016-11-14 16:01:38

标签: performance qt qml qtquick2 dropshadow

我将从我的测试用例开始。这很基本。

  • 它创建一个以3D形式旋转的矩形,以及一个用于矩形的DropShadow元素。
  • 它会动画DropShadow的radius属性。
  • 它创建了一个不断重新绘制的1x1px Canvas3D,因此我可以检查它是否经常重新绘制所有其他内容的重新绘制(Canvas3D具有内置的fps属性)。我用它来衡量应用程序的帧速率。

动画radius的值时,应用程序的运行速度为10FPS。如果此值未设置动画,则应用程序将以60FPS运行。

3D旋转的要点是在rectWrapper元素中有一些动画,因此即使其半径未更改,也必须不断重新计算阴影。这证明计算阴影的速度非常快,而减慢它的速度只是radius的不断变化。

我的代码:

main.cpp :(唯一不寻常的是AA_UseOpenGLES,这是因为我的低于标准的OpenGL驱动程序所必需的)

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

main.qml:

import QtQuick 2.5
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
import QtCanvas3D 1.1

Window {
    visible: true
    width: 640
    height: 480

    Text {
        text: canvas3d.fps + " FPS"
        font.pointSize: 18
    }
    // `rectWrapper` is needed as a layer of indirection around
    // `rect` so DropShadow is aware of `rect`'s the rotation
    Item {
        id: rectWrapper
        width: rect.width
        // +100 here to accomodate the extra space needed due to
        // 3D perspective projection of the 3D-rotated inner item
        height: rect.height + 100
        anchors.centerIn: parent
        visible: false

        Rectangle {
            id: rect
            color: "red"
            width: 300
            height: 100
            anchors.centerIn: parent

            property real yRot: 50

            transform: Rotation {
                origin.x: rect.width/2;
                origin.y: rect.height/2;
                axis { x: 0; y: 1; z: 0 }
                angle: rect.yRot
            }

            SequentialAnimation on yRot {
                loops: Animation.Infinite
                NumberAnimation {
                    from: -180; to: 180; duration: 5000
                }
            }
        }
    }

    DropShadow {
        source: rectWrapper
        anchors.fill: rectWrapper
        samples: 16
        radius: 16

        SequentialAnimation on radius {
            //running: false
            loops: Animation.Infinite
            NumberAnimation {
                from: 2; to: 16; duration: 1000
            }
        }
    }

    Canvas3D {
        id: canvas3d
        width: 1; height: 1 // nonzero size so it can be redrawn
        property var gl;

        onInitializeGL: {
            // should get and save context, otherwise FPS isn't measured for some reason
            gl = canvas3d.getContext("canvas3d", {depth:true, antialias:true, alpha:true});
        }
    }
}

取消注释running: false以查看巨大的加速。

我的理论: DropShadow使用的模糊着色器可能会在每次更改半径时重新编译。当我在GLSL中上传bool制服的新值时,我听说过这种情况,但在这种情况下,它不是bool,而是real

问题:为什么会出现这种减速?我可以解决它吗?

0 个答案:

没有答案