Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions apps/marketing/src/lib/macArch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { describe, expect, it } from "vite-plus/test";

import { macArchFromGpuRenderer } from "./macArch";

describe("macArchFromGpuRenderer", () => {
it("detects explicit Apple Silicon renderers", () => {
expect(macArchFromGpuRenderer("Apple M4 Pro")).toBe("arm64");
});

it("prefers an Intel GPU marker even when the renderer also mentions Apple", () => {
expect(macArchFromGpuRenderer("ANGLE Metal Renderer: Apple, Intel Iris Plus Graphics")).toBe(
"x64",
);
});

it("uses x64 for ambiguous Safari and unavailable renderer values", () => {
expect(macArchFromGpuRenderer("Apple GPU")).toBe("x64");
expect(macArchFromGpuRenderer("")).toBe("x64");
});
});
16 changes: 16 additions & 0 deletions apps/marketing/src/lib/macArch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const INTEL_GPU_PATTERN = /intel|amd|radeon|nvidia|geforce/i;
const APPLE_SILICON_GPU_PATTERN = /\bapple\s+m\d/i;

export function macArchFromGpuRenderer(renderer: string): "arm64" | "x64" {
if (INTEL_GPU_PATTERN.test(renderer)) {
return "x64";
}
if (APPLE_SILICON_GPU_PATTERN.test(renderer)) {
return "arm64";
}

// Generic "Apple GPU" renderers are ambiguous on Safari. x64 is the safe
// fallback because Apple Silicon can run it through Rosetta, while Intel
// Macs cannot run an arm64 build.
return "x64";
}
21 changes: 20 additions & 1 deletion apps/marketing/src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -391,14 +391,33 @@ const mobileEndorsementRows = [

<script>
import { fetchLatestRelease, RELEASES_URL, type ReleaseAsset } from "../lib/releases";
import { macArchFromGpuRenderer } from "../lib/macArch";

type Platform = { os: "mac" | "win" | "linux"; label: string; arch?: string };

// navigator.userAgent reports "Intel Mac OS X" on both Intel and Apple Silicon
// Macs, so probe the GPU renderer instead: Apple Silicon exposes an "Apple" GPU.
function detectMacArch(): "arm64" | "x64" {
try {
const canvas = document.createElement("canvas");
const gl = (canvas.getContext("webgl") ||
canvas.getContext("experimental-webgl")) as WebGLRenderingContext | null;
const debugInfo = gl?.getExtension("WEBGL_debug_renderer_info");
if (gl && debugInfo) {
const renderer = String(gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) ?? "");
return macArchFromGpuRenderer(renderer);
}
} catch {
// fall through to the default below
}
return macArchFromGpuRenderer("");
}

function detectPlatform(): Platform | null {
const ua = navigator.userAgent;
if (/Win/i.test(ua)) return { os: "win", label: "Download for Windows" };
if (/Mac/i.test(ua)) {
return { os: "mac", label: "Download for macOS", arch: "arm64" };
return { os: "mac", label: "Download for macOS", arch: detectMacArch() };
}
if (/Linux/i.test(ua)) return { os: "linux", label: "Download for Linux" };
return null;
Expand Down
Loading