jcefmaven / jcefbuild

Builds for JCef

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Screenshot not possible with offscreen rendering? - NullPointerException

Osiris-Team opened this issue · comments

Exception in thread "main" java.lang.NullPointerException
	at org.cef.browser.CefBrowserOsr.createScreenshot(CefBrowserOsr.java:474)
	at com.osiris.deskuapp.Main.render(Main.java:42)
	at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.update(Lwjgl3Window.java:387)
	at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.loop(Lwjgl3Application.java:192)
	at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lwjgl3Application.java:166)
	at com.osiris.deskuapp.lwjgl3.Lwjgl3Launcher.createApplication(Lwjgl3Launcher.java:14)
	at com.osiris.deskuapp.lwjgl3.Lwjgl3Launcher.main(Lwjgl3Launcher.java:10)

I am initialiszing with

            builder.getCefSettings().windowless_rendering_enabled = false;

Full code here: https://github.com/Osiris-Team/Desku/blob/6cfead918da72ae333a1785e1043099c3e4c15b9/src/main/java/com/osiris/desku/App.java#L70

Mhmm it doesnt mention offscreen rendering however.
I am also making sure that the window is fully loaded.
But yeah it looks like the same issue.
Sorry forgot that this isn't a library on top of JCEF, but only build scripts, thus can't really be the culprit.

commented

Im not sure how you are creating an osr browser in the first place with windowless rendering disabled. Off screen rendering means that the browser should paint to a GL texture, which will then in turn be rendered to a window by jcef. This means that the browser uses no window (windowless rendering disabled). When using windowless rendering (CefBrowserWr), the browser will render directly to a window by drawing on top of it directly. This is also why some awt apps glitch with Wr, and why Wr performance is way better than osr. But this disables the ability to take screenshots entirely.

You will need to enable windowless rendering when using osr. I currently do not yet understand how you achieved the state you describe :D

Ohh ok got it.
Yeah it seems that I am able to create osr browser with widowless renderer disabled.

Its kind of weird that Wr is a global setting and not provided for each browser...
Guess its bound to the underlying chromium instance that can only run in either of the modes.

commented

Yes, it is kind of weird. Also weird is, that it is essentially accepted twice so the user can reach an invalid state on browser creation. The java implementation should rather read the value from the settings than to accept individual values on browser creation.

Now Im wondering if with my PR I could have Wr disabled and still get rendered images via the osr browser...

Well just tested it with Wr enabled and got the same exception:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.jogamp.opengl.GL.getGL2()" because the return value of "com.jogamp.opengl.awt.GLCanvas.getGL()" is null
	at org.cef.browser.CefBrowserOsr.createScreenshot(CefBrowserOsr.java:474)
	at com.osiris.desku.OffscreenAppTest.main(OffscreenAppTest.java:27)

Guess its actually a bug.

commented

Are you sure that the browser content is loaded? Not only the window but also the page load event needs to succeed before you can obtain any output. This can be misleading.

I am doing this to make sure the content is loaded:

            AtomicBoolean isLoaded = new AtomicBoolean(!browser.isLoading());
            App.cefClient.addLoadHandler(new CefLoadHandlerAdapter() {
                @Override
                public void onLoadEnd(CefBrowser b, CefFrame frame, int httpStatusCode) {
                    if (b == browser) {
                        isLoaded.set(true);
                    }
                }
            });
            // JavaScript cannot be executed before the page is loaded
            while (!isLoaded.get()) Thread.yield();

Calling screenshot() is done later and on the same thread.

commented

I guess this could potentially fail in case of a http error. Apart from that I see no reason why a screenshot would fail. In the link I posted above magreenblatt suggests the use of onLoadingStateChange instead of onLoadEnd. Maybe give this a try?

I changed listeners. Now its listening for onLoadingStateChange and onLoadError.
Also it looks like browser.isLoading() returns always false, which is weird.
Guess thats were the error was.
And it really fixed my nullpointer issue, thanks!

commented

Okay, weird. But glad to hear that things are working out :)

Just found out that the load events are not executed/triggered when Wr = true.

@FriwiDev I give up for today. Can u please see if you can reproduce this:

  1. create cef with windowless render = true
  2. create browser with offscreen render = true
  3. see that not a single load event is triggered
commented

Merging duplicate code is always a good idea. :)

Sorry for not testing your bug above yet, I will do so in the upcoming days but currently I do not have the time to look into it.