Skip to content

Image quality degrades in fullscreen games (looks like 1080p downscaled to ~480p) #133

Description

@pwned666

Description

In fullscreen the in-game image looks noticeably worse, as if downscaled (like 1080p shown at ~480p).
Tested on CS2. On Hyprland at 2048x1080 the quality is excellent; on driftwm at 2048x1080 in CS2 it is
clearly worse, with identical in-game settings on both compositors.

This item is not confirmed end-to-end from the code, so please treat it as a question + symptom report
rather than a definitive root cause. If the output scale is 1.0 the logical size equals the native
2048x1080 and the configure is correct, so the culprit is likely elsewhere (no direct scanout, an extra
blit/scale, or a scale/filtering mismatch during composition).

Environment

  • my monitor: 3440x1440
  • driftwm version: git-last
  • disable_direct_scanout value: false (default)
  • GPU / driver: 595.71.05
  • Compared against: Hyprland at 2048x1080, identical in-game settings

Steps to reproduce

  1. Use the same monitor mode (2048x1080) and identical in-game settings on both compositors.
  2. Run CS2 fullscreen on Hyprland — sharp.
  3. Run CS2 fullscreen on driftwm — visibly softer / lower quality.

Expected behavior

Fullscreen renders at the native output resolution, matching Hyprland.

Actual behavior

Fullscreen looks downscaled / blurry compared to Hyprland with the same settings.

Questions for the maintainer

  1. What exact size is sent in enter_fullscreen_configure for a given output — logical (scaled) vs native
    physical — and is fractional scale applied?
  2. Does the fullscreen window actually hit direct scanout, or is it composited / rescaled through GLES?
Code-level findings (verify before relying on these)
  • enter_fullscreen sends the client enter_fullscreen_configure(viewport_size), where
    viewport_size = get_viewport_size() — a logical size.
  • enter_fullscreen_configure (src/window_ext.rs) sets xdg_toplevel::State::Fullscreen and state.size = Some(size).
  • The render path (src/render/mod.rs) uses output.current_scale().fractional_scale() and to_physical_precise_round(scale).
  • Direct scanout for fullscreen is gated by disable_direct_scanout / ALLOW_PRIMARY_PLANE_SCANOUT_ANY
    (src/backend/udev.rs). If the fullscreen buffer is not scanned out directly (unlike Hyprland, which can
    scan out the buffer 1:1), an extra blit/scale step may soften it.
  • Useful to attach: the Backend config: ... disable_direct_scanout=... log line from udev.rs, a run with
    disable_direct_scanout=false, and the output's current_scale().

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions