sublime_text icon indicating copy to clipboard operation
sublime_text copied to clipboard

Frame rate is locked at 60 fps

Open LDAP opened this issue 2 years ago • 16 comments

Description of the bug

Sublime Text is running at 60 fps on a 240hz monitor.

>>> sublime.log_fps(True)
fps: 60.9 average: 0ms
fps: 61 average: 1ms
fps: 61 average: 1ms
fps: 61 average: 1ms
fps: 61 average: 1ms
fps: 61 average: 1ms

This can be observed in Wayland as well as in X11.

Steps to reproduce

  1. Make sure a high-refresh rate monitor is connected
  2. Start Sublime Text
  3. Enable fps logging sublime.log_fps(True)
  4. Scroll text

Expected behavior

Sublime Text renders at 240 fps.

Actual behavior

Sublime Text renders at 60 fps.

Sublime Text build number

4147

Operating system & version

6.1.4-arch1-1

(Linux) Desktop environment and/or window manager

Sway (Wayland) / bspwm (X11)

Additional information

  • Sublime Text is running under xdg_shell (Wayland-native)
  • Other applications (e.g. Chromium) render at 240 fps
  • "hardware_acceleration": "opengl"
  • Monitor configuration
 ~ swaymsg -t get_outputs 
Output HDMI-A-1 'Ancor Communications Inc VS248 H2LMQS031073'
  Current mode: 1920x1080 @ 60.000 Hz
  Position: 1920,0
  Scale factor: 1.000000
  Scale filter: nearest
  Subpixel hinting: unknown
  Transform: normal
  Workspace: 2
  Max render time: off
  Adaptive sync: disabled
  Available modes:
    1920x1080 @ 60.000 Hz
    1920x1080 @ 60.000 Hz (16:9)
    1920x1080 @ 59.940 Hz (16:9)
    1920x1080 @ 59.988 Hz
    1920x1080 @ 50.000 Hz (16:9)
    1600x1200 @ 60.000 Hz
    1680x1050 @ 59.883 Hz
    1280x1024 @ 75.025 Hz
    1280x1024 @ 60.020 Hz
    1440x900 @ 59.901 Hz
    1280x960 @ 60.000 Hz
    1366x768 @ 59.790 Hz
    1280x800 @ 60.000 Hz
    1152x864 @ 75.000 Hz
    1280x720 @ 60.000 Hz
    1280x720 @ 60.000 Hz (16:9)
    1280x720 @ 59.940 Hz (16:9)
    1280x720 @ 50.000 Hz (16:9)
    1024x768 @ 75.029 Hz
    1024x768 @ 70.069 Hz
    1024x768 @ 60.004 Hz
    832x624 @ 74.551 Hz
    800x600 @ 75.000 Hz
    800x600 @ 72.188 Hz
    800x600 @ 60.317 Hz
    800x600 @ 56.250 Hz
    720x576 @ 50.000 Hz (4:3)
    720x576 @ 50.000 Hz (16:9)
    720x480 @ 60.000 Hz (4:3)
    720x480 @ 60.000 Hz (16:9)
    720x480 @ 59.940 Hz
    720x480 @ 59.940 Hz (16:9)
    720x480 @ 59.940 Hz (4:3)
    640x480 @ 75.000 Hz
    640x480 @ 72.809 Hz
    640x480 @ 66.667 Hz
    640x480 @ 60.000 Hz (4:3)
    640x480 @ 59.940 Hz
    640x480 @ 59.940 Hz (4:3)
    720x400 @ 70.082 Hz

Output DP-3 'ASUSTek COMPUTER INC VG259QM L4LMQS072375' (focused)
  Current mode: 1920x1080 @ 239.760 Hz
  Position: 0,0
  Scale factor: 1.000000
  Scale filter: nearest
  Subpixel hinting: unknown
  Transform: normal
  Workspace: 1
  Max render time: off
  Adaptive sync: enabled
  Available modes:
    1920x1080 @ 60.000 Hz
    1920x1080 @ 239.760 Hz
    1920x1080 @ 144.001 Hz
    1920x1080 @ 120.028 Hz
    1920x1080 @ 119.982 Hz
    1920x1080 @ 99.924 Hz
    1920x1080 @ 96.015 Hz
    1920x1080 @ 84.935 Hz
    1920x1080 @ 72.017 Hz
    1920x1080 @ 60.002 Hz
    1920x1080 @ 60.000 Hz (16:9)
    1920x1080 @ 59.940 Hz (16:9)
    1920x1080 @ 50.002 Hz
    1920x1080 @ 50.000 Hz (16:9)
    1920x1080 @ 48.007 Hz
    1680x1050 @ 60.000 Hz
    1280x1024 @ 75.025 Hz
    1440x900 @ 60.000 Hz
    1280x800 @ 74.934 Hz
    1280x800 @ 59.810 Hz
    1280x720 @ 74.915 Hz
    1280x720 @ 60.000 Hz
    1280x720 @ 60.000 Hz (16:9)
    1280x720 @ 59.940 Hz (16:9)
    1280x720 @ 50.000 Hz (16:9)
    1440x576 @ 50.000 Hz (4:3)
    1440x576 @ 50.000 Hz (16:9)
    1024x768 @ 75.029 Hz
    1024x768 @ 70.069 Hz
    1024x768 @ 60.004 Hz
    1440x480 @ 60.000 Hz (4:3)
    1440x480 @ 60.000 Hz (16:9)
    1440x480 @ 59.940 Hz (4:3)
    1440x480 @ 59.940 Hz (16:9)
    832x624 @ 74.551 Hz
    800x600 @ 75.000 Hz
    800x600 @ 72.188 Hz
    800x600 @ 60.317 Hz
    800x600 @ 56.250 Hz
    720x576 @ 50.000 Hz (4:3)
    720x576 @ 50.000 Hz (16:9)
    720x480 @ 60.000 Hz (4:3)
    720x480 @ 60.000 Hz (16:9)
    720x480 @ 59.940 Hz (4:3)
    720x480 @ 59.940 Hz (16:9)
    640x480 @ 75.000 Hz
    640x480 @ 66.667 Hz
    640x480 @ 60.000 Hz (4:3)
    640x480 @ 59.940 Hz
    640x480 @ 59.940 Hz (4:3)
    720x400 @ 70.082 Hz

OpenGL context information

OpenGL Context Information:
  GL API Version: 4.6 (Core Profile) Mesa 22.3.3
  GLSL Version: 4.60
  Vendor: AMD
  Renderer: AMD Radeon RX Vega (vega10, LLVM 14.0.6, DRM 3.49, 6.1.4-arch1-1)
startup time: 0.198031
first paint time: 0.232915

LDAP avatar Jan 14 '23 08:01 LDAP

Do other GTK-based apps support the high refresh rate with your mixed setup? We use the standard gtk_widget_add_tick_callback to set up animations to run at vsync.

BenjaminSchaaf avatar Jan 27 '23 05:01 BenjaminSchaaf

Yes. Xournal++ for example works fine.

LDAP avatar Jan 27 '23 10:01 LDAP

X11 doesn't support mixed refresh rate whatsoever - a display (spanning all monitors) has a single refresh rate. GTK3 queries this by using the _NET_WM_FRAME_TIMINGS property. Under Wayland GTK3 uses wl_output_add_listener to get the display refresh rate. GTK3 internally and externally only use gtk_widget_add_tick_callback, and we don't have any internal timers for animations.

The only way I could see this bug happening for only ST and not Xournal++ is if ST is somehow using GTK <3.8 where gtk_widget_add_tick_callback doesn't exist and Xournal++ is using a newer GTK3.

BenjaminSchaaf avatar Jan 31 '23 04:01 BenjaminSchaaf

X11 doesn't support mixed refresh rate whatsoever - a display (spanning all monitors) has a single refresh rate.

I retested with this in mind, and Xournal++ is indeed running at 60 fps using X11. (In Wayland it is working as reported)

The only way I could see this bug happening for only ST and not Xournal++ is if ST is somehow using GTK <3.8

How can I check which version is used? GTK3 version 1:3.24.36-1 is installed and ldd shows Xournal++ using it:

ldd /usr/bin/xournalpp | grep gtk                                                                                                                                                                  
        libgtk-3.so.0 => /usr/lib/libgtk-3.so.0 (0x00007f3426a00000)

However, running ldd on sublime text shows nothing GTK related at all:

ldd /usr/bin/subl                                                                                                                                                                                     
        linux-vdso.so.1 (0x00007ffd7a3bd000)
        librt.so.1 => /usr/lib/librt.so.1 (0x00007f721bcc5000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f721bcc0000)
        libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0x00007f721bc5f000)
        libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0x00007f721aec1000)
        libGL.so.1 => /usr/lib/libGL.so.1 (0x00007f721bbd9000)
        libX11.so.6 => /usr/lib/libX11.so.6 (0x00007f721ad7e000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007f721ac96000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f721bbd2000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f721aaaf000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f721bcfb000)
        libffi.so.8 => /usr/lib/libffi.so.8 (0x00007f721bbc7000)
        libpcre2-8.so.0 => /usr/lib/libpcre2-8.so.0 (0x00007f721aa14000)
        libGLdispatch.so.0 => /usr/lib/libGLdispatch.so.0 (0x00007f721a95c000)
        libGLX.so.0 => /usr/lib/libGLX.so.0 (0x00007f721bb93000)
        libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00007f721a931000)
        libXau.so.6 => /usr/lib/libXau.so.6 (0x00007f721bb8e000)
        libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00007f721bb86000)

ldd /opt/sublime_text/sublime_text                                                                                                                                                                     
        linux-vdso.so.1 (0x00007ffeb55cb000)
        librt.so.1 => /usr/lib/librt.so.1 (0x00007f5cb978f000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f5cb978a000)
        libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0x00007f5cb8b70000)
        libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0x00007f5cb8a31000)
        libGL.so.1 => /usr/lib/libGL.so.1 (0x00007f5cb89ab000)
        libX11.so.6 => /usr/lib/libX11.so.6 (0x00007f5cb8868000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007f5cb8780000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f5cb9783000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f5cb8599000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f5cb9796000)
        libffi.so.8 => /usr/lib/libffi.so.8 (0x00007f5cb9778000)
        libpcre2-8.so.0 => /usr/lib/libpcre2-8.so.0 (0x00007f5cb84fe000)
        libGLdispatch.so.0 => /usr/lib/libGLdispatch.so.0 (0x00007f5cb8446000)
        libGLX.so.0 => /usr/lib/libGLX.so.0 (0x00007f5cb8414000)
        libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00007f5cb83e9000)
        libXau.so.6 => /usr/lib/libXau.so.6 (0x00007f5cb9771000)
        libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00007f5cb83e1000)

Edit: GTK2 2.24.33-2 and GTK4 1:4.8.3-3 are installed as well.

LDAP avatar Jan 31 '23 09:01 LDAP

We dynamically link at runtime, ie. not using the system linker. Are you sure ST only works at 60hz under wayland? Is it perhaps running under xwayland?

BenjaminSchaaf avatar Jan 31 '23 11:01 BenjaminSchaaf

Yes, I am absolutely sure it runs at 60 fps (just retested):

>>> sublime.log_fps(True)
fps: 61 average: 0ms
fps: 61 average: 1ms
fps: 61 average: 1ms
fps: 61 average: 1ms
fps: 61 average: 1ms

As far as I know, xdg_shell means it is running natively (it does also have an app_id instead of a class_id)

swaymsg -t get_tree
#1: root "root"
  #2147483647: output "__i3"
    #2147483646: workspace "__i3_scratch"
  #3: output "DP-3"
    #4: workspace "1"
      #12: con "algo_summary.xopp - Xournal++" (xdg_shell, pid: 3753, app_id: "xournalpp")
      #19: con "Frame rate is locked at 60 fps · Issue #5828 · sublimehq/sublime_text - Chromium" (xdg_shell, pid: 4955, app_id: "chromium")
    #25: workspace "3"
      #26: con "<removed file path> (<removed folder name>) - Sublime Text" (xdg_shell, pid: 15114, app_id: "sublime_text")
  #5: output "HDMI-A-1"
    #6: workspace "2"
      #15: con "(null)"
        #13: con "Vorlesung — Dolphin" (xdg_shell, pid: 3877, app_id: "org.kde.dolphin")
        #24: con "~ : zsh — Konsole" (xdg_shell, pid: 13186, app_id: "org.kde.konsole")
        #14: con "ln.eps  — Okular" (xdg_shell, pid: 3984, app_id: "org.kde.okular")

LDAP avatar Jan 31 '23 12:01 LDAP

If you run both Sublime Text and Xournal++ with the GTK_DEBUG=interactive environment variable set, (GTK_DEBUG=interactive subl if ST isn't running) if you check under the "General" could you share the display information and check that they're the same for both apps?

BenjaminSchaaf avatar Feb 01 '23 01:02 BenjaminSchaaf

Sure.

They are the same, see the attached screenshots. The 60Hz monitor is Monitor 0 maybe that's relevant?

screenshots.zip

LDAP avatar Feb 01 '23 08:02 LDAP

Shot in the dark: do you have more than one window open?

BenjaminSchaaf avatar Feb 13 '23 05:02 BenjaminSchaaf

Shot in the dark: do you have more than one window open?

Of Sublime Text instances? No, only a single instance. (more instances don't seem to change anything)

LDAP avatar Feb 13 '23 07:02 LDAP

I just realized I did not test without HW acceleration and ST restart, so I tested some more:

  • Started ST with 2 Monitors and HW acceleration on ⇾ stable 60 fps
  • Closed ST, disabled the 60 Hz monitor, started ST ⇾ Could not reach even 60 fps (?) (dangled at about 40-50fps and felt very choppy)
  • Disabled HW acceleration, restarted ST ⇾ 240 fps
  • Connected the 60 Hz monitor, restarted ST ⇾ 240 fps

In short: Without HW acceleration, it runs at 240 fps. With HW acceleration sometimes at 60 fps or even below.

So it has definitely something to do with hardware acceleration. I am sorry if I was pointing into the wrong direction before.

Edit: This was tested in a Wayland session.

LDAP avatar Feb 13 '23 11:02 LDAP

That's likely a bug in GTK3 then (and most likely already fixed in GTK4).

BenjaminSchaaf avatar Feb 13 '23 12:02 BenjaminSchaaf

Is there a way to test that?

LDAP avatar Feb 13 '23 12:02 LDAP

The gtk3-demo has an opengl demo.

BenjaminSchaaf avatar Feb 13 '23 12:02 BenjaminSchaaf

Just tested with gtk3-demo and gtk4-demo (using the OpenGL Area) and the GTK4 demo runs indeed way smoother than the GTK3 demo. (So I am guessing GTK3 runs at 60 and GTK4 at 240)

LDAP avatar Feb 13 '23 13:02 LDAP

From my testing GTK3 under Wayland has a bug where it only does 60hz when using OpenGL rendering. GTK3 under XWayland, X11 or when using software rendering under Wayland all render at >60hz.

BenjaminSchaaf avatar Mar 19 '24 06:03 BenjaminSchaaf

Unfortunately, I can confirm that this continues to be a problem as of build 4200 with hardware acceleration enabled, but turning it off fixes the issue. I can observe this problem in other programs that are still using GTK3, notably Firefox (although the web page view is unaffected due to using a custom implementation).

Are there plans to eventually update Sublime Text to use GTK4?

v1993 avatar Oct 22 '25 14:10 v1993

GTK4 is unfortunately not a viable replacement for GTK3 due to this issue: https://gitlab.gnome.org/GNOME/gtk/-/issues/7395.

BenjaminSchaaf avatar Oct 22 '25 15:10 BenjaminSchaaf

I see, that indeed is unfortunate. I take implementing tiling like the drawing programs are described to do is not a feasible solution? It does look like quite a bit of work, especially when dealing with resizing, and I obviously don't know how well it would play with existing architecture, but it seems like using a grid of widgets may work well enough for allowing partial updates; 64x64 chunks make for 527 widgets on a 1080p screen - a lot, but not ridiculously so. Then again, I haven't actually tested this, maybe full redraws become unacceptable.

EDIT: it might also be worth looking at how GTK WebKit handles this; see https://blogs.igalia.com/plampe/introduction-to-damage-propagation-in-wpe-and-gtk-webkit-ports/ and https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.cpp.

v1993 avatar Oct 22 '25 16:10 v1993

Tiling would work, but it's a substantial performance regression. The most basic case of a blinking cursor ends up consuming significantly more resources.

BenjaminSchaaf avatar Oct 23 '25 01:10 BenjaminSchaaf