You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
libandroid/native_window.c: make Vulkan work, add refcount
This commit is contained in:
@@ -56,7 +56,7 @@ libandroid_so = shared_library('android', [
|
|||||||
install: true,
|
install: true,
|
||||||
soversion: 0,
|
soversion: 0,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('gtk4'), dependency('jni')
|
dependency('gtk4'), dependency('jni'), dependency('vulkan')
|
||||||
])
|
])
|
||||||
|
|
||||||
libtranslationlayer_so = shared_library('translation_layer_main', [
|
libtranslationlayer_so = shared_library('translation_layer_main', [
|
||||||
@@ -103,7 +103,8 @@ libtranslationlayer_so = shared_library('translation_layer_main', [
|
|||||||
install: true,
|
install: true,
|
||||||
install_dir : get_option('libdir') / 'java/dex/android_translation_layer/natives',
|
install_dir : get_option('libdir') / 'java/dex/android_translation_layer/natives',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('gtk4'), dependency('gl'), dependency('egl'), dependency('wayland-client'), dependency('jni'), dependency('libportal'), dependency('sqlite3'), libskia_dep
|
dependency('gtk4'), dependency('gl'), dependency('egl'), dependency('wayland-client'), dependency('jni'),
|
||||||
|
dependency('libportal'), dependency('sqlite3'), libskia_dep
|
||||||
],
|
],
|
||||||
link_with: [ libandroid_so ],
|
link_with: [ libandroid_so ],
|
||||||
link_args: [
|
link_args: [
|
||||||
|
|||||||
@@ -37,6 +37,10 @@
|
|||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <wayland-egl.h>
|
#include <wayland-egl.h>
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
#include <vulkan/vulkan_android.h>
|
||||||
|
#include <vulkan/vulkan_wayland.h>
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gdk/wayland/gdkwayland.h>
|
#include <gdk/wayland/gdkwayland.h>
|
||||||
|
|
||||||
@@ -74,6 +78,10 @@ enum ANativeWindowTransform {
|
|||||||
struct ANativeWindow {
|
struct ANativeWindow {
|
||||||
EGLNativeWindowType egl_window;
|
EGLNativeWindowType egl_window;
|
||||||
GtkWidget *surface_view_widget;
|
GtkWidget *surface_view_widget;
|
||||||
|
struct wl_display *wayland_display;
|
||||||
|
struct wl_surface *wayland_surface;
|
||||||
|
gulong resize_handler;
|
||||||
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,12 +123,18 @@ typedef struct ANativeWindow_Buffer {
|
|||||||
*/
|
*/
|
||||||
void ANativeWindow_acquire(struct ANativeWindow *native_window)
|
void ANativeWindow_acquire(struct ANativeWindow *native_window)
|
||||||
{
|
{
|
||||||
// FIXME: refcount
|
native_window->refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ANativeWindow_release(struct ANativeWindow *native_window)
|
void ANativeWindow_release(struct ANativeWindow *native_window)
|
||||||
{
|
{
|
||||||
// FIXME: refcount
|
native_window->refcount--;
|
||||||
|
if(native_window->refcount == 0) {
|
||||||
|
g_clear_signal_handler(&native_window->resize_handler, native_window->surface_view_widget);
|
||||||
|
wl_egl_window_destroy((struct wl_egl_window *)native_window->egl_window);
|
||||||
|
wl_surface_destroy(native_window->wayland_surface);
|
||||||
|
free(native_window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ANativeWindow_getWidth(struct ANativeWindow *native_window)
|
int32_t ANativeWindow_getWidth(struct ANativeWindow *native_window)
|
||||||
@@ -229,7 +243,7 @@ void wl_registry_global_remove_handler(void *data, struct wl_registry *registry,
|
|||||||
// TODO: handle X11
|
// TODO: handle X11
|
||||||
static void on_resize(GtkWidget* self, gint width, gint height, struct wl_egl_window *egl_window)
|
static void on_resize(GtkWidget* self, gint width, gint height, struct wl_egl_window *egl_window)
|
||||||
{
|
{
|
||||||
wl_egl_window_resize(egl_window, width, height, 0, 0);
|
wl_egl_window_resize(egl_window, width, height, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ANativeWindow * ANativeWindow_fromSurface(JNIEnv* env, jobject surface)
|
ANativeWindow * ANativeWindow_fromSurface(JNIEnv* env, jobject surface)
|
||||||
@@ -242,6 +256,12 @@ ANativeWindow * ANativeWindow_fromSurface(JNIEnv* env, jobject surface)
|
|||||||
double off_x;
|
double off_x;
|
||||||
double off_y;
|
double off_y;
|
||||||
|
|
||||||
|
static struct wl_subcompositor *wl_subcompositor = NULL;
|
||||||
|
static struct wl_registry_listener wl_registry_listener = {
|
||||||
|
.global = wl_registry_global_handler,
|
||||||
|
.global_remove = wl_registry_global_remove_handler
|
||||||
|
};
|
||||||
|
|
||||||
GtkWidget *surface_view_widget = _PTR(_GET_LONG_FIELD(surface, "widget"));
|
GtkWidget *surface_view_widget = _PTR(_GET_LONG_FIELD(surface, "widget"));
|
||||||
GtkWidget *window = GTK_WIDGET(gtk_widget_get_native(surface_view_widget));
|
GtkWidget *window = GTK_WIDGET(gtk_widget_get_native(surface_view_widget));
|
||||||
while( (width = gtk_widget_get_width(surface_view_widget)) == 0 ) {
|
while( (width = gtk_widget_get_width(surface_view_widget)) == 0 ) {
|
||||||
@@ -262,6 +282,7 @@ ANativeWindow * ANativeWindow_fromSurface(JNIEnv* env, jobject surface)
|
|||||||
printf("XXXXX: native offset: x: %lf, y: %lf\n", off_x, off_y);
|
printf("XXXXX: native offset: x: %lf, y: %lf\n", off_x, off_y);
|
||||||
|
|
||||||
struct ANativeWindow *native_window = malloc(sizeof(struct ANativeWindow));
|
struct ANativeWindow *native_window = malloc(sizeof(struct ANativeWindow));
|
||||||
|
native_window->refcount = 1; // probably, 0 doesn't work
|
||||||
native_window->surface_view_widget = surface_view_widget;
|
native_window->surface_view_widget = surface_view_widget;
|
||||||
|
|
||||||
GdkDisplay *display = gtk_root_get_display(GTK_ROOT(window));
|
GdkDisplay *display = gtk_root_get_display(GTK_ROOT(window));
|
||||||
@@ -270,15 +291,12 @@ ANativeWindow * ANativeWindow_fromSurface(JNIEnv* env, jobject surface)
|
|||||||
struct wl_display *wl_display = gdk_wayland_display_get_wl_display(display);
|
struct wl_display *wl_display = gdk_wayland_display_get_wl_display(display);
|
||||||
struct wl_compositor *wl_compositor = gdk_wayland_display_get_wl_compositor(display);
|
struct wl_compositor *wl_compositor = gdk_wayland_display_get_wl_compositor(display);
|
||||||
|
|
||||||
struct wl_registry *wl_registry = wl_display_get_registry(wl_display);
|
if(!wl_subcompositor) { // FIXME this assumes the wl_display doesn't change
|
||||||
struct wl_registry_listener wl_registry_listener = {
|
struct wl_registry *wl_registry = wl_display_get_registry(wl_display);
|
||||||
.global = wl_registry_global_handler,
|
wl_registry_add_listener(wl_registry, &wl_registry_listener, &wl_subcompositor);
|
||||||
.global_remove = wl_registry_global_remove_handler
|
wl_display_roundtrip(wl_display);
|
||||||
};
|
printf("XXX: wl_subcompositor: %p\n", wl_subcompositor);
|
||||||
struct wl_subcompositor *wl_subcompositor = NULL;
|
}
|
||||||
wl_registry_add_listener(wl_registry, &wl_registry_listener, &wl_subcompositor);
|
|
||||||
wl_display_roundtrip(wl_display);
|
|
||||||
printf("XXX: wl_subcompositor: %p\n", wl_subcompositor);
|
|
||||||
|
|
||||||
struct wl_surface *toplevel_surface = gdk_wayland_surface_get_wl_surface(gtk_native_get_surface(GTK_NATIVE(window)));
|
struct wl_surface *toplevel_surface = gdk_wayland_surface_get_wl_surface(gtk_native_get_surface(GTK_NATIVE(window)));
|
||||||
|
|
||||||
@@ -294,11 +312,13 @@ ANativeWindow * ANativeWindow_fromSurface(JNIEnv* env, jobject surface)
|
|||||||
|
|
||||||
struct wl_egl_window *egl_window = wl_egl_window_create(wayland_surface, width, height);
|
struct wl_egl_window *egl_window = wl_egl_window_create(wayland_surface, width, height);
|
||||||
native_window->egl_window = (EGLNativeWindowType)egl_window;
|
native_window->egl_window = (EGLNativeWindowType)egl_window;
|
||||||
|
native_window->wayland_display = wl_display;
|
||||||
|
native_window->wayland_surface = wayland_surface;
|
||||||
printf("EGL::: wayland_surface: %p\n", wayland_surface);
|
printf("EGL::: wayland_surface: %p\n", wayland_surface);
|
||||||
// end of wayland-specific code
|
// end of wayland-specific code
|
||||||
printf("EGL::: native_window->egl_window: %ld\n", native_window->egl_window);
|
printf("EGL::: native_window->egl_window: %ld\n", native_window->egl_window);
|
||||||
|
|
||||||
g_signal_connect(surface_view_widget, "resize", G_CALLBACK(on_resize), egl_window);
|
native_window->resize_handler = g_signal_connect(surface_view_widget, "resize", G_CALLBACK(on_resize), egl_window);
|
||||||
|
|
||||||
return native_window;
|
return native_window;
|
||||||
}
|
}
|
||||||
@@ -380,7 +400,7 @@ EGLBoolean bionic_eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface,
|
|||||||
void (* bionic_eglGetProcAddress(char const *procname))(void)
|
void (* bionic_eglGetProcAddress(char const *procname))(void)
|
||||||
{
|
{
|
||||||
if(__unlikely__(!strcmp(procname, "eglPresentationTimeANDROID")))
|
if(__unlikely__(!strcmp(procname, "eglPresentationTimeANDROID")))
|
||||||
return bionic_eglPresentationTimeANDROID;
|
return (void (*)(void))bionic_eglPresentationTimeANDROID;
|
||||||
|
|
||||||
return eglGetProcAddress(procname);
|
return eglGetProcAddress(procname);
|
||||||
}
|
}
|
||||||
@@ -423,6 +443,40 @@ EGLSurface bionic_eglCreateWindowSurface(EGLDisplay display, EGLConfig config, s
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME 1.5: this most likely belongs elsewhere
|
||||||
|
|
||||||
|
VkResult bionic_vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)
|
||||||
|
{
|
||||||
|
VkWaylandSurfaceCreateInfoKHR wayland_create_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
|
||||||
|
.display = pCreateInfo->window->wayland_display,
|
||||||
|
.surface = pCreateInfo->window->wayland_surface,
|
||||||
|
};
|
||||||
|
|
||||||
|
return vkCreateWaylandSurfaceKHR(instance, &wayland_create_info, pAllocator, pSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult bionic_vkCreateInstance(VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance)
|
||||||
|
{
|
||||||
|
int original_extension_count = pCreateInfo->enabledExtensionCount;
|
||||||
|
int new_extension_count = original_extension_count + 1;
|
||||||
|
const char **enabled_exts = malloc(new_extension_count * sizeof(char *));
|
||||||
|
memcpy(enabled_exts, pCreateInfo->ppEnabledExtensionNames, original_extension_count * sizeof(char *));
|
||||||
|
enabled_exts[original_extension_count] = "VK_KHR_wayland_surface";
|
||||||
|
|
||||||
|
pCreateInfo->enabledExtensionCount = new_extension_count;
|
||||||
|
pCreateInfo->ppEnabledExtensionNames = enabled_exts;
|
||||||
|
return vkCreateInstance(pCreateInfo, pAllocator, pInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
PFN_vkVoidFunction bionic_vkGetInstanceProcAddr(VkInstance instance, const char *pName)
|
||||||
|
{
|
||||||
|
if(__unlikely__(!strcmp(pName, "vkCreateInstance")))
|
||||||
|
return (PFN_vkVoidFunction)bionic_vkCreateInstance;
|
||||||
|
|
||||||
|
return vkGetInstanceProcAddr(instance, pName);
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME 2: this BLATANTLY belongs elsewhere
|
// FIXME 2: this BLATANTLY belongs elsewhere
|
||||||
|
|
||||||
typedef XrResult(*xr_func)();
|
typedef XrResult(*xr_func)();
|
||||||
|
|||||||
Reference in New Issue
Block a user