Skip to content

WineFix: detect whether d2d1 already has the fix before patching it #60

Open

Description

@jfacemyer

Thanks for moving the Direct2D fixes to runtime patches (#40, #47) and dropping the bundled d2d1.dll. We ran into exactly why that matters: the v0.3.0 copy beside Affinity.exe is a Wine 10.18 build, it shadows whatever Wine the user runs, and it's where our copy/paste and resize hangs were spinning. One suggestion, from running current dev on a Wine that already carries these fixes.

Setup. Affinity 3.3.0.4850, Wine 11.18 built with ElementalWarrior's patch set (ryzendew/Affinity-Wine-Builder). That set compiles the same fixes into d2d1: Arecsu's Widen stub, bezier split limit + recursion guard and collinear outline join, and your cubic-to-quadratic subdivision.

What WineFix does there:

Bezier rendering fix installed (ID2D1GeometrySink vtable patched)
Collinear join fix applied at d2d1+0x2CF0F
Widen stub fix installed (ID2D1PathGeometry vtable patched)
Bezier split recursion guard installed at d2d1+0x37A20
[WARNING] Bezier split budget: split_bezier pattern not found in d2d1.dll

So on this build, each fix either goes in a second time on top of the compiled-in one, or its pattern no longer matches because the function was already changed. The miss is harmless here, since the split budget is compiled in (512 splits, 16 per pair). But the same message would appear on a build that genuinely lacks the fix, and there it would mean the hang is back. I also can't tell whether the collinear-join pattern matching at 0x2CF0F is patching code that already carries Arecsu's fix; that seems worth a look.

Suggestion: feature-detect where it's cheap, and make "skipped" distinguishable from "missing":

  • Widen: create a factory and a trivial path geometry at startup and call Widen. Hook only if it returns E_NOTIMPL.
  • Split budget, recursion guard, collinear join: these are harder to probe safely, since a probe could hang. Distinguishing the log outcomes would already help: "pattern found, applied", "pattern not found", and ideally "function already has the guard" if there's a recognisable signature for the patched code.
  • Per-patch auto / on / off in winefix.toml, with auto = probe, or skip on mismatch. Someone on a patched Wine can then turn the native detours off without guessing.
  • Warn at startup if d2d1.dll loads from Affinity's own directory (GetModuleFileName on the d2d1 handle). Anyone upgrading from v0.3.0 still has the old copy there unless their installer removes it, and then every runtime patch lands on the 10.18 code.

Unrelated, FYI: on 3.3.0.4850, Could not find HasPreviousPackageInstalled call to patch is logged before Patched OnMainWindowLoaded. It may be a no-op on 3.3, but it's worth a glance.

Two small PRs are coming separately: keeping libplugins.dll loaded (random crashes, use-after-unload), and quoting AffinityHook's launch arguments by the CommandLineToArgvW rules (trailing backslashes, embedded quotes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions