From 715dda9d24630aa389aace7fd872cd22191e0760 Mon Sep 17 00:00:00 2001 From: Moresteck Date: Tue, 15 Oct 2024 11:18:48 +0000 Subject: [PATCH] Impl: OpenGlHelper patch for Intel Graphics driver --- .../betacraft/legacyfix/LegacyFixAgent.java | 1 + .../legacyfix/patch/impl/IntelPatch.java | 83 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 src/main/java/uk/betacraft/legacyfix/patch/impl/IntelPatch.java diff --git a/src/main/java/uk/betacraft/legacyfix/LegacyFixAgent.java b/src/main/java/uk/betacraft/legacyfix/LegacyFixAgent.java index 8b6eb7b..241474c 100644 --- a/src/main/java/uk/betacraft/legacyfix/LegacyFixAgent.java +++ b/src/main/java/uk/betacraft/legacyfix/LegacyFixAgent.java @@ -45,6 +45,7 @@ public static void premain(String agentArgs, final Instrumentation inst) { new BitDepthPatch(), new ClassicPatch(), new GameDirPatch(), + new IntelPatch(), new DeAwtPatch(), new MousePatch(), new VSyncPatch() diff --git a/src/main/java/uk/betacraft/legacyfix/patch/impl/IntelPatch.java b/src/main/java/uk/betacraft/legacyfix/patch/impl/IntelPatch.java new file mode 100644 index 0000000..5aeaf52 --- /dev/null +++ b/src/main/java/uk/betacraft/legacyfix/patch/impl/IntelPatch.java @@ -0,0 +1,83 @@ +package uk.betacraft.legacyfix.patch.impl; + +import javassist.CannotCompileException; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.expr.ExprEditor; +import javassist.expr.MethodCall; +import uk.betacraft.legacyfix.LFLogger; +import uk.betacraft.legacyfix.LegacyFixAgent; +import uk.betacraft.legacyfix.patch.Patch; +import uk.betacraft.legacyfix.patch.PatchException; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.Instrumentation; +import java.lang.reflect.Modifier; +import java.security.ProtectionDomain; + +/** + * Patches OpenGlHelper to fix rendering on Intel graphics (when using performance trick JVM argument) + * Reference + */ +public class IntelPatch extends Patch { + public IntelPatch() { + super("intelpatch", "Patches rendering on Intel", false); + } + + public void apply(final Instrumentation inst) throws PatchException, Exception { + inst.addTransformer(new ClassFileTransformer() { + public byte[] transform(ClassLoader loader, String className, Class classRedefined, ProtectionDomain domain, byte[] classfileBuffer) { + CtClass clas = pool.getOrNull(className.replace("/", ".")); + if (clas == null || clas.getName().startsWith("org.lwjgl") || clas.getDeclaredConstructors().length != 1 || clas.isFrozen()) { + return null; + } + + try { + final boolean[] openGlHelperMatched = new boolean[1]; + for (CtMethod glActiveTextureMethod : clas.getDeclaredMethods()) { + if (!Modifier.isPublic(glActiveTextureMethod.getModifiers()) || + !Modifier.isStatic(glActiveTextureMethod.getModifiers()) || + !"void".equals(glActiveTextureMethod.getReturnType().getName()) || + glActiveTextureMethod.getParameterTypes().length != 1 || + !"int".equals(glActiveTextureMethod.getParameterTypes()[0].getName())) { + continue; + } + + glActiveTextureMethod.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if ("org.lwjgl.opengl.ARBMultitexture".equals(m.getClassName()) && + "glActiveTextureARB".equals(m.getMethodName()) && + "(I)V".equalsIgnoreCase(m.getSignature())) { + openGlHelperMatched[0] = true; + m.replace("{ org.lwjgl.opengl.ARBMultitexture.glClientActiveTextureARB($$); $_ = $proceed($$); }"); + if (LegacyFixAgent.isDebug()) + LFLogger.info("intelpatch", "Matched ARBMultitexture.glActiveTextureARB(I)V"); + + } else if ("org.lwjgl.opengl.GL13".equals(m.getClassName()) && + "glActiveTexture".equals(m.getMethodName()) && + "(I)V".equalsIgnoreCase(m.getSignature())) { + openGlHelperMatched[0] = true; + m.replace("{ org.lwjgl.opengl.GL13.glClientActiveTexture($$); $_ = $proceed($$); }"); + if (LegacyFixAgent.isDebug()) + LFLogger.info("intelpatch", "Matched GL13.glActiveTexture(I)V"); + } + } + }); + + if (openGlHelperMatched[0]) { + if (LegacyFixAgent.isDebug()) + LFLogger.info("intelpatch", "Found OpenGlHelper and patched it: " + clas.getName()); + + inst.removeTransformer(this); // job is done, don't transform any more classes + return clas.toBytecode(); + } + } + } catch (Throwable t) { + LFLogger.error("intelpatch", t); + } + + return null; + } + }); + } +}