Jump to content

howto avoid opengl crash and speed up chrome & ms edge browsers


25 posts in this topic

Recommended Posts

This is a lilu plugin that i've made to fix the slow/crashes that i was getting on chrome/edge.

I expect this to work for most graphic cards.

The kext downgrades opengl version to 3.2 and although some apps work it can break others.

 

 

Install on OC/Kexts and reboot.

 

If you have any issues goto browser flags and make shure youre using opengl

other browsers like opera and brave also have this setting by default

 

image.png.15ce61c7968978c4bda731c84400a61e.png

 

this kext might affect other apps that use opengl.

for instance in firefox i had to use this setting (the app just crashes on some pages no matter what)

 

image.png.b872d1d26f24d3b22ad6806a91a5d6ac.png

 

Tested on big sur and ventura. might work on other os releases.

this was build with lilu 1.6.6

 

todo:

- support other os versions

 

updates:

- fixed lilu req (1.6.4+)

- add other os versions patches

- new approach on post #3

 

BFixup.kext.zipBFixup-master.zip

 

Edited by jalavoui
  • 4 weeks later...

this release as a new patch for ventura. other os versions use post #1 approach

 

it is closer to my initial idea to change gl_enable flags code

 

not finished but a step forward

 

side effect on opengl:

- same as post #1

- firefox now won't crash because this release makes it disable webgl. meaning the gfx.webrendersoftware can be disabled

- chrome + related apps slower due to some gl extensions disabled

 

BFixup.kext.zipBFixup-master.zip

 

my fav app with post#1 kext test

image.png.36113cc53203b7a1316ba3e7af49448c.png

 

my fav app with this post kext test:

image.png.8a0b42d4e3473cb035c27ccf4b152f90.png

 

; This function takes four arguments: glVersion, extFlags, arg2, and arg3
; The function uses the registers rsi, rdi, rax, and rcx to store some values
; The function also uses some memory locations pointed by rdi and rsi to access some data
void _gleGetFilteredExtensions(int64_t *glVersion, int32_t *extFlags, int32_t arg2, int32_t arg3)
{
    ; Save the arguments in the registers
    rsi = extFlags
    rdi = glVersion

    ; Check if the 4th bit of the 16-bit value at glVersion + 0xc69e is zero
    ; This seems to be a flag that indicates the OpenGL profile
    ; If it is zero, it means the profile is core or compatibility
    ; If it is one, it means the profile is ES
    if ((*(int16_t *)(glVersion + 0xc69e) & 0xffff & 0x8) == 0x0)
    {
        ; Copy the value at glVersion + 0xb4d8 to rax
        ; This seems to be a pointer to a buffer that stores some flags related to the OpenGL extensions
        rax = *(glVersion + 0xb4d8)

        ; Copy four 32-bit values from the buffer pointed by rax + 0x220 to the memory pointed by extFlags
        ; These seem to be the extension flags for the core or compatibility profile
        rcx = 0x0
        do
        {
            *(int32_t *)(extFlags + rcx * 0x4) = *(int32_t *)(rax + rcx * 0x4 + 0x220)
            rcx = rcx + 0x1
        } while (rcx != 0x4)

        ; Check if the 8-bit value at glVersion + 0xc69d is greater than or equal to 7
        ; This seems to be another flag that indicates the OpenGL version
        ; If it is greater than or equal to 7, it means the version is 4.6 or higher
        ; If it is less than 7, it means the version is lower than 4.6
        if (*(int8_t *)(glVersion + 0xc69d) >= 0x7)
        {
            ; Clear the 4th bit of the 8-bit value at extFlags + 0x8
            ; This seems to be a flag that indicates the support for GL_ARB_gl_spirv extension
            *(int8_t *)(extFlags + 0x8) = *(int8_t *)(extFlags + 0x8) & 0xf7
        }

        ; Check if the 2nd bit of the 16-bit value at glVersion + 0xc69e is one
        ; This seems to be another flag that indicates the OpenGL profile
        ; If it is one, it means the profile is compatibility
        ; If it is zero, it means the profile is core
        if ((*(int16_t *)(glVersion + 0xc69e) & 0xffff & 0x2) != 0x0)
        {
            ; Clear the 1st bit of the 8-bit value at extFlags + 0xd
            ; This seems to be a flag that indicates the support for GL_ARB_compatibility extension
            *(int8_t *)(extFlags + 0xd) = *(int8_t *)(extFlags + 0xd) & 0xfe
        }
    }
    else
    {
        ; Set the value at extFlags + 0x4 to 0x30000001000000
        ; This seems to be a flag that indicates the support for GL_OES_texture_3D extension
        *(extFlags + 0x4) = 0x30000001000000

        ; Set the value at extFlags + 0xc to 0x10000000
        ; This seems to be a flag that indicates the support for GL_OES_element_index_uint extension
        *(int32_t *)(extFlags + 0xc) = 0x10000000

        ; Check if the 8-bit value at glVersion + 0xc69d is less than or equal to 6
        ; This seems to be another flag that indicates the OpenGL version
        ; If it is less than or equal to 6, it means the version is 3.2 or lower
        ; If it is greater than 6, it means the version is higher than 3.2
        if (*(int8_t *)(glVersion + 0xc69d) <= 0x6)
        {
            ; Set the value at extFlags + 0x8 to 0x300008
            ; This seems to be a flag that indicates the support for GL_OES_texture_npot and GL_OES_vertex_array_object extensions
            *(int32_t *)(extFlags + 0x8) = 0x300008
        }

        ; Set the value at extFlags to 0x1300000
        ; This seems to be a flag that indicates the support for GL_OES_rgb8_rgba8, GL_OES_depth24, and GL_OES_depth_texture extensions
        *(int32_t *)extFlags = 0x1300000

        ; Copy the value at glVersion + 0xb4d8 to rax
        ; This seems to be a pointer to a buffer that stores some flags related to the OpenGL extensions
        rax = *(glVersion + 0xb4d8)

        ; Perform a bitwise AND operation between the value at extFlags and the value at rax + 0x220, and store the result at extFlags
        ; This seems to be a way to filter out the extensions that are not supported by the ES profile
        *(int32_t *)extFlags = 0x1300000 & *(int32_t *)(rax + 0x220)

        ; Perform a bitwise AND operation between the values at extFlags + 0x4, extFlags + 0x8, and extFlags + 0xc and the values at rax + 0x224, rax + 0x228, and rax + 0x22c, respectively, and store the results at extFlags + 0x4, extFlags + 0x8, and extFlags + 0xc
        ; This seems to be another way to filter out the extensions that are not supported by the ES profile
        rcx = 0x0
        do
        {
            *(int32_t *)(extFlags + rcx * 0x4 + 0x4) = *(int32_t *)(extFlags + rcx * 0x4 + 0x4) & *(int32_t *)(rax + rcx * 0x4 + 0x224)
            rcx = rcx + 0x1
        } while (rcx != 0x3)
    }

    ; Return from the function
    return
}

 

Edited by jalavoui
  • Thanks 1
  • 2 weeks later...
On 11/29/2023 at 5:00 AM, jalavoui said:

This is a lilu plugin that i've made to fix the slow/crashes that i was getting on chrome/edge.

I expect this to work for most graphic cards.

The kext downgrades opengl version to 3.2 and although some apps work it can break others.

 

 

Install on OC/Kexts and reboot.

 

If you have any issues goto browser flags and make shure youre using opengl

other browsers like opera and brave also have this setting by default

 

image.png.15ce61c7968978c4bda731c84400a61e.png

 

this kext might affect other apps that use opengl.

for instance in firefox i had to use this setting (the app just crashes on some pages no matter what)

 

image.png.b872d1d26f24d3b22ad6806a91a5d6ac.png

 

Tested on big sur and ventura. might work on other os releases.

this was build with lilu 1.6.6

 

todo:

- support other os versions

 

updates:

- fixed lilu req (1.6.4+)

- add other os versions patches

- new approach on post #3

 

BFixup.kext.zip 11.62 kB · 0 downloads BFixup-master.zip 32.03 kB · 0 downloads

 

Is this usable for Monterey too?

there's a monterey patch for testing on #1 post but idk if it will work.

 

if you have latest monterey i could use the correct GLEngine file to check the patch

 

can you can go here and attach it ?

 

  • 3 weeks later...
On 1/10/2024 at 1:04 AM, jalavoui said:

there's a monterey patch for testing on #1 post but idk if it will work.

 

if you have latest monterey i could use the correct GLEngine file to check the patch

 

can you can go here and attach it ?

 

Hi hello, sorry for the really late reply. I just ran this from my system and it didn't work... any specific steps would be appreciated, thank you

Screen Shot 2024-01-30 at 22.02.06.png

Edited by vanmoo
  • 1 month later...
  • 1 month later...
  • 5 weeks later...
On 5/14/2024 at 8:17 AM, jalavoui said:

latest sonoma might changed patched bytes

the patch is easy so if someone wanna send it i can update the kext

i'm not using sonoma atm


/**
 * Sonoma
 *
 * 8B 55 E0 89 D0 F7 D0 A9 01 00 04 48 0F 85 A1 00 00 00
 */
static const uint8_t kSonomaAddrLibGetBaseArrayModeReturnOriginal[] = {
    0x8B, 0x55, 0xE0, 0x89, 0xD0, 0xF7, 0xD0, 0xA9, 0x01, 0x00, 0x04, 0x48, 0x0F, 0x85, 0xA1, 0x00, 0x00, 0x00,
};
static const uint8_t kSonomaAddrLibGetBaseArrayModeReturnPatched[] = {
    0x8B, 0x55, 0xE0, 0x89, 0xD0, 0xF7, 0xD0, 0xA9, 0x01, 0x00, 0x04, 0x48, 0xE9, 0xA2, 0x00, 0x00, 0x00, 0x90,
};

/**
 * Sequoia
 * 83 48 C6 00 00 34 EB 60 8B 4D E0 F7 D1 F7 C1 01 00 04 48 75 45
 */
static const uint8_t kSequoiaAddrLibGetBaseArrayModeReturnOriginal[] = {
	0x83, 0x48, 0xC6, 0x00, 0x00, 0x34, 0xEB, 0x60, 0x8B, 0x4D, 0xE0, 0xF7, 0xD1, 0xF7, 0xC1, 0x01, 0x00, 0x04, 0x48, 0x75, 0x45,
};
static const uint8_t kSequoiaAddrLibGetBaseArrayModeReturnPatched[] = {
	0x83, 0x48, 0xC6, 0x00, 0x00, 0x34, 0xEB, 0x60, 0x8B, 0x4D, 0xE0, 0xF7, 0xD1, 0xF7, 0xC1, 0x01, 0x00, 0x04, 0x48, 0xEB, 0x45
};

 

tks

so i build it with Sequoia patch but also added new kernelsdk and lilu

 

worked wth old lilu and new lilu github version

 

BFixup.kext.zipLilu.kext.zip

 

here's the source with dependencies used

BFixup-master.zip

  • Like 2
  • Thanks 1
  • 4 months later...

yes that was my idea when i started.

i suspect of opengl/metal bundles but idk if they can be patched without breaking the seal

but looking at other "apple" cards they seem to enable those gl functions + others. so the issue can be that there's some validation of the card and the needed functions are just disabled and we get all sort of opengl errors

 

if you lucky maybe patching /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine does the trick

Edited by jalavoui
  • Like 1
  • 11 months later...

Chrome decided to remove render flag that allows change to opengl

 

but from logs

 

Capturadeecra2025-10-03as13_36_42.png.219fca2d7accb0ead84508d626514c20.png

 

This mean it still can be done but only from terminal by using this command

 

Capturadeecra2025-10-03as13_37_08.png.e93038477e37aefa9ed776285e7488a2.png

 

the default hw encode/decode flags can still be disabled if any issues as some gpus dont support hw decoding.

 

gpu settings look like this

Capturadeecra2025-10-03as13_47_36.png.5f7f04d0c68b9ff12c482c066e3eefbb.png

 

oclp as a script for this issue

https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1145

as long as this apps keep working with --args --use-angle=gl 

Edited by jalavoui

there's a way to change gl version to 3.3 or higher. 

setting to 3.3 keep firefox happy but hangs chrome, discord, etc when using --use-angle=gl flag

patch is in source code. to change from 3.2 to 3.3 set last byte to 0x33 (ventura)

this will allow more gl extensions to be enabled and keep some apps happy while crashing others.

as far as i tested using the gl flag with gl version > 3.2 will crash chrome but idk how this will work on other os x versions.

 

image.png.bc32de97f786bcf3d181db3e9979cc56.png

 

BFixup-master.zip

 

this is the patched function where u can see other possible values for minor/major gl version

int _gleDeriveVersion(int arg0) {
    rbx = arg0;
    rax = _gleGetFilteredExtensions(arg0, &var_20, rdx, rcx);
    *(int8_t *)(rbx + 0xc647) = 0x2e;
    *(int8_t *)(rbx + 0xc649) = 0x0;
    rax = *(int8_t *)(rbx + 0xc6a6);
    if (rax != 0x1) {
            if (rax == 0x0) {
                    rax = var_20;
                    if (!COND) {
                            rdx = var_1C;
                            if (!COND) {
                                    rcx = var_18;
                                    if (!COND) {
                                            *(int8_t *)(rbx + 0xc646) = 0x31;
                                            *(int8_t *)(rbx + 0xc648) = 0x34;
                                    }
                                    else {
                                            if ((!rax & 0x2002080) == 0x0) {
                                                    rsi = rdx & 0x4000;
                                                    if (rsi != 0x0 && rdx < 0x0) {
                                                            COND = *(int16_t *)(*(rbx + 0xb4d8) + 0x9a) > 0x1;
                                                            if (!COND) {
                                                                    *(int8_t *)(rbx + 0xc646) = 0x31;
                                                                    *(int8_t *)(rbx + 0xc648) = 0x35;
                                                            }
                                                            else {
                                                                    *(int8_t *)(rbx + 0xc646) = 0x32;
                                                                    if (!COND) {
                                                                            rcx = rcx & 0x20000000;
                                                                            if (rcx != 0x0) {
                                                                                    *(int8_t *)(rbx + 0xc648) = 0x31;
                                                                            }
                                                                            else {
                                                                                    *(int8_t *)(rbx + 0xc648) = 0x30;
                                                                            }
                                                                    }
                                                                    else {
                                                                            *(int8_t *)(rbx + 0xc648) = 0x30;
                                                                    }
                                                            }
                                                    }
                                                    else {
                                                            *(int8_t *)(rbx + 0xc646) = 0x31;
                                                            *(int8_t *)(rbx + 0xc648) = 0x35;
                                                    }
                                            }
                                            else {
                                                    *(int8_t *)(rbx + 0xc646) = 0x31;
                                                    *(int8_t *)(rbx + 0xc648) = 0x35;
                                            }
                                    }
                            }
                            else {
                                    *(int8_t *)(rbx + 0xc646) = 0x31;
                                    *(int8_t *)(rbx + 0xc648) = 0x34;
                            }
                    }
                    else {
                            *(int8_t *)(rbx + 0xc646) = 0x31;
                            *(int8_t *)(rbx + 0xc648) = 0x34;
                    }
            }
    }
    else {
            TEST(!var_20 & 0x48040001);
            *(int8_t *)(rbx + 0xc646) = 0x33;
            *(int8_t *)(rbx + 0xc648) = 0x32;
    }
    var_10 = **0x7ffa41f0ac30;
    rax = *0x7ffa41f0ac30;
    rax = *rax;
    if (rax != var_10) {
            __stack_chk_fail();
    }
    return rax;
}
typedef struct {
    // ... other fields ...
    char version_major;   // Offset 0xc646
    char dot;             // Offset 0xc647
    char version_minor;   // Offset 0xc648
    char null_term;       // Offset 0xc649
    char flag_c6a6;       // Offset 0xc6a6
    void* ptr_b4d8;       // Offset 0xb4d8
    // ... other fields ...
} MyStruct;

int _gleDeriveVersion(MyStruct* s) {
    int var_20, var_1C, var_18;
    int ret = _gleGetFilteredExtensions(s, &var_20, &var_1C, &var_18);

    // Set dot and null terminator
    s->dot = '.';
    s->null_term = '\0';

    // Check flag at offset 0xc6a6
    if (s->flag_c6a6 != 1) {
        if (s->flag_c6a6 == 0) {
            int val = var_20;
            // Placeholder for unknown conditions (cond1, cond2, cond3, cond5)
            if (cond1) {
                int rdx = var_1C;
                if (cond2) {
                    int rcx = var_18;
                    if (cond3) {
                        s->version_major = '1';
                        s->version_minor = '4';
                    } else {
                        if ((val & 0x2002080) == 0) {
                            if ((rdx & 0x4000) && (rdx < 0)) {
                                // Access nested structure via ptr_b4d8
                                uint16_t* nested_ptr = *(uint16_t**)((char*)s->ptr_b4d8 + 0x9a);
                                if (*nested_ptr > 1) {
                                    s->version_major = '2';
                                    if (cond5) {
                                        s->version_minor = (rcx & 0x20000000) ? '1' : '0';
                                    } else {
                                        s->version_minor = '0';
                                    }
                                } else {
                                    s->version_major = '1';
                                    s->version_minor = '5';
                                }
                            } else {
                                s->version_major = '1';
                                s->version_minor = '5';
                            }
                        } else {
                            s->version_major = '1';
                            s->version_minor = '5';
                        }
                    }
                } else {
                    s->version_major = '1';
                    s->version_minor = '4';
                }
            } else {
                s->version_major = '1';
                s->version_minor = '4';
            }
        }
    } else {
        s->version_major = '3';
        s->version_minor = '2';
    }

    // Stack canary check (simplified)
    if (stack_canary_check_failed()) {
        __stack_chk_fail();
    }
    return ret;
}

 

Edited by jalavoui

just added a automator script to run chrome with flag instead of calling from terminal.

use  text edit to change this line to other app if need (discord,etc)

 

image.png.00c2c1d9fb0801aa3f5c2bfceb923521.png

 

chromer.zip

 

here's the msedge script

msedge.zip

Edited by jalavoui
  • Like 1
  • 3 months later...

chrome does act like a virus. it ignores mac os settings and loves to create a file in home folder for Library/LaunchAgents/com.google.GoogleUpdater.wake.plist

 

only way that works to prevent this is change permissions to read only in /Library/Application\ Support/Google/GoogleUpdater and in same folder for /users

 

Side effect: as chrome can no longer update it is now a very fast browser

 

ty google

Edited by jalavoui
  • Like 2
  • 2 weeks later...

Hi @jalavoui

Thank you for this great project. I found your topic today. So, Iitried building from the latest source you uploaded above. However, I'm getting a kernel panic on boot. It shơ that kext conflicting with Lilu.kext (no other kext). I'm using Laptop AMD Ryzen 9-5900HX with Radeon Vega 8 (Nootedred.kext) and Sequoia 15.5 installed. I don't know what the problem is. I only see the log show kernel panic come from Lilu and BFixup, so I'm not sure what's causing the conflict.
 

Edited by hoaug
  • 3 weeks later...
  • 2 months later...
×
×
  • Create New...