perf(ui): gate per-pixel clip compares behind a flags bit (#50)
uiResolveScreenPixel ran four float compares against hdr.clipRectPx for
every pixel of every UI dispatch, even though the clip rect is the
full-surface default {0,0,1e9,1e9} in the overwhelmingly common case.
Reserve the high bit of the header flags word (UI_FLAG_CLIP) and have
FillHeader set it only when the clip rect is narrower than the surface
(extracted into the unit-testable UIRenderer::ClipFlags). The shader
gates the compares on the bit; the branch is push-constant-uniform so it
never diverges. When the rect covers the surface the skipped compares
could never reject an in-surface pixel, so output is pixel-identical.
Mirrored on the WebGPU/WGSL path (dom-webgpu.js) for parity. Adds the
UIClipFlag CPU test covering the gate decision.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c58b68ec40
commit
65c19ea84a
6 changed files with 192 additions and 9 deletions
|
|
@ -38,11 +38,27 @@ UIDispatchHeader UIRenderer::FillHeader(std::uint32_t itemBufferSlot,
|
|||
#else
|
||||
h.frameIdx = 0;
|
||||
#endif
|
||||
h.flags = flags;
|
||||
h.flags = ClipFlags(clipRectPx, window_->width, window_->height, flags);
|
||||
h._pad = 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
std::uint32_t UIRenderer::ClipFlags(std::array<float,4> clipRectPx,
|
||||
std::uint32_t surfaceWidth,
|
||||
std::uint32_t surfaceHeight,
|
||||
std::uint32_t flags) noexcept {
|
||||
// The reserved kUIFlagClip bit signals "clip rect is narrower than the
|
||||
// surface". When the rect already covers the whole surface (the common
|
||||
// {0,0,1e9,1e9} default), the four per-pixel clip compares in
|
||||
// uiResolveScreenPixel can never reject an in-surface pixel, so we leave
|
||||
// the bit clear and the shader skips them — pixel-identical output.
|
||||
const bool clipCoversSurface =
|
||||
clipRectPx[0] <= 0.0f && clipRectPx[1] <= 0.0f
|
||||
&& clipRectPx[0] + clipRectPx[2] >= static_cast<float>(surfaceWidth)
|
||||
&& clipRectPx[1] + clipRectPx[3] >= static_cast<float>(surfaceHeight);
|
||||
return clipCoversSurface ? (flags & ~kUIFlagClip) : (flags | kUIFlagClip);
|
||||
}
|
||||
|
||||
std::uint32_t UIRenderer::ShapeText(Font& font, float pxSize,
|
||||
float x, float baselineY,
|
||||
std::string_view utf8,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue