laserpants / qt-material-widgets

:art: Qt widgets-based implementation of the Material Design specification.
BSD 3-Clause "New" or "Revised" License
3.05k stars 683 forks source link

The effects and shadows are CPU expensive. #36

Open kashyap2690 opened 6 years ago

kashyap2690 commented 6 years ago

If you open the Dialog box in the example application, it eats 20-25% of CPU in core i3!!!

I am using many controls including flatbutton, dialog, drawer, slider, etc in my application, but now the application takes > 25% CPU in just standby mode.

Any workaround to optimize this will be appreciated.

ashraf-kx commented 6 years ago

After i digged a little at details and observations I located that the component "QtMaterialFlatButton" is the responsible to that CPU Consumption. I suspect that the method " QtMaterialFlatButtonStateMachine::eventFilter" is the reason for that endless LOOP. the more flat buttons used the more the cpu usage get higher. Check-Out => class "QtMaterialFlatButton_internal.cpp/ line : 190"

rbaker26 commented 6 years ago

It seems to me it is a "busy wait" for the "close button pushed" event. Where is looping structure that is calling QtMaterialFlatButtonStateMachine::eventFilter defined? I am guessing the reason my simple stack trace is not finding it is because the state machine logic is jumpy by definition.

rbaker26 commented 6 years ago

Here are two different stack traces I did. The first is is the first time the breakpoint on 193 is hit after opening a dialog box. The second is what the stack looks like after the first iteration of the loop calling eventFiller. image

Stack Traces.xlsx

I cannot find any "user-defined" functions that have looping structures in them.
Do you think this loop being executed from a Qt Lib in their QState code?


Here are the two MaterialDesign Functions that are in the first stack trace. image

image

franciszekjuras commented 4 years ago

After some investigation, I noticed, that the halo animation (pulsing animation when button is focused) is causing looping paint events, even if it's not visible at a time. Temporary fix is to comment the line starting the animation:

void QtMaterialFlatButtonStateMachine::startAnimations()
{
    //m_haloAnimation->start();
    start();
}

in qtmaterialflatbutton_internal.cpp. This obviously brakes the halo effect, but apart from that, I haven't experienced any other issues. Focused highlight is still visible though, if one needs it.

I wish it could be addressed properly, unfortunately, I can't figure out how this state machine system exactly works. I know that this project is not actively maintained, but maybe @laserpants would find some time to have a look at this?

zengdapang commented 2 years ago

void QtMaterialRaisedButtonPrivate::init() { Q_Q(QtMaterialRaisedButton);

shadowStateMachine = new QStateMachine(q);
normalState        = new QState;
pressedState       = new QState;
effect             = new QGraphicsDropShadowEffect;

effect->setBlurRadius(7);
effect->setOffset(QPointF(0, 2));
effect->setColor(QColor(0, 0, 0, 75));

q->setBackgroundMode(Qt::OpaqueMode);
q->setMinimumHeight(42);
//q->setGraphicsEffect(effect);
...........................................................
setGraphicsEffect是导致cpu资源暴涨的罪魁祸首,具体原因尚不清楚。
猜测是QGraphicsDropShadowEffect引起的重绘