You are not logged in.

#1 2020-08-04 05:15:49

Nezhul
Member
Registered: 2020-08-04
Posts: 3

AWT native window under Wayland for EGL

Hello.
I'm working on a project as part of a large team, and I am developing a 3d rendering part of that application.\
The application itself is written in Java, using Swing for the interface and layout. It is designed to run on ARM-based devices initially.

The way I do my rendering is I have to render on an AWT Canvas (because it's a heavyweight component). I have to render directly onto it, because going through swing's paint() and BufferedImage pipeline is extremely slow.
The way I do that is through using JAWT to get the Canvas's Native Window, and then use EGL to create a GLES context from it.
It works fine on our base ARM device.

here's a small bit of code without going into much detail:

public static final JAWT awt;
public Component canvas;
private JAWTDrawingSurface ds;
public long display;
private long eglDisplay;

// in Init() method:
        this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
        lock();                     //locks drawing surface
        JAWTDrawingSurfaceInfo dsi = JAWT_DrawingSurface_GetDrawingSurfaceInfo(ds, ds.GetDrawingSurfaceInfo());
        JAWTX11DrawingSurfaceInfo dsiWin = JAWTX11DrawingSurfaceInfo.create(dsi.platformInfo());

        this.display = dsiWin.display();
        this.drawable = dsiWin.drawable();
        eglDisplay = eglGetDisplay(display);

        IntBuffer major = stack.mallocInt(1);
        IntBuffer minor = stack.mallocInt(1);

        if (!eglInitialize(eglDisplay, major, minor))
        {
             throw new IllegalStateException(String.format("-- Failed to initialize EGL [0x%X]", eglGetError()));
        }

        // create context after that

But then, our bosses decided to try a new set of hardware, and the problem here is that this hardware can only use Wayland. There is no way to run X11 on that device.
Now, Swing actually required X11 to run, so it runs through XWayland. But my code doesn't. It produces a segmentation fault during eglInitialize(), because probably I am not getting a correct Native Window / Native Display with my code.
Which makes sense, because XWayland is not the same as X11, and it basically works as a wayland client rather than handling surfaces and drawing calls on its own like X11.
Another problem: JAWT doesn't know how to work with Wayland windowing platform.

So I'm basically at a loss. I don't really know how to make my program work under wayland. How to take an AWT Canvas and somehow create an EGL context from it, to then render directly onto the Canvas surface.
I actually am not even sure if it's possible at all. I've been searching the net high and low for 2 days, trying other API's and researching if I could write some native code that could work, but so far my efforts had resulted in nothing.

Perhaps anyone knows how to do it? I can create EGL from a Wayland native window, but then I don't know how to get it from an AWT canvas.

If you need any additional information, then I will provide it.

Last edited by Nezhul (2020-08-04 05:17:02)

Offline

#2 2020-08-10 05:36:27

Nezhul
Member
Registered: 2020-08-04
Posts: 3

Re: AWT native window under Wayland for EGL

anyone?

Offline

#3 2020-08-10 12:05:13

2ManyDogs
Forum Moderator
Registered: 2012-01-15
Posts: 3,336

Re: AWT native window under Wayland for EGL

Nezhul wrote:

anyone?

Please don't do that.

Offline

#4 2020-08-13 04:25:18

Nezhul
Member
Registered: 2020-08-04
Posts: 3

Re: AWT native window under Wayland for EGL

Ok, so I wrote a small JNI module that obtains the Display directly from wayland rather than Xwayland. it's a one-screen system, so I can get away with obtaining a default system display.
That way I can Initialize EGL without issue. However I can't create the EGL surface from the surface returned by JAWT from Canvas component. I only have XWayland surface on hand, but I need Wayland surface handle (without the X) for this to work.

If anyone knows how I can get a wayland surface through Xwayland surface handle - let me know. For now, it's a partial solution.

JNI module:

package wldisplaylib;

public class WlDisplayJNI
{
    public long getWaylandDisplayHandle()
    {
        return getWaylandDisplayHandleNative();
    }

    public native long getWaylandDisplayHandleNative();
}

Native code is very simple:

#include "wldisplaylib_WlDisplayJNI.h"
#include <wayland-client.h>
#include <wayland-client-core.h>

static struct wl_display *display;

JNIEXPORT jlong JNICALL Java_wldisplaylib_WlDisplayJNI_getWaylandDisplayHandleNative(JNIEnv *env, jobject obj)
{
    dlopen();
	display = wl_display_connect (NULL);
	return (long int)display;
}

Offline

Board footer

Powered by FluxBB