关于qml 动画性能问题分析,做流畅动画

关于qml 动画性能问题分析,做流畅动画

背景

在开发过程中经常使用动画,如果在台式PC上运行,没发现区别,但是在资源受限的嵌入式设备上,则动画的实现方式与流畅性能区别尤为明显

方式一 ,刷图片

频繁从存储器读取图片资源加载,加载速度慢,内存消耗大,增加GPU负担,导致动画不流畅或者掉帧

import QtQuick 2.7
Item {
    id:root
    width: 1920
    height: 720

    property int carMoveIndex:-1
    
    Component.onCompleted: {
        moveTimer.start()
    }

    Timer{
        id:moveTimer
        interval: 40
        running: false
        repeat: true
        onTriggered: {
            if(carMoveIndex<24){
                carMoveIndex++
            }
            if(carMovedex===24){
                moveTimer.stop()
            }
        }
    }

    Image {
        id: car_move
        source:qsTr(":/move_%1.png").arg(carMovedex)):   
    }
}

方式二 AnimatedSprite

创建时一次性调入内存,运行时流畅,即使嵌入式设备上

	Component.onCompleted: {
		carMovingAnimated.start()
	}
	
	AnimatedSprite {
		id: carMovingAnimated;
		width: 999;
		height: 397;
		source: ":/modeRoad/car_moving_combine_h.png"
		frameWidth: 999;
		frameHeight: 397;
		frameCount: 25;
		frameRate: 10
		running: false
		frameX: 0;
		frameY: 0;
	}

特别注意 AnimatedSprite 一些属性

1 必须设置 width、height 、 frameWidth 、 frameHeight
2 frameRate : 0 导致浮点运算异常,PC程序退出
3 interpolate:false 默认true 插帧, 帧数>frameCount,false 帧数==frameCount
true开启插帧会导致动画帧数不正确,与设计不匹配,导致掉帧或者闪烁。
正、反播放、或者播放速度在某些数值时候明显掉帧或者闪烁。

动画渲染:Animation 与 Animator 的区别

  • Animation 在主线程运行,主线程卡顿会造成Animation卡顿
  • Animator 在渲染线程运行,主线程卡顿,对动画无影响

代码:


/*
    Animation 和它的派生类运行在GUI线程,卡顿
    Animator  运行在渲染线程,不受主线程卡顿的影响
 */

import QtQuick 2.6
import QtQuick.Window 2.2

Window {
    visible: true
    width: 600
    height: 400

    Rectangle {//--紫色受控Animation,卡顿
        id: rectangle1
        x: 50
        y: 50
        width: 100
        height: 100
        color: "#ff00ff"
    }

    Rectangle {//--黄色,受控Animator,流畅
        id: rectangle2
        x: 50
        y: 250
        width: 100
        height: 100
        color: "#ffff00"
    }

    NumberAnimation {
        id: animation
        target: rectangle1
        property: "x"
        from: 50
        to: 450
        duration: 1000
    }

    XAnimator {
        id: animator
        target: rectangle2
        from: 50
        to: 450
        duration: 1000
    }

    Timer {//--每100毫秒模拟GUI耗时
        id: timer
        interval: 100
        repeat: true
        running: animation.running

        onTriggered: {

            //--模拟主线程耗时任务
            var last = Date.now();
            while (Date.now() - last < 50){

            }
        }
    }

    MouseArea {
        anchors.fill: parent

        onClicked: {
            animation.running = true;
            animator.running = true;
            timer.running = true;
        }
    }
}




效果:

  • 紫色受控Animation,卡顿
  • 黄色,受控Animator,流畅
    关于qml 动画性能问题分析,做流畅动画_第1张图片
    假设 屏幕刷新率60fps, 也就是每一帧 1000ms/60 =16.7ms 刷新一帧,那么200毫秒的动画,Animation 方式会掉帧 200ms/16.7ms = 12帧 ,明显卡顿现象。
    Animator 在渲染线程运行,不受主线程阻塞影响,动画流畅

你可能感兴趣的:(QT/QML)