Repository navigation
Optimize launch speed: fast prefix reuse, bridge staging check, and launcher icon caching - #8
Conversation
| if [ ! -s "$ico" ] && [ ! -f "$absent" ]; then | ||
| url="https://shared.fastly.steamstatic.com/community_assets/images/apps/$app_id/$meta_clienticon.ico" | ||
| code=$(curl -fsL --connect-timeout 5 --max-time 20 -w '%{http_code}' -o "$ico.new" "$url" 2>>"$log") | ||
| code=$(curl -fsL --connect-timeout 2 --max-time 4 -w '%{http_code}' -o "$ico.new" "$url" 2>>"$log" || echo "none") |
There was a problem hiding this comment.
Missing-icon marker is never saved. With || echo "none" appended, a 404 gets recorded as "404none", so the check for "404" never matches. Games with no published icon retry the download on every launch, which can add up to ~4s — the kind of launch delay this PR is trying to remove.
|
|
||
| CX_ROOT="$HOME/Library/Application Support/notproton/runners/current" | ||
| CX_RUNNERS="$HOME/Library/Application Support/notproton/runners" | ||
| CX_ROOT="" |
There was a problem hiding this comment.
Can launch the wrong runner. The app never creates current-rosetta or current-fex, so this always falls through to whichever crossover-* folder find | head -1 returns first. That can be an old, unpatched runner rather than the current one the app set up.
| bundle_needs_build=0 | ||
| if [ ! -d "$loader_app" ] || [ ! -x "$loader_macos/launcher" ] || [ ! -f "$loader_contents/Info.plist" ] || [ ! -e "$loader_macos/wine" ]; then | ||
| bundle_needs_build=1 | ||
| elif ! cmp -s "$WINELOADER" "$loader_macos/wine" 2>/dev/null; then |
There was a problem hiding this comment.
Launcher app settings go stale. Once the per-game launcher app exists, its Info.plist is only rewritten when the wine loader binary changes. If the first launch had no icon, the icon never appears later, and toggling NOTPROTON_HIDE_LAUNCHER_TILE has no effect.
| base=${f##*/} | ||
| case "$base" in | ||
| wine|wine.app) continue ;; | ||
| esac |
There was a problem hiding this comment.
Links can keep pointing into an old runner. When the launcher app is reused, an existing link is left alone if a file with that name already exists. If the runner changes but the loader is byte-identical, the game ends up mixing the old runner's unix libraries with the new runner's DLLs.
| updateBlocks: [URL] = UpdateBlock.paths, | ||
| legacyCompat: URL = SupportPaths.Steam.legacyCompat, | ||
| compatTool: URL = SupportPaths.Steam.compatTool, | ||
| compatToolFex: URL = SupportPaths.Steam.compatToolFex, |
There was a problem hiding this comment.
Tests delete a real folder. compatToolFex defaults to the real ~/Library/Application Support/Steam/compatibilitytools.d/notproton-fex, and the existing UninstallTests don't override it, so running the suite removes that folder on the developer's machine. Suggest passing a temp path in the tests (or removing the default).
| if [ ! -f "$setup_marker" ]; then | ||
| echo "=== first-time prefix initialization ===" >> "$log" 2>&1 || true | ||
| "$WINESERVER" -k >> "$log" 2>&1 || true | ||
| stage_step="profile layout" |
There was a problem hiding this comment.
Saves split between FEX and Rosetta. A new pfx-fex / pfx-rosetta prefix gets a one-time copy of saves from pfx, and nothing copies them back. After switching back, recent progress looks lost, and the app's backup/rebuild options only ever touch pfx. Probably worth deciding whether prefixes should share saves or stay intentionally separate.
|
Follow-up after building and testing locally (arm64 macOS, compared against
1. 2. Swift test "Staging reproduces the bridge the python patcher produced" fails (not in The other 15 Swift failures also fail on |
|
Thanks a lot for the thorough review and great catches, @LaganYT! Really appreciate you taking the time to read through everything so carefully. I've addressed all 6 points in the latest commit:
|
LaganYT
left a comment
There was a problem hiding this comment.
Re-reviewed after 4616f0d, then built and tested locally again.
Fixed: the icon 404 marker; the tests no longer touch the real notproton-fex folder (UninstallTests passes); stale launcher Info.plist / tile settings; stale helper links.
Still open: the Rosetta/FEX runner selection (inline). The two earlier test failures are unchanged: make sigdb-fixtures still fails 5 of 28 (the if (is_live) bad++ change in anchorcheck.c), and the Swift ntdll staging test still fails for the same reason as before. The other Swift failures also happen on main; they need make app-payload.
New: the save-sharing change can permanently delete save progress (inline, reproduced). I'd treat that one as blocking.
| if [ -d "$curr_u/$fold" ] && [ ! -L "$curr_u/$fold" ]; then | ||
| echo "=== merging $fold into base prefix for shared saves ===" >> "$log" 2>&1 || true | ||
| merge_user_dir "$curr_u/$fold" "$main_u/$fold" || true | ||
| rm -rf "$curr_u/$fold" 2>/dev/null || true |
There was a problem hiding this comment.
This can delete save progress. merge_user_dir never overwrites. It skips any file that already exists in the destination, and any subfolder that already exists there (the if [ -n "$rest" ] && [ -e "$dst_dir" ]; then continue check). Its return value is also ignored (|| true), and then this line deletes the source unconditionally.
Reproduced with the functions from this file: base pfx has Saved Games/MyGame/slot1.sav (older), pfx-fex has Saved Games/MyGame/slot1.sav (newer) plus slot2.sav. After share_user_saves, pfx-fex/.../Saved Games is a symlink to the base and the base still holds only the old slot1.sav. The newer slot1.sav and slot2.sav are both gone.
This hits anyone who played under a flavor prefix with the previous commit, and anyone whose game or wineboot later replaces the symlink with a real folder. Suggest only deleting when the merge fully succeeded and nothing was skipped. Otherwise, move the folder aside (e.g. "$fold.notproton-backup") instead of rm -rf, and log it.
| fi | ||
| fi | ||
| else | ||
| if [ -d "$CX_RUNNERS/current/lib/wine/x86_64-unix" ] || [ -d "$CX_RUNNERS/current/lib/wine" ]; then |
There was a problem hiding this comment.
The Rosetta tool still runs the FEX runner when current points to FEX. The FEX CrossOver build also ships lib/wine/x86_64-unix, and the || [ -d .../current/lib/wine ] fallback matches any runner. So both conditions are true for a FEX current. Running this block against a real install where current -> crossover-27.0.0.40921-fex/CrossOver resolves flavor=rosetta to the FEX runner.
The Rosetta check needs to reject a FEX current, e.g. [ -d current/lib/wine/x86_64-unix ] && [ ! -d current/lib/wine/aarch64-unix ], or check the resolved path for a -fex suffix.
| elif [ -d "$CX_RUNNERS/current-rosetta/lib/wine" ]; then | ||
| CX_ROOT="$CX_RUNNERS/current-rosetta" | ||
| else | ||
| rosetta_cand=$(find "$CX_RUNNERS" -maxdepth 3 -type d -name "x86_64-unix" 2>/dev/null | head -1) |
There was a problem hiding this comment.
These new find -maxdepth 3 lookups never match (same for the aarch64-unix one above). The runners are laid out as runners/crossover-<ver>[-fex]/CrossOver/lib/wine/x86_64-unix, which is depth 5, so the search always comes back empty and falls through to the older crossover-* lookup. It's dead code as written. If it were deepened, it would have the same problem as above: the FEX runner has x86_64-unix too.
| esac | ||
| ln -sfn "$f" "$loader_macos/$base" 2>/dev/null || true | ||
| done | ||
| if [ -s "$icon_cache" ] && [ ! -f "$loader_res/game.icns" ]; then |
There was a problem hiding this comment.
Minor: the icon no longer updates when the game's art changes. resolve_icon rebuilds game.icns in $loader_root, but since the plist still has CFBundleIconFile, the bundle isn't rebuilt. This line only copies the file when Resources/game.icns is missing. Before this commit, resolve_icon copied it every time. Copying whenever the source changed (or cmp -s differs) would restore that.
|
The two test failures from my earlier comment (#8 (comment)) still fail on 4616f0d. I re-ran them locally:
Could you take a look at both, or explain if they're expected? |
|
Thanks @Ghostkwebb! I checked 0754eb8: Your comment above describes 4616f0d, and my re-review of that commit (#8 (review)) found that two of those fixes still have problems:
Still waiting on the Swift ntdll staging test ( |
|
Thanks @LaganYT! I’ve pushed
Could you test it now on your side when you get a chance and let me know if everything looks good? |
LaganYT
left a comment
There was a problem hiding this comment.
Re-reviewed 9f7db36, then built and tested it locally.
Verified fixed:
- Save sharing: rerunning my earlier scenario, the newer
slot1.savand the FEX-onlyslot2.savboth end up in the base prefix, and the original is kept as*.notproton-backup-<ts>. Nothing is lost. - Runner selection: against a mock runners folder with both builds, Rosetta →
crossover-27.0.0.40921, and FEX →crossover-27.0.0.40921-fex, whethercurrentpoints to FEX or Rosetta. - Launcher icon: now refreshed when
game.icnsdiffers. - Tests:
make allis clean, allmakechecks pass (includingsigdb-fixtures, 28/28), andsh -npasses. The Swift failures are the same payload-dependent ones as onmain, plus the ntdll staging test. Your explanation (a leftover bridge frommain's FEX pruning, fixed by re-staging) makes sense. I haven't re-staged my real install to confirm it.
Remaining (inline): the new python3 dependency, which I think should be fixed before merge, and a merge that gets stuck on a broken symlink. Minor: the *.notproton-backup-* folders are never cleaned up, and for AppData/Local that can be a lot of disk space.
| mkdir -p "$dst" 2>/dev/null || true | ||
| if [ -d "$src" ] && [ ! -L "$src" ]; then | ||
| echo "=== safely merging $fold into base prefix for shared saves ===" >> "$log" 2>&1 || true | ||
| if python3 - "$src" "$dst" 2>>"$log" <<'PY' |
There was a problem hiding this comment.
New runtime dependency on python3. main's run script never calls Python. On a Mac without the Xcode Command Line Tools (most gamers), /usr/bin/python3 is only a stub: it opens the "install command line developer tools" dialog and exits non-zero. Then the merge fails, the folder is never shared, and because this runs on every launch, the dialog would likely come back each time a game starts.
I'd keep this in POSIX sh (find + cp -p with a [ "$s" -nt "$d" ] check), or check xcode-select -p >/dev/null 2>&1 first and skip the merge (leaving the folder unshared) when the tools aren't installed.
| s = os.path.join(root, f) | ||
| d = os.path.join(target_dir, f) | ||
| try: | ||
| if not os.path.exists(d) or os.path.getmtime(s) >= os.path.getmtime(d): |
There was a problem hiding this comment.
One bad entry blocks sharing for that folder and re-copies it on every launch. A broken symlink anywhere in the tree makes shutil.copy2 raise, so the merge returns 1 and the folder is skipped. It retries, and fails, on every launch, and never gets shared. I reproduced this with one dangling link under AppData/Local.
Because the check is >= and copy2 keeps mtimes, each retry copies every file again, even ones already identical in the base. AppData/Local can hold large shader or engine caches, so that can add launch time.
Suggestions: copy symlinks as links (os.path.islink(s) → os.symlink(os.readlink(s), d), or copy2(..., follow_symlinks=False)) so broken ones don't fail the merge, and use > instead of >=.
|
Oooooh ic ic, completely slipped my mind that macOS throws that CLI tools dialog on clean installs like an idiot XD! I've pushed
Should be all clean now, let me know what you think! |
LaganYT
left a comment
There was a problem hiding this comment.
Re-reviewed dd73919, then built and tested it locally.
Verified:
python3is gone; the merge is plainsh.make allis clean, allmakechecks pass (sigdb-fixtures28/28), andsh -npasses. The Swift results are the same as on 9f7db36.- My earlier save scenarios now work: the newer save and the FEX-only save both reach
pfx, and filenames with leading and trailing spaces survive. A dangling link underAppData/Localno longer blocks the merge, and the folder is now shared.
Remaining (inline): a symlink in the flavor prefix can still overwrite a real save in pfx (reproduced; one-line fix). Minor: the single backup is deleted on a later re-merge.
| target=$(readlink "$rel" 2>/dev/null || true) | ||
| if [ -n "$target" ]; then | ||
| mkdir -p "$(dirname "$_d_root/$rel")" 2>/dev/null || exit 1 | ||
| ln -sfn "$target" "$_d_root/$rel" 2>/dev/null || true |
There was a problem hiding this comment.
A symlink in the flavor prefix overwrites a real save in the base. ln -sfn runs unconditionally, so when pfx already has a real file at the same path, it gets replaced by the link. Regular files use [ ! -e "$d" ] || [ "$s" -nt "$d" ], but symlinks skip that check.
Reproduced: base Documents/G/profile.dat is a real file, and pfx-fex has Documents/G/profile.dat -> /nonexistent/profile.dat. After the merge, the base file is a dangling link, and the .notproton-backup only holds the link, so the save is gone from both prefixes.
Suggest only creating the link when nothing is there: if [ ! -e "$_d_root/$rel" ] && [ ! -L "$_d_root/$rel" ]; then ln -s ...; fi.
| echo "=== safely merging $fold into base prefix for shared saves ===" >> "$log" 2>&1 || true | ||
| if merge_user_tree "$src" "$dst" 2>>"$log"; then | ||
| backup="${src}.notproton-backup" | ||
| [ -e "$backup" ] && rm -rf "$backup" 2>/dev/null || true |
There was a problem hiding this comment.
Minor: this deletes the previous backup the next time the folder is merged, e.g. if a game or wineboot replaces the symlink with a real folder again. That previous backup is the only copy of any file the first merge skipped because the base's copy was newer. I confirmed a second merge of Saved Games replaces the first backup's contents entirely.
Suggest keeping the old backup: merge into it, or fall back to a timestamped name only when .notproton-backup already exists. That still avoids piling up a new copy on every launch.
|
There is good stuff in here. A good chunk of this will come in (though I will make some changes, rewrite stuff). The launch speed improvements - a good chunk of that is great, The handling of FEX specific sections of Steam is good. I won't be bringing in stuff that relates to altering Proton's normal behavior with prefixes/saves without a lot of reverse engineering on my end to match the actual Proton behavior with that. There's other good stuff in here too, but some of the more critical stuff has already been handled in the development code I plan to push to the dev branch tonight. You don't need to spend any time with FEX and the 'runners' until I push - I have changed how that works quite a bit, support for multiple simultaneous versions of CrossOver is in. |
|
The thing is I wanted to play Deadlock with D3DM, so I made changes according to myself without thinking much, as I was doing something randomly till it worked, and thought, 'Why not PR this?' Anyways, I look forward to the development of this project, as the performance in the game seems to be better, as Steam is native and nothing else is taking performance! |
|
Could I get this PR resubmitted with specifically the prefix settings/wine reg changes + the bridge staging copying on every launch + the icon changes but without the other components? I don't want to do the automatic prefix rebuild stuff until I've done a lot more research. That could be very dangerous. I have already dealt with the FEX/Rosetta versions being switchable inside of Steam in the dev branch/in the next update. I am not ready to review the Compatibility UI changes, but I do want those - just in a separate PR. I've played Deadlock against Rosetta CrossOver in the most recent public and the current dev branch without an issue. I'm sorry for the poor communication, i didn't see this PR until fairly late today. |
dd73919 to
327dfb0
Compare
|
Understood! Rebased and scoped the PR strictly to the launch speedups:
Stripped out the runner selection, save sharing, and UI changes to avoid conflicts with your upcoming changes. Does this look good, or did I miss anything? |
There was a problem hiding this comment.
Thanks for rescoping this, @Ghostkwebb, and thanks @NotProtonNot for the context. I'm going through PRs to help keep code quality and reliability up, so I built and tested the new version of this one (327dfb0, now just compat_run.sh + the anchorcheck.c one-liner).
Build/tests (arm64 macOS, compared against origin/main c09e0c4):
make allis clean andsh -npasses. Allmakechecks pass:compatcheck,compatsvc-check,sigcheck,anchorcheck,sigdb-fixtures,peicon-fixtures,webpatch-fixtures,spawn-env,panel-behavior,ntdll-resolve,overlay-shim-tests.- Heads-up for
main:make sigdb-fixturescurrently fails onmain(theif (is_live) bad++change already landed there). Theanchorcheck.cline in this PR fixes it, so that part is worth keeping whatever happens to the rest. - Swift: identical to
main. The same 15 tests fail on both because they need the full app payload (make app-payload). The earlier ntdll staging failure is gone now that the FEX changes are out.
Review: the three pieces NotProton asked for look right. The bridge cmp -s check is a straightforward win, and the 404 marker fix works. I checked one concern and it doesn't hold: CrossOver's wine.inf sets AeDebug\Auto with the NOCLOBBER flag, so a prefix update won't undo the one-time Auto=0. The inline comments are mostly about reliability over time: bundle reuse not noticing template changes, the setup marker being written after a failed init, the lsregister log line, and a question about dropping the per-launch wineserver -k.
Small thing: the PR title and description still describe the original scope (FEX selection, UI changes, prefix sync, "366/366 passing"). Updating them to the three launch-speed changes would make the history clearer.
| chmod +x "$loader_macos/launcher" | ||
| else | ||
| WINELOADER="$loader_macos/wine" | ||
| echo "reusing existing staged bundle (skipped rebuild and lsregister)" >> "$log" 2>&1 || true |
There was a problem hiding this comment.
This log line (and the PR description's "skip … LaunchServices re-registration") doesn't match what happens: lsregister -f "$loader_app" further down (just before open -n -W) still runs unconditionally on every launch. Either gate it on bundle_needs_build = 1 to get that saving, or drop "and lsregister" from the message so the log doesn't mislead anyone debugging a launch.
| echo "launcher tile hidden by NOTPROTON_HIDE_LAUNCHER_TILE" >> "$log" 2>&1 || true | ||
| fi | ||
|
|
||
| bundle_needs_build=0 |
There was a problem hiding this comment.
Bundle reuse doesn't notice template changes. The reuse check covers the wine loader, the icon and LSUIElement, but not the generated launcher script or the rest of Info.plist. If a future NotProton release changes the LAUNCHER heredoc (e.g. the overlay-shim / DYLD_INSERT_LIBRARIES handling) or adds a plist key, existing per-game bundles keep the old versions until the CrossOver loader binary happens to change.
One cheap way to make this reliable: render the plist and launcher into variables (or temp files) first, then rebuild when either differs from what's on disk (cmp -s). Alternatively, write a version stamp into $loader_root and bump it whenever the templates change.
|
|
||
| "$WINELOADER" reg add 'HKLM\Software\Classes\steam' /v 'URL Protocol' /t REG_SZ /d '' /f >> "$log" 2>&1 || true | ||
| "$WINELOADER" reg add 'HKLM\Software\Classes\steam\shell\open\command' /ve /t REG_SZ /d '"C:\Program Files (x86)\Steam\steam.exe" "%1"' /f >> "$log" 2>&1 || true | ||
| : > "$setup_marker" 2>/dev/null || true |
There was a problem hiding this comment.
The setup marker is written even if wineboot --init or the reg add calls failed, since they're all || true. If first-time init fails (e.g. wineboot times out or the runner is broken at that moment), every later launch takes the fast path and the prefix never gets initialized or gets its AeDebug / URL-protocol keys. Suggest only writing the marker when wineboot --init exits 0 (and maybe the reg adds too), so a failed init is retried on the next launch.
|
|
||
| if [ ! -f "$setup_marker" ]; then | ||
| echo "=== first-time prefix initialization ===" >> "$log" 2>&1 || true | ||
| "$WINESERVER" -k >> "$log" 2>&1 || true |
There was a problem hiding this comment.
Question: wineserver -k used to run on every launch and now only runs on first init. Normal exits and the termination trap still run kill_wine_prefix, so this only matters if the run script itself dies hard (Steam crash, force quit, SIGKILL). In that case a leftover wineserver survives to the next launch. That's probably fine with a single runner. But with the multiple simultaneous CrossOver versions @NotProtonNot mentioned, a stale server from a different wine version could give a version-mismatch failure. It might be worth keeping a cheap -k (or a prefix_game_running check) on the fast path.
| if [ ! -s "$ico" ] && [ ! -f "$absent" ]; then | ||
| url="https://shared.fastly.steamstatic.com/community_assets/images/apps/$app_id/$meta_clienticon.ico" | ||
| code=$(curl -fsL --connect-timeout 5 --max-time 20 -w '%{http_code}' -o "$ico.new" "$url" 2>>"$log") | ||
| code=$(curl -sL --connect-timeout 2 --max-time 4 -w '%{http_code}' -o "$ico.new" "$url" 2>>"$log" || echo "none") |
There was a problem hiding this comment.
Minor: the timeouts dropped from 5s/20s to 2s/4s. On a slow connection, a larger .ico may never finish in 4s. Since only a 404 writes the .absent marker, it will retry, and time out, on every launch, adding up to 4s each time. That's still better than 20s, but a slightly longer --max-time (or a short-lived .retry-after marker after a timeout) would avoid paying it forever.
327dfb0 to
70c3b9f
Compare
|
Totally missed the template & lsregister stuff. Just pushed an update addressing all those points, and updated the PR title and description to match the new scope! |
LaganYT
left a comment
There was a problem hiding this comment.
Thanks @Ghostkwebb, nice turnaround. As before, I'm reviewing with an eye on code quality and reliability. I re-reviewed 70c3b9f, then built and tested it (arm64 macOS, against origin/main c09e0c4).
Tests: make all is clean and sh -n passes. All make checks pass, including sigdb-fixtures 28/28, which still fails on main without this PR's anchorcheck.c line. The Swift results are identical to main (the same 15 payload-dependent tests).
Previous points, verified fixed:
wineserver -kruns on every launch again.- The setup marker is only written when init succeeds (but see the inline comment; there's one catch).
- A bundle template version now forces a rebuild, and existing bundles without the stamp rebuild once.
lsregisteronly runs when the bundle is rebuilt or its icon changes.- The icon fetch timeouts are now 3s/8s.
- The title and description match the new scope.
One blocker (inline): on a fresh prefix with Retina off, reg delete RetinaMode exits 1 because the value doesn't exist yet. That marks init as failed on every launch, so the fast path never kicks in for default users. It's a one-line fix. Otherwise this looks good to me.
| if [ "$NOTPROTON_RETINA" = "1" ]; then | ||
| "$WINELOADER" reg add 'HKCU\Software\Wine\Mac Driver' /v RetinaMode /t REG_SZ /d y /f >> "$log" 2>&1 || init_ok=0 | ||
| else | ||
| "$WINELOADER" reg delete 'HKCU\Software\Wine\Mac Driver' /v RetinaMode /f >> "$log" 2>&1 || init_ok=0 |
There was a problem hiding this comment.
This makes the marker check fail for default users, so the fast path never runs. In a fresh prefix RetinaMode doesn't exist yet, and Wine's reg delete returns 1 for a missing value. I checked against the CrossOver 27.0.0.40921 runner in a throwaway prefix:
wineboot --init rc=0
reg delete (value absent) rc=1 reg: Unable to find the specified registry key
reg add RetinaMode rc=0
reg delete (value present) rc=0
With NOTPROTON_RETINA unset (the default), init_ok is always 0 here. The setup marker is never written, and every launch runs the full wineboot --init + reg add path, which removes the launch speedup for most users.
The delete just means "make sure it isn't set", so its failure shouldn't count: keep || true on this line (the fast-path delete below is already fine).
| echo "launcher tile hidden by NOTPROTON_HIDE_LAUNCHER_TILE" >> "$log" 2>&1 || true | ||
| fi | ||
|
|
||
| bundle_template_ver=1 |
There was a problem hiding this comment.
Nit: this only works if whoever edits the PLIST / LAUNCHER heredocs remembers to bump it. A one-line comment here (and ideally next to each heredoc) like # bump when the Info.plist or launcher templates below change would help keep it reliable.
70c3b9f to
024b84a
Compare
|
Is it good now? |
|
I'll be merging (and making changes - but nothing you need to deal with) shortly. I'm chasing down a minor visual bug and then I'll finally start staging pre-release stuff for the next major update. I'll also post some contribution policy stuff and general project maintenance, to avoid issues in the event that the project grows in popularity and contributions. |
|
@NotProtonNot want me to still run a code review? |
I can handle it :D. Thank you, though. I'm at a point where I'm about ready to review on my end. |
|
I'm starting to push to the dev branch. Check this place when I am awake and I'll continue the push, give this a full review and merge |
|
Hello! This functionality is a go for the next major release (1.1.0). I have pushed some early code to the dev branch. Ignore the messy/sloppy commit names for a few of the commits, my IDE screwed me over when I was doing the push. I'll fix it tomorrow. How startup works has improved a lot since you began working on this/when you made the PR. If you are okay with it, I'd like to assign you authorship of the work that I have committed/will be committing that relates to that, as it was inspired by your earlier PR and would not have happened without your PR. I would then continue reviewing and working on the other performance improvement changes you have in this PR. I think the biggest gains are in now, but I have not fully reviewed all of the stuff in this PR to see if there are further gains that would be worth any potential costs. In short: I agree startup can be much faster and avoiding wineboot --init on each startup shaves a lot of time off of launch. The 'don't copy hash-identical files' feature is logical and clean, but the real world gains are near zero. Still, there is no need to replace files when they share the same hash. I'll bring it in for the release. The icon caching and bundle reuse thing is more complicated. There are a lot of complicated edge cases with that one. I don't know that I will keep that functionality in the final shipping update. I'm going to explore it, though. |
|
Yeah, totally cool with assigning authorship; appreciate it! Glad the startup improvements are making it into 1.1.0, and I completely understand being cautious with the icon caching/bundle reuse stuff. Well, maybe the icon caching is not saving that much time, so you can decide. I'm not sure either way XD. Looking forward to the release! |
98b25c7 to
5ca692a
Compare
|
Merged the bulk of the functionality. Thank you :) Happy to revisit the functionality that didn't make it in if you or others find the performance gains to be worth the costs. |
Summary
This PR focuses specifically on launch speed optimizations and test fixture fixes:
wineboot --initand staticreg addcalls on existing prefixes where initial setup has already succeeded, while still dynamically applying runtime toggles like Retina mode.steamclient64.dll, etc.) on every launch usingcmp -s.game.icnson art changes, tracks bundle template versions, and skips redundant bundle recreation and LaunchServices re-registration when unchanged.dylib/tests/anchorcheck.csomake sigdb-fixturespasses.