Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebKit2Gtk 2.46 breaks v86 rendering #1166

Closed
gysddn opened this issue Sep 29, 2024 · 8 comments
Closed

WebKit2Gtk 2.46 breaks v86 rendering #1166

gysddn opened this issue Sep 29, 2024 · 8 comments

Comments

@gysddn
Copy link

gysddn commented Sep 29, 2024

WebKit2Gtk's new release adds a new setting enable-2d-canvas-acceleration and enables it by default, which seems to break the rendering in v86.

OS/Browser: arch/Epiphany
Console: Clean

I am also able to reproduce the error by writing a small C app and load "https://copy.sh/v86":

#include <webkit2/webkit2.h>

static void load_changed(WebKitWebView *web_view, WebKitLoadEvent load_event, gpointer user_data) {
    if (load_event == WEBKIT_LOAD_STARTED) {
        WebKitWebInspector *inspector = webkit_web_view_get_inspector(web_view);
        webkit_web_inspector_show(inspector); // Show Web Inspector as soon as page starts loading
    }
}

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

    // Create a WebKitWebView
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_resize(GTK_WINDOW(window), 600, 600);
    WebKitWebView *web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());

    // Enable developer extras
    WebKitSettings *settings = webkit_web_view_get_settings(web_view);
    webkit_settings_set_enable_developer_extras(settings, TRUE);
    // Uncomment to fix
    //webkit_settings_set_enable_2d_canvas_acceleration(settings, FALSE);

    // Connect load-changed signal
    g_signal_connect(web_view, "load-changed", G_CALLBACK(load_changed), NULL);

    // Load a webpage
    webkit_web_view_load_uri(web_view, "http://copy.sh/v86");

    // Set up the window
    gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(web_view));
    gtk_widget_show_all(window);

    gtk_main();
    return 0;
}
@chschnell
Copy link
Contributor

I don't think you get anything out of GPU hardware acceleration in V86, all it does is write pixels into a RAM buffer which gets copied to the canvas at ~60 fps or more.

There is an option willreadfrequently that can be passed to HTMLCanvasElement.getContext() which is supposed to disable GPU hardware acceleration alltogether:

willReadFrequently: A boolean value that indicates whether or not a lot of read-back operations are planned. This will force the use of a software (instead of hardware accelerated) 2D canvas and can save memory when calling getImageData() frequently.

Browser support for willReadFrequently seems complete, however I don't know a thing about Epiphany.

If you can build your own V86 you'd need to change this line to:

graphic_context = graphic_screen.getContext("2d", { alpha: false, willReadFrequently: true }),

One could argue that this option belongs there anyway.

@chschnell
Copy link
Contributor

chschnell commented Sep 30, 2024

You can now easily test if this option changes anything at my V86 demo site (I patched willReadFrequently in there).

Use Machine -> Boot from the menu to boot into a small FreeDOS image (NOTE: ~15 sec download time for the image) or import any image of your liking using Harddisk -> Import... before booting.

Note that this demo uses the canvas in both text and in graphics mode, so either nothing or all should work with your browser.

@gysddn
Copy link
Author

gysddn commented Sep 30, 2024

Browser support for willReadFrequently seems complete, however I don't know a thing about Epiphany.

It's a Linux browser that uses WebKit/Gtk and that was the issue, I was trying to find why the WebKit that loaded v86 in the GTK app I was debugging suddenly stopped working.

I could get around it with this line:

  webkit_settings_set_enable_2d_canvas_acceleration(settings, FALSE);

But that would mean any app that was embedding WebKit, which is what Gtk+ offers by default, would not render v86 properly.

You can now easily test if this option changes anything at my V86 demo site (I patched willReadFrequently in there).

I just did, and it works perfectly fine, so I guess that does the trick?

But I can't test the other case where willReadFrequently isn't patched becase I can't modify the attributes once the context is created, I believe?

But if you're on Linux, and want to test that case, you can get Epiphany, a.k.a. Gnome Web.

@chschnell
Copy link
Contributor

I just did, and it works perfectly fine, so I guess that does the trick?

Good. I'll see that I include the willReadFrequently patch in my PR #1123, if you can wait a bit it will be fixed at the main site in the next weeks (and not only at my demo site).

@copy
Copy link
Owner

copy commented Sep 30, 2024

This sounds like a bug in WebKit2Gtk. Could you check if this renders correctly: https://copy.sh/bug.html

I don't think you get anything out of GPU hardware acceleration in V86, all it does is write pixels into a RAM buffer which gets copied to the canvas at ~60 fps or more.

There is an option willreadfrequently that can be passed to HTMLCanvasElement.getContext() which is supposed to disable GPU hardware acceleration alltogether:

Note that v86 doesn't read the image data frequently (or at all), and it only sends the region that changed, not the whole buffer. I'm not a graphics expert, but it sounds to me that setting that flag could negatively affect performance.

At the very least, you should turn on paint flashing (found in chromium dev tools: ... -> more tools -> rendering) and check that this doesn't cause more redraws than necessary. There's also an FPS counter in ?profile=solos.

@chschnell
Copy link
Contributor

chschnell commented Oct 1, 2024

This sounds like a bug in WebKit2Gtk. Could you check if this renders correctly: https://copy.sh/bug.html

I don't think you get anything out of GPU hardware acceleration in V86, all it does is write pixels into a RAM buffer which gets copied to the canvas at ~60 fps or more.
There is an option willreadfrequently that can be passed to HTMLCanvasElement.getContext() which is supposed to disable GPU hardware acceleration alltogether:

Note that v86 doesn't read the image data frequently (or at all), and it only sends the region that changed, not the whole buffer. I'm not a graphics expert, but it sounds to me that setting that flag could negatively affect performance.

I agree that it's actually a bug in WebKit2Gtk.

I will not touch this in my PR.

To clarify my reasoning, yes, V86 only sends buffers to the canvas. These buffers are copied from system RAM to GPU RAM using the system bus, and there's really nothing the GPU could do to help us here. V86 doesn't use any of the 2D primitive functions of canvas (like strokeRect(), arc(), etc.) which could potentially be accelerated by the GPU hardware, except for the implementation of ScreenAdapter.make_screenshot() which doesn't really matter in this context.

When looking at the definition of willreadfrequently it sounds like a misnomer to me.

So never mind my earlier post :)

@gysddn
Copy link
Author

gysddn commented Oct 4, 2024

Sorry for being late.

This sounds like a bug in WebKit2Gtk. Could you check if this renders correctly: https://copy.sh/bug.html

This renders normal.

I believe I should report this to WebKit2Gtk as well.

@copy
Copy link
Owner

copy commented Nov 7, 2024

Let's close this, as there seems to be an agreement that this is not a v86 bug.

@copy copy closed this as completed Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants