6e7c40f62d
Initial implementation for DRI3 v1.1. Only the DRI3 implementation is there, backends need to implement the proper hooks. Version is still set to 1.0 so clients shouldn't use the new requests yet. v2: Use depth/bpp instead of DRM formats in requests v3: Remove DMA fence requests from v1.1 Add screen/drawable modifier sets v4: Free array returned by 'get_drawable_modifiers()' v5: Fix FD leak Signed-off-by: Daniel Stone <daniels@collabora.com> Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Acked-by: Keith Packard <keithp@keithp.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
625 lines
17 KiB
C
625 lines
17 KiB
C
/*
|
|
* Copyright © 2011-2014 Intel Corporation
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software
|
|
* and its documentation for any purpose is hereby granted without
|
|
* fee, provided that the above copyright notice appear in all copies
|
|
* and that both that copyright notice and this permission notice
|
|
* appear in supporting documentation, and that the name of the
|
|
* copyright holders not be used in advertising or publicity
|
|
* pertaining to distribution of the software without specific,
|
|
* written prior permission. The copyright holders make no
|
|
* representations about the suitability of this software for any
|
|
* purpose. It is provided "as is" without express or implied
|
|
* warranty.
|
|
*
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
#include "xwayland.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <xf86drm.h>
|
|
|
|
#define MESA_EGL_NO_X11_HEADERS
|
|
#include <gbm.h>
|
|
#include <glamor_egl.h>
|
|
|
|
#include <glamor.h>
|
|
#include <glamor_context.h>
|
|
#include <dri3.h>
|
|
#include "drm-client-protocol.h"
|
|
|
|
static DevPrivateKeyRec xwl_auth_state_private_key;
|
|
|
|
struct xwl_pixmap {
|
|
struct wl_buffer *buffer;
|
|
struct gbm_bo *bo;
|
|
void *image;
|
|
unsigned int texture;
|
|
};
|
|
|
|
static void
|
|
xwl_glamor_egl_make_current(struct glamor_context *glamor_ctx)
|
|
{
|
|
eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
|
|
EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
if (!eglMakeCurrent(glamor_ctx->display,
|
|
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
|
glamor_ctx->ctx))
|
|
FatalError("Failed to make EGL context current\n");
|
|
}
|
|
|
|
static uint32_t
|
|
wl_drm_format_for_depth(int depth)
|
|
{
|
|
switch (depth) {
|
|
case 15:
|
|
return WL_DRM_FORMAT_XRGB1555;
|
|
case 16:
|
|
return WL_DRM_FORMAT_RGB565;
|
|
case 24:
|
|
return WL_DRM_FORMAT_XRGB8888;
|
|
default:
|
|
ErrorF("unexpected depth: %d\n", depth);
|
|
case 32:
|
|
return WL_DRM_FORMAT_ARGB8888;
|
|
}
|
|
}
|
|
|
|
static uint32_t
|
|
gbm_format_for_depth(int depth)
|
|
{
|
|
switch (depth) {
|
|
case 16:
|
|
return GBM_FORMAT_RGB565;
|
|
case 24:
|
|
return GBM_FORMAT_XRGB8888;
|
|
default:
|
|
ErrorF("unexpected depth: %d\n", depth);
|
|
case 32:
|
|
return GBM_FORMAT_ARGB8888;
|
|
}
|
|
}
|
|
|
|
void
|
|
glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
|
|
{
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
|
|
|
glamor_ctx->ctx = xwl_screen->egl_context;
|
|
glamor_ctx->display = xwl_screen->egl_display;
|
|
|
|
glamor_ctx->make_current = xwl_glamor_egl_make_current;
|
|
|
|
xwl_screen->glamor_ctx = glamor_ctx;
|
|
}
|
|
|
|
static PixmapPtr
|
|
xwl_glamor_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth)
|
|
{
|
|
PixmapPtr pixmap;
|
|
struct xwl_pixmap *xwl_pixmap;
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
|
|
|
xwl_pixmap = malloc(sizeof *xwl_pixmap);
|
|
if (xwl_pixmap == NULL)
|
|
return NULL;
|
|
|
|
pixmap = glamor_create_pixmap(screen,
|
|
gbm_bo_get_width(bo),
|
|
gbm_bo_get_height(bo),
|
|
depth,
|
|
GLAMOR_CREATE_PIXMAP_NO_TEXTURE);
|
|
if (pixmap == NULL) {
|
|
free(xwl_pixmap);
|
|
return NULL;
|
|
}
|
|
|
|
if (lastGLContext != xwl_screen->glamor_ctx) {
|
|
lastGLContext = xwl_screen->glamor_ctx;
|
|
xwl_glamor_egl_make_current(xwl_screen->glamor_ctx);
|
|
}
|
|
|
|
xwl_pixmap->bo = bo;
|
|
xwl_pixmap->buffer = NULL;
|
|
xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
|
|
xwl_screen->egl_context,
|
|
EGL_NATIVE_PIXMAP_KHR,
|
|
xwl_pixmap->bo, NULL);
|
|
|
|
glGenTextures(1, &xwl_pixmap->texture);
|
|
glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
xwl_pixmap_set_private(pixmap, xwl_pixmap);
|
|
|
|
glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture);
|
|
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
|
|
|
|
return pixmap;
|
|
}
|
|
|
|
struct wl_buffer *
|
|
xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap)
|
|
{
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
|
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
|
int prime_fd;
|
|
|
|
if (xwl_pixmap->buffer)
|
|
return xwl_pixmap->buffer;
|
|
|
|
prime_fd = gbm_bo_get_fd(xwl_pixmap->bo);
|
|
if (prime_fd == -1)
|
|
return NULL;
|
|
|
|
xwl_pixmap->buffer =
|
|
wl_drm_create_prime_buffer(xwl_screen->drm, prime_fd,
|
|
pixmap->drawable.width,
|
|
pixmap->drawable.height,
|
|
wl_drm_format_for_depth(pixmap->drawable.depth),
|
|
0, gbm_bo_get_stride(xwl_pixmap->bo),
|
|
0, 0,
|
|
0, 0);
|
|
|
|
close(prime_fd);
|
|
|
|
return xwl_pixmap->buffer;
|
|
}
|
|
|
|
static PixmapPtr
|
|
xwl_glamor_create_pixmap(ScreenPtr screen,
|
|
int width, int height, int depth, unsigned int hint)
|
|
{
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
|
struct gbm_bo *bo;
|
|
|
|
if (width > 0 && height > 0 && depth >= 15 &&
|
|
(hint == 0 ||
|
|
hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP ||
|
|
hint == CREATE_PIXMAP_USAGE_SHARED)) {
|
|
bo = gbm_bo_create(xwl_screen->gbm, width, height,
|
|
gbm_format_for_depth(depth),
|
|
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
|
|
|
if (bo)
|
|
return xwl_glamor_create_pixmap_for_bo(screen, bo, depth);
|
|
}
|
|
|
|
return glamor_create_pixmap(screen, width, height, depth, hint);
|
|
}
|
|
|
|
static Bool
|
|
xwl_glamor_destroy_pixmap(PixmapPtr pixmap)
|
|
{
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
|
|
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
|
|
|
if (xwl_pixmap && pixmap->refcnt == 1) {
|
|
if (xwl_pixmap->buffer)
|
|
wl_buffer_destroy(xwl_pixmap->buffer);
|
|
|
|
eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
|
|
gbm_bo_destroy(xwl_pixmap->bo);
|
|
free(xwl_pixmap);
|
|
}
|
|
|
|
return glamor_destroy_pixmap(pixmap);
|
|
}
|
|
|
|
static Bool
|
|
xwl_glamor_create_screen_resources(ScreenPtr screen)
|
|
{
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
|
int ret;
|
|
|
|
screen->CreateScreenResources = xwl_screen->CreateScreenResources;
|
|
ret = (*screen->CreateScreenResources) (screen);
|
|
xwl_screen->CreateScreenResources = screen->CreateScreenResources;
|
|
screen->CreateScreenResources = xwl_glamor_create_screen_resources;
|
|
|
|
if (!ret)
|
|
return ret;
|
|
|
|
if (xwl_screen->rootless) {
|
|
screen->devPrivate =
|
|
fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
|
|
}
|
|
else {
|
|
screen->devPrivate =
|
|
xwl_glamor_create_pixmap(screen, screen->width, screen->height,
|
|
screen->rootDepth,
|
|
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
|
|
}
|
|
|
|
SetRootClip(screen, xwl_screen->root_clip_mode);
|
|
|
|
return screen->devPrivate != NULL;
|
|
}
|
|
|
|
static char
|
|
is_fd_render_node(int fd)
|
|
{
|
|
struct stat render;
|
|
|
|
if (fstat(fd, &render))
|
|
return 0;
|
|
if (!S_ISCHR(render.st_mode))
|
|
return 0;
|
|
if (render.st_rdev & 0x80)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
xwl_drm_init_egl(struct xwl_screen *xwl_screen)
|
|
{
|
|
EGLint major, minor;
|
|
static const EGLint config_attribs_core[] = {
|
|
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
|
|
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
|
|
EGL_CONTEXT_MAJOR_VERSION_KHR,
|
|
GLAMOR_GL_CORE_VER_MAJOR,
|
|
EGL_CONTEXT_MINOR_VERSION_KHR,
|
|
GLAMOR_GL_CORE_VER_MINOR,
|
|
EGL_NONE
|
|
};
|
|
|
|
if (xwl_screen->egl_display)
|
|
return;
|
|
|
|
xwl_screen->expecting_event--;
|
|
|
|
xwl_screen->gbm = gbm_create_device(xwl_screen->drm_fd);
|
|
if (xwl_screen->gbm == NULL) {
|
|
ErrorF("couldn't get display device\n");
|
|
return;
|
|
}
|
|
|
|
xwl_screen->egl_display = glamor_egl_get_display(EGL_PLATFORM_GBM_MESA,
|
|
xwl_screen->gbm);
|
|
if (xwl_screen->egl_display == EGL_NO_DISPLAY) {
|
|
ErrorF("glamor_egl_get_display() failed\n");
|
|
return;
|
|
}
|
|
|
|
if (!eglInitialize(xwl_screen->egl_display, &major, &minor)) {
|
|
ErrorF("eglInitialize() failed\n");
|
|
return;
|
|
}
|
|
|
|
eglBindAPI(EGL_OPENGL_API);
|
|
|
|
xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display,
|
|
NULL, EGL_NO_CONTEXT, config_attribs_core);
|
|
if (!xwl_screen->egl_context)
|
|
xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display,
|
|
NULL, EGL_NO_CONTEXT, NULL);
|
|
|
|
if (xwl_screen->egl_context == EGL_NO_CONTEXT) {
|
|
ErrorF("Failed to create EGL context\n");
|
|
return;
|
|
}
|
|
|
|
if (!eglMakeCurrent(xwl_screen->egl_display,
|
|
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
|
xwl_screen->egl_context)) {
|
|
ErrorF("Failed to make EGL context current\n");
|
|
return;
|
|
}
|
|
|
|
if (!epoxy_has_gl_extension("GL_OES_EGL_image")) {
|
|
ErrorF("GL_OES_EGL_image not available\n");
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void
|
|
xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
|
|
{
|
|
struct xwl_screen *xwl_screen = data;
|
|
drm_magic_t magic;
|
|
|
|
xwl_screen->device_name = strdup(device);
|
|
if (!xwl_screen->device_name)
|
|
return;
|
|
|
|
xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC);
|
|
if (xwl_screen->drm_fd == -1) {
|
|
ErrorF("wayland-egl: could not open %s (%s)\n",
|
|
xwl_screen->device_name, strerror(errno));
|
|
return;
|
|
}
|
|
|
|
if (is_fd_render_node(xwl_screen->drm_fd)) {
|
|
xwl_screen->fd_render_node = 1;
|
|
xwl_drm_init_egl(xwl_screen);
|
|
} else {
|
|
drmGetMagic(xwl_screen->drm_fd, &magic);
|
|
wl_drm_authenticate(xwl_screen->drm, magic);
|
|
}
|
|
}
|
|
|
|
static void
|
|
xwl_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
|
|
{
|
|
struct xwl_screen *xwl_screen = data;
|
|
|
|
switch (format) {
|
|
case WL_DRM_FORMAT_ARGB8888:
|
|
xwl_screen->formats |= XWL_FORMAT_ARGB8888;
|
|
break;
|
|
case WL_DRM_FORMAT_XRGB8888:
|
|
xwl_screen->formats |= XWL_FORMAT_XRGB8888;
|
|
break;
|
|
case WL_DRM_FORMAT_RGB565:
|
|
xwl_screen->formats |= XWL_FORMAT_RGB565;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
xwl_drm_handle_authenticated(void *data, struct wl_drm *drm)
|
|
{
|
|
struct xwl_screen *xwl_screen = data;
|
|
|
|
if (!xwl_screen->egl_display)
|
|
xwl_drm_init_egl(xwl_screen);
|
|
}
|
|
|
|
static void
|
|
xwl_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
|
|
{
|
|
struct xwl_screen *xwl_screen = data;
|
|
|
|
xwl_screen->capabilities = value;
|
|
}
|
|
|
|
static const struct wl_drm_listener xwl_drm_listener = {
|
|
xwl_drm_handle_device,
|
|
xwl_drm_handle_format,
|
|
xwl_drm_handle_authenticated,
|
|
xwl_drm_handle_capabilities
|
|
};
|
|
|
|
Bool
|
|
xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
|
|
uint32_t id, uint32_t version)
|
|
{
|
|
if (version < 2)
|
|
return FALSE;
|
|
|
|
xwl_screen->drm =
|
|
wl_registry_bind(xwl_screen->registry, id, &wl_drm_interface, 2);
|
|
wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen);
|
|
xwl_screen->expecting_event++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int
|
|
glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
|
|
PixmapPtr pixmap,
|
|
unsigned int tex,
|
|
Bool want_name, CARD16 *stride, CARD32 *size)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
struct xwl_auth_state {
|
|
int fd;
|
|
ClientPtr client;
|
|
struct wl_callback *callback;
|
|
};
|
|
|
|
static void
|
|
free_xwl_auth_state(ClientPtr pClient, struct xwl_auth_state *state)
|
|
{
|
|
dixSetPrivate(&pClient->devPrivates, &xwl_auth_state_private_key, NULL);
|
|
if (state) {
|
|
wl_callback_destroy(state->callback);
|
|
free(state);
|
|
}
|
|
}
|
|
|
|
static void
|
|
xwl_auth_state_client_callback(CallbackListPtr *pcbl, void *unused, void *data)
|
|
{
|
|
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
|
|
ClientPtr pClient = clientinfo->client;
|
|
struct xwl_auth_state *state;
|
|
|
|
switch (pClient->clientState) {
|
|
case ClientStateGone:
|
|
case ClientStateRetained:
|
|
state = dixLookupPrivate(&pClient->devPrivates, &xwl_auth_state_private_key);
|
|
free_xwl_auth_state(pClient, state);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
|
|
{
|
|
struct xwl_auth_state *state = data;
|
|
ClientPtr client = state->client;
|
|
|
|
/* if the client is gone, the callback is cancelled so it's safe to
|
|
* assume the client is still in ClientStateRunning at this point...
|
|
*/
|
|
dri3_send_open_reply(client, state->fd);
|
|
AttendClient(client);
|
|
free_xwl_auth_state(client, state);
|
|
}
|
|
|
|
static const struct wl_callback_listener sync_listener = {
|
|
sync_callback
|
|
};
|
|
|
|
static int
|
|
xwl_dri3_open_client(ClientPtr client,
|
|
ScreenPtr screen,
|
|
RRProviderPtr provider,
|
|
int *pfd)
|
|
{
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
|
struct xwl_auth_state *state;
|
|
drm_magic_t magic;
|
|
int fd;
|
|
|
|
fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC);
|
|
if (fd < 0)
|
|
return BadAlloc;
|
|
if (xwl_screen->fd_render_node) {
|
|
*pfd = fd;
|
|
return Success;
|
|
}
|
|
|
|
state = malloc(sizeof *state);
|
|
if (state == NULL) {
|
|
close(fd);
|
|
return BadAlloc;
|
|
}
|
|
|
|
state->client = client;
|
|
state->fd = fd;
|
|
|
|
if (drmGetMagic(state->fd, &magic) < 0) {
|
|
close(state->fd);
|
|
free(state);
|
|
return BadMatch;
|
|
}
|
|
|
|
wl_drm_authenticate(xwl_screen->drm, magic);
|
|
state->callback = wl_display_sync(xwl_screen->display);
|
|
wl_callback_add_listener(state->callback, &sync_listener, state);
|
|
dixSetPrivate(&client->devPrivates, &xwl_auth_state_private_key, state);
|
|
|
|
IgnoreClient(client);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static PixmapPtr
|
|
xwl_dri3_pixmap_from_fd(ScreenPtr screen, int fd,
|
|
CARD16 width, CARD16 height, CARD16 stride,
|
|
CARD8 depth, CARD8 bpp)
|
|
{
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
|
struct gbm_import_fd_data data;
|
|
struct gbm_bo *bo;
|
|
PixmapPtr pixmap;
|
|
|
|
if (width == 0 || height == 0 ||
|
|
depth < 15 || bpp != BitsPerPixel(depth) || stride < width * bpp / 8)
|
|
return NULL;
|
|
|
|
data.fd = fd;
|
|
data.width = width;
|
|
data.height = height;
|
|
data.stride = stride;
|
|
data.format = gbm_format_for_depth(depth);
|
|
bo = gbm_bo_import(xwl_screen->gbm, GBM_BO_IMPORT_FD, &data,
|
|
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
|
if (bo == NULL)
|
|
return NULL;
|
|
|
|
pixmap = xwl_glamor_create_pixmap_for_bo(screen, bo, depth);
|
|
if (pixmap == NULL) {
|
|
gbm_bo_destroy(bo);
|
|
return NULL;
|
|
}
|
|
|
|
return pixmap;
|
|
}
|
|
|
|
static int
|
|
xwl_dri3_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
|
|
CARD16 *stride, CARD32 *size)
|
|
{
|
|
struct xwl_pixmap *xwl_pixmap;
|
|
|
|
xwl_pixmap = xwl_pixmap_get(pixmap);
|
|
|
|
*stride = gbm_bo_get_stride(xwl_pixmap->bo);
|
|
*size = pixmap->drawable.width * *stride;
|
|
|
|
return gbm_bo_get_fd(xwl_pixmap->bo);
|
|
}
|
|
|
|
static dri3_screen_info_rec xwl_dri3_info = {
|
|
.version = 1,
|
|
.open = NULL,
|
|
.pixmap_from_fd = xwl_dri3_pixmap_from_fd,
|
|
.fd_from_pixmap = xwl_dri3_fd_from_pixmap,
|
|
.open_client = xwl_dri3_open_client,
|
|
};
|
|
|
|
Bool
|
|
xwl_glamor_init(struct xwl_screen *xwl_screen)
|
|
{
|
|
ScreenPtr screen = xwl_screen->screen;
|
|
const char *no_glamor_env;
|
|
|
|
no_glamor_env = getenv("XWAYLAND_NO_GLAMOR");
|
|
if (no_glamor_env && *no_glamor_env != '0') {
|
|
ErrorF("Disabling glamor and dri3 support, XWAYLAND_NO_GLAMOR is set\n");
|
|
return FALSE;
|
|
}
|
|
|
|
if (xwl_screen->egl_context == EGL_NO_CONTEXT) {
|
|
ErrorF("Disabling glamor and dri3, EGL setup failed\n");
|
|
return FALSE;
|
|
}
|
|
|
|
if (!glamor_init(xwl_screen->screen, GLAMOR_USE_EGL_SCREEN)) {
|
|
ErrorF("Failed to initialize glamor\n");
|
|
return FALSE;
|
|
}
|
|
|
|
if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
|
|
ErrorF("Failed to initialize dri3\n");
|
|
return FALSE;
|
|
}
|
|
|
|
if (!dixRegisterPrivateKey(&xwl_auth_state_private_key, PRIVATE_CLIENT, 0)) {
|
|
ErrorF("Failed to register private key\n");
|
|
return FALSE;
|
|
}
|
|
|
|
if (!AddCallback(&ClientStateCallback, xwl_auth_state_client_callback, NULL)) {
|
|
ErrorF("Failed to add client state callback\n");
|
|
return FALSE;
|
|
}
|
|
|
|
xwl_screen->CreateScreenResources = screen->CreateScreenResources;
|
|
screen->CreateScreenResources = xwl_glamor_create_screen_resources;
|
|
screen->CreatePixmap = xwl_glamor_create_pixmap;
|
|
screen->DestroyPixmap = xwl_glamor_destroy_pixmap;
|
|
|
|
#ifdef XV
|
|
if (!xwl_glamor_xv_init(screen))
|
|
ErrorF("Failed to initialize glamor Xv extension\n");
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|