#include "native_x11.h"
#include "x11_screen.h"
-#ifdef GLX_DIRECT_RENDERING
+#ifdef HAVE_WAYLAND_BACKEND
+#include "common/native_wayland_drm_bufmgr_helper.h"
+#endif
-enum dri2_surface_type {
- DRI2_SURFACE_TYPE_WINDOW,
- DRI2_SURFACE_TYPE_PIXMAP,
-};
+#ifdef GLX_DIRECT_RENDERING
struct dri2_display {
struct native_display base;
Display *dpy;
boolean own_dpy;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct x11_screen *xscr;
int xscr_number;
int num_configs;
struct util_hash_table *surfaces;
+#ifdef HAVE_WAYLAND_BACKEND
+ struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
+#endif
};
struct dri2_surface {
struct native_surface base;
Drawable drawable;
- enum dri2_surface_type type;
enum pipe_format color_format;
struct dri2_display *dri2dpy;
static struct dri2_surface *
dri2_display_create_surface(struct native_display *ndpy,
- enum dri2_surface_type type,
Drawable drawable,
- const struct native_config *nconf)
+ enum pipe_format color_format)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
- struct dri2_config *dri2conf = dri2_config(nconf);
struct dri2_surface *dri2surf;
dri2surf = CALLOC_STRUCT(dri2_surface);
return NULL;
dri2surf->dri2dpy = dri2dpy;
- dri2surf->type = type;
dri2surf->drawable = drawable;
- dri2surf->color_format = dri2conf->base.color_format;
+ dri2surf->color_format = color_format;
dri2surf->base.destroy = dri2_surface_destroy;
dri2surf->base.present = dri2_surface_present;
{
struct dri2_surface *dri2surf;
- dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW,
- (Drawable) win, nconf);
+ dri2surf = dri2_display_create_surface(ndpy,
+ (Drawable) win, nconf->color_format);
return (dri2surf) ? &dri2surf->base : NULL;
}
{
struct dri2_surface *dri2surf;
- dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP,
- (Drawable) pix, nconf);
+ if (!nconf) {
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ uint depth, nconf_depth;
+ int i;
+
+ depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
+ for (i = 0; i < dri2dpy->num_configs; i++) {
+ nconf_depth = util_format_get_blocksizebits(
+ dri2dpy->configs[i].base.color_format);
+ /* simple depth match for now */
+ if (depth == nconf_depth ||
+ (depth == 24 && depth + 8 == nconf_depth)) {
+ nconf = &dri2dpy->configs[i].base;
+ break;
+ }
+ }
+
+ if (!nconf)
+ return NULL;
+ }
+
+ dri2surf = dri2_display_create_surface(ndpy,
+ (Drawable) pix, nconf->color_format);
return (dri2surf) ? &dri2surf->base : NULL;
}
{
return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count,
(is_color) ? PIPE_BIND_RENDER_TARGET :
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
}
static boolean
if (!mode->xRenderable || !mode->drawableType)
return FALSE;
+ /* fast/slow configs are probably not relevant */
+ if (mode->visualRating == GLX_SLOW_CONFIG)
+ return FALSE;
+
nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_FRONT_LEFT;
if (mode->doubleBufferMode)
nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_LEFT;
if (nconf->color_format == PIPE_FORMAT_NONE)
return FALSE;
- if (mode->drawableType & GLX_WINDOW_BIT)
+ if ((mode->drawableType & GLX_WINDOW_BIT) && mode->visualID)
nconf->window_bit = TRUE;
if (mode->drawableType & GLX_PIXMAP_BIT)
nconf->pixmap_bit = TRUE;
nconf->native_visual_id = mode->visualID;
- nconf->native_visual_type = mode->visualType;
+ switch (mode->visualType) {
+ case GLX_TRUE_COLOR:
+ nconf->native_visual_type = TrueColor;
+ break;
+ case GLX_DIRECT_COLOR:
+ nconf->native_visual_type = DirectColor;
+ break;
+ case GLX_PSEUDO_COLOR:
+ nconf->native_visual_type = PseudoColor;
+ break;
+ case GLX_STATIC_COLOR:
+ nconf->native_visual_type = StaticColor;
+ break;
+ case GLX_GRAY_SCALE:
+ nconf->native_visual_type = GrayScale;
+ break;
+ case GLX_STATIC_GRAY:
+ nconf->native_visual_type = StaticGray;
+ break;
+ }
nconf->level = mode->level;
- nconf->samples = mode->samples;
-
- nconf->slow_config = (mode->visualRating == GLX_SLOW_CONFIG);
if (mode->transparentPixel == GLX_TRANSPARENT_RGB) {
nconf->transparent_rgb = TRUE;
count = 0;
for (i = 0; i < num_modes; i++) {
struct native_config *nconf = &dri2dpy->configs[count].base;
- if (dri2_display_convert_config(&dri2dpy->base, modes, nconf))
- count++;
+
+ if (dri2_display_convert_config(&dri2dpy->base, modes, nconf)) {
+ int j;
+ /* look for duplicates */
+ for (j = 0; j < count; j++) {
+ if (memcmp(&dri2dpy->configs[j], nconf, sizeof(*nconf)) == 0)
+ break;
+ }
+ if (j == count)
+ count++;
+ }
modes = modes->next;
}
dri2dpy->event_handler->new_drm_screen(&dri2dpy->base,
dri2dpy->dri_driver, fd);
if (!dri2dpy->base.screen) {
- _eglLog(_EGL_WARNING, "failed to create DRM screen");
+ _eglLog(_EGL_DEBUG, "failed to create DRM screen");
return FALSE;
}
static int
dri2_display_hash_table_compare(void *key1, void *key2)
{
- return (key1 - key2);
+ return ((char *) key1 - (char *) key2);
}
+static int
+dri2_display_authenticate(void *user_data, uint32_t magic)
+{
+ struct native_display *ndpy = user_data;
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+
+ return x11_screen_authenticate(dri2dpy->xscr, magic);
+}
+
+#ifdef HAVE_WAYLAND_BACKEND
+
+static struct wayland_drm_callbacks wl_drm_callbacks = {
+ dri2_display_authenticate,
+ egl_g3d_wl_drm_helper_reference_buffer,
+ egl_g3d_wl_drm_helper_unreference_buffer
+};
+
+static boolean
+dri2_display_bind_wayland_display(struct native_display *ndpy,
+ struct wl_display *wl_dpy)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+
+ if (dri2dpy->wl_server_drm)
+ return FALSE;
+
+ dri2dpy->wl_server_drm = wayland_drm_init(wl_dpy,
+ x11_screen_get_device_name(dri2dpy->xscr),
+ &wl_drm_callbacks, ndpy);
+
+ if (!dri2dpy->wl_server_drm)
+ return FALSE;
+
+ return TRUE;
+}
+
+static boolean
+dri2_display_unbind_wayland_display(struct native_display *ndpy,
+ struct wl_display *wl_dpy)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+
+ if (!dri2dpy->wl_server_drm)
+ return FALSE;
+
+ wayland_drm_uninit(dri2dpy->wl_server_drm);
+ dri2dpy->wl_server_drm = NULL;
+
+ return TRUE;
+}
+
+static struct native_display_wayland_bufmgr dri2_display_wayland_bufmgr = {
+ dri2_display_bind_wayland_display,
+ dri2_display_unbind_wayland_display,
+ egl_g3d_wl_drm_common_wl_buffer_get_resource
+};
+
+#endif /* HAVE_WAYLAND_BACKEND */
+
struct native_display *
x11_create_dri2_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct dri2_display *dri2dpy;
return NULL;
dri2dpy->event_handler = event_handler;
- dri2dpy->base.user_data = user_data;
dri2dpy->dpy = dpy;
if (!dri2dpy->dpy) {
return NULL;
}
- if (!dri2_display_init_screen(&dri2dpy->base)) {
- dri2_display_destroy(&dri2dpy->base);
- return NULL;
- }
-
dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash,
dri2_display_hash_table_compare);
if (!dri2dpy->surfaces) {
return NULL;
}
+ dri2dpy->base.init_screen = dri2_display_init_screen;
dri2dpy->base.destroy = dri2_display_destroy;
dri2dpy->base.get_param = dri2_display_get_param;
dri2dpy->base.get_configs = dri2_display_get_configs;
dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
+#ifdef HAVE_WAYLAND_BACKEND
+ dri2dpy->base.wayland_bufmgr = &dri2_display_wayland_bufmgr;
+#endif
return &dri2dpy->base;
}