perf(baseline): time full Draw() handler into LastDrawMs field
This commit is contained in:
+63
-37
@@ -166,6 +166,15 @@ public sealed class Plugin : IAsyncDalamudPlugin
|
|||||||
// because the tick reads it from a different thread than the writer.
|
// because the tick reads it from a different thread than the writer.
|
||||||
private volatile bool _isDisposing;
|
private volatile bool _isDisposing;
|
||||||
|
|
||||||
|
// v1.9.0 B5: last full Draw() wall-time in ms, written once per frame at
|
||||||
|
// the end of the UiBuilder.Draw handler. Covers the GlobalStyleScope push
|
||||||
|
// and the font push (§7.5 First-Frame-HITCH must include atlas/style
|
||||||
|
// prologue cost), not just WindowSystem.Draw — measuring the inner call
|
||||||
|
// alone would drop the prologue and make the figure non-comparable to the
|
||||||
|
// v1.5.6 baseline. Only accumulated here; the disk write happens in
|
||||||
|
// PerformanceBaselineStep so the hot path stays allocation-free.
|
||||||
|
internal double LastDrawMs;
|
||||||
|
|
||||||
internal int DeferredSaveFrames = -1;
|
internal int DeferredSaveFrames = -1;
|
||||||
|
|
||||||
// Cancels the v1.4.8 FTS5 bulk-insert worker on plugin teardown. The
|
// Cancels the v1.4.8 FTS5 bulk-insert worker on plugin teardown. The
|
||||||
@@ -1012,48 +1021,65 @@ public sealed class Plugin : IAsyncDalamudPlugin
|
|||||||
|
|
||||||
private void Draw()
|
private void Draw()
|
||||||
{
|
{
|
||||||
// v1.4.8 B2: pick up external edits of the active custom theme JSON
|
// v1.9.0 B5: time the whole handler (style + font prologue included).
|
||||||
// without forcing the user to re-click the picker. The disk-stat is
|
// Bail before measuring once teardown has begun — a late Draw tick
|
||||||
// 1Hz-throttled inside RefreshActiveIfStale, so this is essentially
|
// must not touch ThemeRegistry / FontManager after DisposeAsync.
|
||||||
// free on built-in themes and ~1 stat/second on custom themes.
|
if (_isDisposing)
|
||||||
ThemeRegistry.RefreshActiveIfStale();
|
|
||||||
|
|
||||||
using IDisposable _style = Ui.StyleEngine.GlobalStyleScope.Push(
|
|
||||||
ThemeRegistry.Active,
|
|
||||||
ThemeRegistry,
|
|
||||||
Config.WindowOpacity
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Config.HideInLoadingScreens && Condition[ConditionFlag.BetweenAreas])
|
|
||||||
{
|
|
||||||
TypingIpc.Update();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Hide all plugin windows while the New Game+ menu is open.
|
var drawWatch = Stopwatch.StartNew();
|
||||||
if (
|
try
|
||||||
Config.HideInNewGamePlusMenu
|
{
|
||||||
&& GameFunctions.GameFunctions.IsAddonInteractable(
|
// v1.4.8 B2: pick up external edits of the active custom theme JSON
|
||||||
GameFunctions.GameFunctions.NewGamePlusAddonName
|
// without forcing the user to re-click the picker. The disk-stat is
|
||||||
|
// 1Hz-throttled inside RefreshActiveIfStale, so this is essentially
|
||||||
|
// free on built-in themes and ~1 stat/second on custom themes.
|
||||||
|
ThemeRegistry.RefreshActiveIfStale();
|
||||||
|
|
||||||
|
using IDisposable _style = Ui.StyleEngine.GlobalStyleScope.Push(
|
||||||
|
ThemeRegistry.Active,
|
||||||
|
ThemeRegistry,
|
||||||
|
Config.WindowOpacity
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Config.HideInLoadingScreens && Condition[ConditionFlag.BetweenAreas])
|
||||||
|
{
|
||||||
|
TypingIpc.Update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide all plugin windows while the New Game+ menu is open.
|
||||||
|
if (
|
||||||
|
Config.HideInNewGamePlusMenu
|
||||||
|
&& GameFunctions.GameFunctions.IsAddonInteractable(
|
||||||
|
GameFunctions.GameFunctions.NewGamePlusAddonName
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
{
|
||||||
{
|
TypingIpc.Update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Interface.UiBuilder.DisableUserUiHide = !Config.HideWhenUiHidden;
|
||||||
|
|
||||||
|
// RegularFont is nullable only because the live rebuild path
|
||||||
|
// disposes it before reassigning; both ends of that swap happen on
|
||||||
|
// this same draw thread, so it cannot be null here.
|
||||||
|
var useRegularFont = Config.FontsEnabled || Config.UseHellionFont;
|
||||||
|
using ((useRegularFont ? FontManager.RegularFont! : FontManager.Axis).Push())
|
||||||
|
WindowSystem.Draw();
|
||||||
|
|
||||||
TypingIpc.Update();
|
TypingIpc.Update();
|
||||||
return;
|
|
||||||
|
FileDialogManager.Draw();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// finally so the early-return frames (loading screen / NG+) record
|
||||||
|
// their (cheap) time too instead of freezing on the last full frame.
|
||||||
|
drawWatch.Stop();
|
||||||
|
LastDrawMs = drawWatch.Elapsed.TotalMilliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
Interface.UiBuilder.DisableUserUiHide = !Config.HideWhenUiHidden;
|
|
||||||
|
|
||||||
// RegularFont is nullable only because the live rebuild path
|
|
||||||
// disposes it before reassigning; both ends of that swap happen on
|
|
||||||
// this same draw thread, so it cannot be null here.
|
|
||||||
var useRegularFont = Config.FontsEnabled || Config.UseHellionFont;
|
|
||||||
using ((useRegularFont ? FontManager.RegularFont! : FontManager.Axis).Push())
|
|
||||||
WindowSystem.Draw();
|
|
||||||
|
|
||||||
TypingIpc.Update();
|
|
||||||
|
|
||||||
FileDialogManager.Draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SaveConfig()
|
internal void SaveConfig()
|
||||||
|
|||||||
Reference in New Issue
Block a user