Skip to content

Commit a91a183

Browse files
committed
fix: correct macOS OpenGL reduced resolution (#566)
1 parent 66fd978 commit a91a183

2 files changed

Lines changed: 57 additions & 4 deletions

File tree

common/src/main/java/me/flashyreese/mods/sodiumextra/client/util/MacReducedResolution.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
import net.minecraft.util.Util;
55

66
public final class MacReducedResolution {
7+
/*
8+
* This branch only has the OpenGL presentation path. On macOS, the reduced
9+
* resolution option is handled by GLFW_COCOA_RETINA_FRAMEBUFFER=false, which
10+
* gives Minecraft a logical-size drawable. Halving Window.framebufferWidth
11+
* and Window.framebufferHeight after that makes a 1440p Retina setup render
12+
* as 720p, so Window's framebuffer fields must not be reduced again.
13+
*/
14+
private static boolean openGlBackend;
15+
716
public static boolean isEnabled() {
817
return Util.getPlatform() == Util.OS.OSX && SodiumExtraClientMod.options().extraSettings.reduceResolutionOnMac;
918
}
@@ -12,7 +21,20 @@ public static int reduce(int value) {
1221
return Math.max(1, value / 2);
1322
}
1423

24+
public static void useOpenGlBackend() {
25+
openGlBackend = true;
26+
}
27+
28+
public static boolean shouldReduceFramebuffer() {
29+
return isEnabled() && !openGlBackend;
30+
}
31+
32+
public static boolean shouldUseWindowSizeForInitialFramebuffer() {
33+
return isEnabled() && openGlBackend;
34+
}
35+
1536
public static boolean shouldScalePresentation(int sourceWidth, int sourceHeight, int targetWidth, int targetHeight) {
37+
// Fallback for any path where the render target and presentation target still disagree.
1638
return isEnabled() && (sourceWidth < targetWidth || sourceHeight < targetHeight);
1739
}
1840
}

common/src/main/java/me/flashyreese/mods/sodiumextra/mixin/reduce_resolution_on_mac/MixinWindow.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
*/
2424
@Mixin(Window.class)
2525
public class MixinWindow {
26+
@Shadow
27+
private int width;
28+
29+
@Shadow
30+
private int height;
31+
2632
@Shadow
2733
private int framebufferWidth;
2834

@@ -32,6 +38,7 @@ public class MixinWindow {
3238
@Redirect(at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwDefaultWindowHints()V"), method = "<init>", remap = false)
3339
private void onDefaultWindowHints() {
3440
GLFW.glfwDefaultWindowHints();
41+
MacReducedResolution.useOpenGlBackend();
3542

3643
if (MacReducedResolution.isEnabled()) {
3744
GLFW.glfwWindowHint(GLFW.GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW.GLFW_FALSE);
@@ -40,21 +47,45 @@ private void onDefaultWindowHints() {
4047

4148
@Inject(at = @At(value = "RETURN"), method = "refreshFramebufferSize")
4249
private void afterUpdateFrameBufferSize(CallbackInfo ci) {
43-
this.scaleFramebufferSize();
50+
this.scaleInitialFramebufferSize();
4451
}
4552

4653
@Inject(method = "onFramebufferResize", at = @At(value = "FIELD", target = "Lcom/mojang/blaze3d/platform/Window;framebufferHeight:I", opcode = Opcodes.PUTFIELD, shift = At.Shift.AFTER))
4754
private void afterFramebufferResize(long handle, int newWidth, int newHeight, CallbackInfo ci) {
4855
this.scaleFramebufferSize();
4956
}
5057

58+
@Unique
59+
private void scaleInitialFramebufferSize() {
60+
/*
61+
* OpenGL only: the Cocoa non-Retina window hint gives us the correct
62+
* reduced drawable, but the first refreshFramebufferSize() during startup
63+
* can leave Minecraft's Window framebuffer fields at the Retina backing
64+
* size. A manual resize fixes it through the normal callback path; pinning
65+
* the initial values to the logical window size avoids the startup-only
66+
* stretched/offset GUI without changing resize behavior.
67+
*/
68+
if (MacReducedResolution.shouldUseWindowSizeForInitialFramebuffer()) {
69+
this.framebufferWidth = Math.max(1, this.width);
70+
this.framebufferHeight = Math.max(1, this.height);
71+
return;
72+
}
73+
74+
this.scaleFramebufferSize();
75+
}
76+
5177
@Unique
5278
private void scaleFramebufferSize() {
53-
if (!MacReducedResolution.isEnabled()) {
79+
/*
80+
* Do not halve on the OpenGL backend. GLFW already returned the reduced
81+
* drawable after GLFW_COCOA_RETINA_FRAMEBUFFER=false, and a second halving
82+
* was confirmed on 26.2 to render 1440p as 720p.
83+
*/
84+
if (!MacReducedResolution.shouldReduceFramebuffer()) {
5485
return;
5586
}
5687

57-
framebufferWidth = MacReducedResolution.reduce(framebufferWidth);
58-
framebufferHeight = MacReducedResolution.reduce(framebufferHeight);
88+
this.framebufferWidth = MacReducedResolution.reduce(this.framebufferWidth);
89+
this.framebufferHeight = MacReducedResolution.reduce(this.framebufferHeight);
5990
}
6091
}

0 commit comments

Comments
 (0)