wayland-egl: Make wl_egl_window a versioned struct
We need wl_egl_window to be a versioned struct in order to keep track of ABI changes. This change makes the first member of wl_egl_window the version number. An heuristic in the wayland driver is added so that we don't break backwards compatibility: - If the first field (version) is an actual pointer, it is an old implementation of wl_egl_window, and version points to the wl_surface proxy. - Else, the first field is the version number, and we have wl_egl_window::surface pointing to the wl_surface proxy. Signed-off-by: Miguel A. Vico <mvicomoya@nvidia.com> Reviewed-by: James Jones <jajones@nvidia.com> Acked-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
This commit is contained in:
committed by
Emil Velikov
parent
63c251e38f
commit
2d5d61bc49
@@ -43,6 +43,7 @@
|
||||
#include "egl_dri2_fallbacks.h"
|
||||
#include "loader.h"
|
||||
#include "util/u_vector.h"
|
||||
#include "eglglobals.h"
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include "wayland-drm-client-protocol.h"
|
||||
@@ -111,6 +112,19 @@ destroy_window_callback(void *data)
|
||||
dri2_surf->wl_win = NULL;
|
||||
}
|
||||
|
||||
static struct wl_surface *
|
||||
get_wl_surface_proxy(struct wl_egl_window *window)
|
||||
{
|
||||
/* Version 3 of wl_egl_window introduced a version field at the same
|
||||
* location where a pointer to wl_surface was stored. Thus, if
|
||||
* window->version is dereferencable, we've been given an older version of
|
||||
* wl_egl_window, and window->version points to wl_surface */
|
||||
if (_eglPointerIsDereferencable((void *)(window->version))) {
|
||||
return wl_proxy_create_wrapper((void *)(window->version));
|
||||
}
|
||||
return wl_proxy_create_wrapper(window->surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
|
||||
*/
|
||||
@@ -182,7 +196,7 @@ dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
|
||||
wl_proxy_set_queue((struct wl_proxy *)dri2_surf->wl_dpy_wrapper,
|
||||
dri2_surf->wl_queue);
|
||||
|
||||
dri2_surf->wl_surface_wrapper = wl_proxy_create_wrapper(window->surface);
|
||||
dri2_surf->wl_surface_wrapper = get_wl_surface_proxy(window);
|
||||
if (!dri2_surf->wl_surface_wrapper) {
|
||||
_eglError(EGL_BAD_ALLOC, "dri2_create_surface");
|
||||
goto cleanup_drm;
|
||||
|
||||
@@ -41,8 +41,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WL_EGL_WINDOW_VERSION 3
|
||||
|
||||
struct wl_egl_window {
|
||||
struct wl_surface *surface;
|
||||
const intptr_t version;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
@@ -55,6 +57,8 @@ struct wl_egl_window {
|
||||
void *private;
|
||||
void (*resize_callback)(struct wl_egl_window *, void *);
|
||||
void (*destroy_window_callback)(void *);
|
||||
|
||||
struct wl_surface *surface;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include "wayland-egl.h"
|
||||
@@ -54,6 +55,7 @@ WL_EGL_EXPORT struct wl_egl_window *
|
||||
wl_egl_window_create(struct wl_surface *surface,
|
||||
int width, int height)
|
||||
{
|
||||
struct wl_egl_window _INIT_ = { .version = WL_EGL_WINDOW_VERSION };
|
||||
struct wl_egl_window *egl_window;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
@@ -63,6 +65,8 @@ wl_egl_window_create(struct wl_surface *surface,
|
||||
if (!egl_window)
|
||||
return NULL;
|
||||
|
||||
memcpy(egl_window, &_INIT_, sizeof *egl_window);
|
||||
|
||||
egl_window->surface = surface;
|
||||
egl_window->private = NULL;
|
||||
egl_window->resize_callback = NULL;
|
||||
|
||||
Reference in New Issue
Block a user