Debugging and measuring
Seeing what DreamGUI drew and what it cost without a debugger — DreamUI.Capture, DreamUI.Stats and the Insights scopes, stat DreamGUI, DreamGUI.Memory, the two verification switches, the diagnostic commands, the console variables for A/B runs, and the log categories.
Both questions — "what did it draw" and "what did it cost" — can be answered without a debugger.
What it drew: DreamUI.Capture
DreamUI.Capture [Directory]Writes this world's UI as PNG files: one of the viewport, and one of every root canvas that renders into a target.
Without a directory it writes into a new, time-stamped directory under Saved/DreamUI/Captures. A canvas drawn
straight onto the screen has no picture of its own — it is part of the viewport's; capture the viewport.
The same thing is a Blueprint library, UDreamUICaptureLibrary:
| Function | What it does |
|---|---|
CaptureAll | What the console command does: Viewport.png plus <widget name>.png for each root canvas that renders into a target; returns the files written |
SaveViewportToPng | The viewport the world is shown in — the scene with every panel on it, as a player sees it |
SaveCanvasToPng | What a canvas that renders into a target draws |
SaveRenderTargetToPng | A render target's pixels, alpha kept |
GetCaptureDirectory | <Project>/Saved/DreamUI/Captures, which a relative path is taken from |
Every call reads the picture back from the GPU, and so waits for the render thread to finish what it has been given:
a tool for looking, not something to do every frame. Without a GPU (-nullrhi) there is nothing to read; the call
says so in the log and returns false. In a game the viewport is drawn straight into its window and has no texture
between frames, so SaveViewportToPng returns false there and says to use the engine's screenshot request.
What it cost: DreamUI.Stats and Insights
DreamUI.StatsPrints what the frames since the last DreamUI.Stats cost, stage by stage, and starts counting again — so type it
once before and once after the stretch you want to measure.
| Stage | What it is |
|---|---|
ManagerTick | The UI manager's tick |
CanvasUpdate | Canvas updates |
Batching | Batching |
DrawCallSubmit | Draw-call submission |
RenderRecord | The render thread's recording |
Each stage gets milliseconds per frame and a run count. The counters follow, per frame and in all: BatchesRecorded,
VerticesRecorded, SectionUploads, UploadedBytes, DataTextureUpdates, GeometryCopies, SectionReuses,
WidgetsUpdated, SectionPatches, DrawCallRebuilds, InPlaceRefreshes, the render layers' RenderLayerMoves /
Promotions / Demotions, and for text TextPaints, TextMoveRepaints, SmallTextPlacements, SharpenSweepTexts,
SharpenRepaints, CoverageItemsDrawn, CoverageGlyphLookups, CoverageRastersSync, CoverageJobs,
CoverageFlushes and FontAtlasUploadBytes.
In Unreal Insights, each stage is also a named scope starting with DreamUI_ (DreamUI_LayoutPass,
DreamUI_UpdateRootCanvases, DreamUI_TextLayout, DreamUI_RecordScreenSpace, DreamUI_WorldSpaceRaycast, …) on the
CPU channel. The finer scopes that run once per canvas, section or widget are on a channel of their own,
DreamUIDetail, off by default — a wall of thousands of widgets runs them thousands of times, each reading the clock
twice, enough for a traced frame to say little about an untraced one. When you want them:
-trace=default,DreamUIDetail
Trace.Enable DreamUIDetailthe first on the command line, the second at the console.
stat DreamGUI is the plugin's stat group: timings for canvas batching, draw-call updates, geometry updates, vertex
transforms, layout, the property-binding poll and the root-canvas update, and two animation-player counts (players
keeping their own time, players updated by the sequencer).
What it holds: DreamGUI.Memory
DreamGUI.Memory
DreamGUI.Memory Json
DreamGUI.Memory File=<path>Each font's glyph atlas (slices, GPU bytes and the CPU copy, cells, glyphs, face bytes), the sprite atlas pages, and in
every world with a UI manager the canvas meshes' sections and the paint rows. Json prints it as JSON instead;
File= writes the JSON to a file (relative to Saved). The packaged smoke test's probe records its memory report this
way.
The two verification switches
For a report of something drawn wrong or not drawn:
| Variable | When on |
|---|---|
r.DreamUI.VerifyPartialPrepare 1 | Every prepare a canvas makes from its last one (making again only what the widgets that asked, came or moved draw) is checked against a prepare of every widget; a difference is an ensure that names the canvas |
r.DreamUI.VerifyKeptPointers 1 | Each object DreamGUI keeps instead of looking up every frame — a widget's canvas, a canvas's render layers, the UI manager's canvases, an animated property's bound object — is looked up as well where it is used; a disagreement is an ensure that says which |
Both are off by default, because they cost what the shortcuts save (a full prepare, the look-ups). The test host
switches them on in its Config/DefaultEngine.ini, so the whole suite runs under them:
[ConsoleVariables]
r.DreamUI.VerifyPartialPrepare=1
r.DreamUI.VerifyKeptPointers=1The benchmarks (Tools/Bench) switch them off for the sessions they measure. Text's incremental layout has a switch of
the same kind: DreamGUI.Text.VerifyIncremental 1 lays out again from nothing every layout that built on a kept one,
compares the two, logs the first difference and uses the fresh layout.
Diagnostic commands
| Command | What it does |
|---|---|
dreamgui.ListPendingWidgets | Lists widgets created but not yet added to anything (the parked state between ConstructWidget and AddChild), with how long they have been waiting. Holding them in a named array is what stops them being collected; listing them is what stops that becoming a place things quietly pile up |
DreamGUI.Diag.FindTreeBridges | Lists every reference from an object the current world's levels keep (an actor, one of its components or sub-objects) into a DreamGUI widget tree, and whose tree it is. A play session's copy of the level follows such a reference into the tree |
DreamGUI.Text.ShapeCacheFlush | Empties the text shape cache; its counters are kept |
DreamUI.ExportSymbols | Rewrites DUI/.dui-symbols.json (editor); see The VS Code extension |
Tracing variables, which log when on: dreamgui.LayoutTrace 1 (every panel arrange and every rect it commits),
dreamgui.ScrollBoxTrace 1 (every scroll-box drag delta and physics tick that changes state), and
dreamgui.DumpMaterialDraws 1 (which branch each screen-space material draw attempt took, until set back to 0).
Switches for A/B runs
These exist to measure with: side A, switch, side B, in one session. The defaults are the shipped behaviour.
Log categories
| Category | Who writes to it |
|---|---|
DreamGUI | The core, and the input, controls, extensions and samples modules |
LogDreamGUIRenderer | The renderer |
DreamTween | Tweens |
DreamGUIEditor | The designer and asset tools (text compile, write-back, the bridge) |
DreamGUIK2Nodes | The Blueprint nodes |
LogDreamGUIReferenceDocs | The reference-docs commandlet |
Verbosity is set the engine's way: -LogCmds="DreamGUI Verbose" on the command line, or Log DreamGUI Verbose at the
console.
The VS Code extension
Installing DreamGUI Language Support, what it does, where its completion data DUI/.dui-symbols.json comes from, the bridge to the running editor, and its commands and settings.
The automation suite
The plugin's own automation suite (more than 2400 tests in a full run), Invoke-DreamGUITests.ps1 and its presets, the static checks and their rules, the test host project, and the packaged text smoke test of the release gate.