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
@Osiris-Team I guess you are referring to this issue? https://magpcss.org/ceforum/viewtopic.php?f=17&t=19295
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.
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.
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.
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.
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!
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:
- create cef with windowless render = true
- create browser with offscreen render = true
- see that not a single load event is triggered
Btw what do you think about this: https://bitbucket.org/chromiumembedded/java-cef/issues/432/retrieve-rendered-image-from-cefbrowserosr#comment-64809278
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.