Skyriding Performance Woes
emptyrivers opened this issue ยท 3 comments
Hello, I've been having severe fps problems in War Within, and today I decided to make use of Perfy in the hopes that I would find a smoking gun. And I did!
Investigation
Here are some reports that Perfy generated for 30s of skyriding in loops around the populated bit of dornogal, near the upgrade npcs and timeways portal:
Of Particular note to me was the DynamicCam:SkyridingOn()
method, which seems to be running for an abnormally large amount of time.
Disabling DynamicCam resulted in a noticeably smoother subjective performance while skyriding, both in and out of Dornogal. For reference, here are some reports of a Perfy run I made, with DynamicCam disabled:
Analysis
Reading the source code, I can see how this happens: the builtin situation controls for situations 103 Mounted (only flying-mount + airborne + Skyriding)
, 104 Mounted (only flying-mount + Skyriding)
, 106 Mounted (only airborne + Skyriding)
, and 107 Mounted (only Skyriding)
(of which I had 106 & 107 enabled in this perf run) all invoke DynamicCam:SkyRidingOn() on PLAYER_MOUNT_DISPLAY_CHANGED
(unlikely to be problematic) and UNIT_AURA
(extremely spammy in heavily populated areas). And DynamicCam:SkyRidingOn()
itself is a potentially quite expensive function to run:
DynamicCam/SituationManager.lua
Lines 989 to 1016 in 6c26720
Contrast this with how WeakAuras detects whether the player is "skyriding", which we've used for 10 months now with no complaints from our users:
Private.IsDragonriding = function ()
return UnitPowerBarID("player") == 631
end
(the relevant events are UNIT_POWER_BAR_SHOW
/UNIT_POWER_BAR_HIDE
/PLAYER_ENTERING_WORLD
)
I believe DynamicCam could benefit a lot from adopting this method of detecting if the player is skyriding.
Experiments
Injecting the line do return UnitPowerBarID("player") == 631 end
at the top of DynamicCam:SkyridingOn() produced the following Perfy report (DynamicCam is on the left again, note its vastly reduced CPU time):
Note the similarity to the above run without DynamicCam enabled.
Editing the situation controls for:
Mounted (only Skyriding)
to use eventsUNIT_POWER_BAR_SHOW, UNIT_POWER_BAR_HIDE
and conditionreturn UnitPowerBarID("player") == 631
Mounted (only airborne + SkyRiding)
to use eventsPLAYER_IS_GLIDING_CHANGED, UNIT_POWER_BAR_SHOW, UNIT_POWER_BAR_HIDE
and conditionreturn IsFlying() and UnitPowerBarID("player") == 631
produced the following Perfy run:
Subjectively, both changes were a marked improvement to flying around in dornogal, and outside dornogal, flying became buttery smooth. Given the crosstalk between SkyridingOn
and CurrentMountCanFly
, I'm not quite sure if the first change would break anything, so I decided to write up all my findings instead of simply doing a drive-by pull request that might not be completely sound.
Great job! Thanks for this elaborate analysis. The skyriding stuff has been a very recent addition to the DynamicCam code. I will definitely check this out and resolve these issues with the next release!
My SkyridingOn() function was in fact bugged such that it had to always traverse the entire mount journal. I fixed this and some further slight performance improvements with release 2.9.0.
I really want to try prefy myself some time, but I just did not have time tonight. Maybe you wanna profile DynamicCam again and let me know the results?
Thanks again!