mirror of
https://github.com/openbsd/xenocara.git
synced 2025-12-08 10:19:00 +00:00
Update to xserver 1.20.5. Tested by jsg@
This commit is contained in:
@@ -69,7 +69,7 @@ CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \
|
||||
$(top_builddir)/include/xorg-config.h \
|
||||
$(top_builddir)/include/xkb-config.h \
|
||||
$(top_builddir)/include/xwin-config.h \
|
||||
$(top_builddir)/include/kdrive-config.h \
|
||||
$(top_builddir)/include/xwayland-config.h \
|
||||
$(top_builddir)/include/version-config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
@@ -337,6 +337,7 @@ RANLIB = @RANLIB@
|
||||
RAWCPP = @RAWCPP@
|
||||
RAWCPPFLAGS = @RAWCPPFLAGS@
|
||||
RELEASE_DATE = @RELEASE_DATE@
|
||||
SCANNER_ARG = @SCANNER_ARG@
|
||||
SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@
|
||||
SED = @SED@
|
||||
SELINUX_CFLAGS = @SELINUX_CFLAGS@
|
||||
@@ -355,15 +356,18 @@ SYSCONFDIR = @SYSCONFDIR@
|
||||
SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@
|
||||
SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@
|
||||
TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@
|
||||
TSLIB_CFLAGS = @TSLIB_CFLAGS@
|
||||
TSLIB_LIBS = @TSLIB_LIBS@
|
||||
UDEV_CFLAGS = @UDEV_CFLAGS@
|
||||
UDEV_LIBS = @UDEV_LIBS@
|
||||
UTILS_SYS_LIBS = @UTILS_SYS_LIBS@
|
||||
VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@
|
||||
VERSION = @VERSION@
|
||||
WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@
|
||||
WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@
|
||||
WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@
|
||||
WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@
|
||||
WAYLAND_SCANNER = @WAYLAND_SCANNER@
|
||||
WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@
|
||||
WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@
|
||||
WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@
|
||||
WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@
|
||||
WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@
|
||||
@@ -371,6 +375,8 @@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@
|
||||
WINDRES = @WINDRES@
|
||||
X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@
|
||||
X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@
|
||||
XCONFIGDIR = @XCONFIGDIR@
|
||||
XCONFIGFILE = @XCONFIGFILE@
|
||||
XDMCP_CFLAGS = @XDMCP_CFLAGS@
|
||||
XDMCP_LIBS = @XDMCP_LIBS@
|
||||
XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@
|
||||
@@ -442,8 +448,6 @@ XWIN_SERVER_NAME = @XWIN_SERVER_NAME@
|
||||
XWIN_SYS_LIBS = @XWIN_SYS_LIBS@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
__XCONFIGDIR__ = @__XCONFIGDIR__@
|
||||
__XCONFIGFILE__ = @__XCONFIGFILE__@
|
||||
abi_ansic = @abi_ansic@
|
||||
abi_extension = @abi_extension@
|
||||
abi_videodrv = @abi_videodrv@
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "dri3_priv.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
static int dri3_request;
|
||||
DevPrivateKeyRec dri3_screen_private_key;
|
||||
|
||||
@@ -43,7 +45,7 @@ dri3_close_screen(ScreenPtr screen)
|
||||
}
|
||||
|
||||
Bool
|
||||
dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info)
|
||||
dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info)
|
||||
{
|
||||
dri3_screen_generation = serverGeneration;
|
||||
|
||||
@@ -99,3 +101,20 @@ dri3_extension_init(void)
|
||||
bail:
|
||||
FatalError("Cannot initialize DRI3 extension");
|
||||
}
|
||||
|
||||
uint32_t
|
||||
drm_format_for_depth(uint32_t depth, uint32_t bpp)
|
||||
{
|
||||
switch (bpp) {
|
||||
case 16:
|
||||
return DRM_FORMAT_RGB565;
|
||||
case 24:
|
||||
return DRM_FORMAT_XRGB8888;
|
||||
case 30:
|
||||
return DRM_FORMAT_XRGB2101010;
|
||||
case 32:
|
||||
return DRM_FORMAT_ARGB8888;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <X11/extensions/dri3proto.h>
|
||||
#include <randrstr.h>
|
||||
|
||||
#define DRI3_SCREEN_INFO_VERSION 1
|
||||
#define DRI3_SCREEN_INFO_VERSION 2
|
||||
|
||||
typedef int (*dri3_open_proc)(ScreenPtr screen,
|
||||
RRProviderPtr provider,
|
||||
@@ -47,11 +47,43 @@ typedef PixmapPtr (*dri3_pixmap_from_fd_proc) (ScreenPtr screen,
|
||||
CARD8 depth,
|
||||
CARD8 bpp);
|
||||
|
||||
typedef PixmapPtr (*dri3_pixmap_from_fds_proc) (ScreenPtr screen,
|
||||
CARD8 num_fds,
|
||||
const int *fds,
|
||||
CARD16 width,
|
||||
CARD16 height,
|
||||
const CARD32 *strides,
|
||||
const CARD32 *offsets,
|
||||
CARD8 depth,
|
||||
CARD8 bpp,
|
||||
CARD64 modifier);
|
||||
|
||||
typedef int (*dri3_fd_from_pixmap_proc) (ScreenPtr screen,
|
||||
PixmapPtr pixmap,
|
||||
CARD16 *stride,
|
||||
CARD32 *size);
|
||||
|
||||
typedef int (*dri3_fds_from_pixmap_proc) (ScreenPtr screen,
|
||||
PixmapPtr pixmap,
|
||||
int *fds,
|
||||
uint32_t *strides,
|
||||
uint32_t *offsets,
|
||||
uint64_t *modifier);
|
||||
|
||||
typedef int (*dri3_get_formats_proc) (ScreenPtr screen,
|
||||
CARD32 *num_formats,
|
||||
CARD32 **formats);
|
||||
|
||||
typedef int (*dri3_get_modifiers_proc) (ScreenPtr screen,
|
||||
uint32_t format,
|
||||
uint32_t *num_modifiers,
|
||||
uint64_t **modifiers);
|
||||
|
||||
typedef int (*dri3_get_drawable_modifiers_proc) (DrawablePtr draw,
|
||||
uint32_t format,
|
||||
uint32_t *num_modifiers,
|
||||
uint64_t **modifiers);
|
||||
|
||||
typedef struct dri3_screen_info {
|
||||
uint32_t version;
|
||||
|
||||
@@ -62,14 +94,24 @@ typedef struct dri3_screen_info {
|
||||
/* Version 1 */
|
||||
dri3_open_client_proc open_client;
|
||||
|
||||
/* Version 2 */
|
||||
dri3_pixmap_from_fds_proc pixmap_from_fds;
|
||||
dri3_fds_from_pixmap_proc fds_from_pixmap;
|
||||
dri3_get_formats_proc get_formats;
|
||||
dri3_get_modifiers_proc get_modifiers;
|
||||
dri3_get_drawable_modifiers_proc get_drawable_modifiers;
|
||||
|
||||
} dri3_screen_info_rec, *dri3_screen_info_ptr;
|
||||
|
||||
extern _X_EXPORT Bool
|
||||
dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info);
|
||||
dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info);
|
||||
|
||||
extern _X_EXPORT int
|
||||
dri3_send_open_reply(ClientPtr client, int fd);
|
||||
|
||||
extern _X_EXPORT uint32_t
|
||||
drm_format_for_depth(uint32_t depth, uint32_t bpp);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _DRI3_H_ */
|
||||
|
||||
@@ -34,12 +34,22 @@
|
||||
|
||||
extern DevPrivateKeyRec dri3_screen_private_key;
|
||||
|
||||
typedef struct dri3_dmabuf_format {
|
||||
uint32_t format;
|
||||
uint32_t num_modifiers;
|
||||
uint64_t *modifiers;
|
||||
} dri3_dmabuf_format_rec, *dri3_dmabuf_format_ptr;
|
||||
|
||||
typedef struct dri3_screen_priv {
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
ConfigNotifyProcPtr ConfigNotify;
|
||||
DestroyWindowProcPtr DestroyWindow;
|
||||
|
||||
dri3_screen_info_ptr info;
|
||||
Bool formats_cached;
|
||||
CARD32 num_formats;
|
||||
dri3_dmabuf_format_ptr formats;
|
||||
|
||||
const dri3_screen_info_rec *info;
|
||||
} dri3_screen_priv_rec, *dri3_screen_priv_ptr;
|
||||
|
||||
#define wrap(priv,real,mem,func) {\
|
||||
@@ -69,10 +79,26 @@ int
|
||||
dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd);
|
||||
|
||||
int
|
||||
dri3_pixmap_from_fd(PixmapPtr *ppixmap, ScreenPtr screen, int fd,
|
||||
CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp);
|
||||
dri3_pixmap_from_fds(PixmapPtr *ppixmap, ScreenPtr screen,
|
||||
CARD8 num_fds, const int *fds,
|
||||
CARD16 width, CARD16 height,
|
||||
const CARD32 *strides, const CARD32 *offsets,
|
||||
CARD8 depth, CARD8 bpp, CARD64 modifier);
|
||||
|
||||
int
|
||||
dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size);
|
||||
dri3_fd_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size);
|
||||
|
||||
int
|
||||
dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds,
|
||||
uint32_t *strides, uint32_t *offsets,
|
||||
uint64_t *modifier);
|
||||
|
||||
int
|
||||
dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable,
|
||||
CARD8 depth, CARD8 bpp,
|
||||
CARD32 *num_drawable_modifiers,
|
||||
CARD64 **drawable_modifiers,
|
||||
CARD32 *num_screen_modifiers,
|
||||
CARD64 **screen_modifiers);
|
||||
|
||||
#endif /* _DRI3PRIV_H_ */
|
||||
|
||||
@@ -30,6 +30,21 @@
|
||||
#include <xace.h>
|
||||
#include "../Xext/syncsdk.h"
|
||||
#include <protocol-versions.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
static Bool
|
||||
dri3_screen_can_one_point_two(ScreenPtr screen)
|
||||
{
|
||||
dri3_screen_priv_ptr dri3 = dri3_screen_priv(screen);
|
||||
|
||||
if (dri3 && dri3->info && dri3->info->version >= 2 &&
|
||||
dri3->info->pixmap_from_fds && dri3->info->fds_from_pixmap &&
|
||||
dri3->info->get_formats && dri3->info->get_modifiers &&
|
||||
dri3->info->get_drawable_modifiers)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_dri3_query_version(ClientPtr client)
|
||||
@@ -44,7 +59,35 @@ proc_dri3_query_version(ClientPtr client)
|
||||
};
|
||||
|
||||
REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
|
||||
(void) stuff;
|
||||
|
||||
for (int i = 0; i < screenInfo.numScreens; i++) {
|
||||
if (!dri3_screen_can_one_point_two(screenInfo.screens[i])) {
|
||||
rep.minorVersion = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < screenInfo.numGPUScreens; i++) {
|
||||
if (!dri3_screen_can_one_point_two(screenInfo.gpuscreens[i])) {
|
||||
rep.minorVersion = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* From DRI3 proto:
|
||||
*
|
||||
* The client sends the highest supported version to the server
|
||||
* and the server sends the highest version it supports, but no
|
||||
* higher than the requested version.
|
||||
*/
|
||||
|
||||
if (rep.majorVersion > stuff->majorVersion ||
|
||||
(rep.majorVersion == stuff->majorVersion &&
|
||||
rep.minorVersion > stuff->minorVersion)) {
|
||||
rep.majorVersion = stuff->majorVersion;
|
||||
rep.minorVersion = stuff->minorVersion;
|
||||
}
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
@@ -92,7 +135,7 @@ proc_dri3_open(ClientPtr client)
|
||||
|
||||
REQUEST_SIZE_MATCH(xDRI3OpenReq);
|
||||
|
||||
status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixReadAccess);
|
||||
status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
|
||||
if (status != Success)
|
||||
return status;
|
||||
|
||||
@@ -124,6 +167,7 @@ proc_dri3_pixmap_from_buffer(ClientPtr client)
|
||||
int fd;
|
||||
DrawablePtr drawable;
|
||||
PixmapPtr pixmap;
|
||||
CARD32 stride, offset;
|
||||
int rc;
|
||||
|
||||
SetReqFds(client, 1);
|
||||
@@ -159,11 +203,14 @@ proc_dri3_pixmap_from_buffer(ClientPtr client)
|
||||
if (fd < 0)
|
||||
return BadValue;
|
||||
|
||||
rc = dri3_pixmap_from_fd(&pixmap,
|
||||
drawable->pScreen, fd,
|
||||
stuff->width, stuff->height,
|
||||
stuff->stride, stuff->depth,
|
||||
stuff->bpp);
|
||||
offset = 0;
|
||||
stride = stuff->stride;
|
||||
rc = dri3_pixmap_from_fds(&pixmap,
|
||||
drawable->pScreen, 1, &fd,
|
||||
stuff->width, stuff->height,
|
||||
&stride, &offset,
|
||||
stuff->depth, stuff->bpp,
|
||||
DRM_FORMAT_MOD_INVALID);
|
||||
close (fd);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
@@ -211,9 +258,9 @@ proc_dri3_buffer_from_pixmap(ClientPtr client)
|
||||
rep.depth = pixmap->drawable.depth;
|
||||
rep.bpp = pixmap->drawable.bitsPerPixel;
|
||||
|
||||
rc = dri3_fd_from_pixmap(&fd, pixmap, &rep.stride, &rep.size);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
fd = dri3_fd_from_pixmap(pixmap, &rep.stride, &rep.size);
|
||||
if (fd < 0)
|
||||
return BadPixmap;
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
@@ -299,6 +346,218 @@ proc_dri3_fd_from_fence(ClientPtr client)
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_dri3_get_supported_modifiers(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3GetSupportedModifiersReq);
|
||||
xDRI3GetSupportedModifiersReply rep = {
|
||||
.type = X_Reply,
|
||||
.sequenceNumber = client->sequence,
|
||||
};
|
||||
WindowPtr window;
|
||||
ScreenPtr pScreen;
|
||||
CARD64 *window_modifiers = NULL;
|
||||
CARD64 *screen_modifiers = NULL;
|
||||
CARD32 nwindowmodifiers = 0;
|
||||
CARD32 nscreenmodifiers = 0;
|
||||
int status;
|
||||
int i;
|
||||
|
||||
REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
|
||||
|
||||
status = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
|
||||
if (status != Success)
|
||||
return status;
|
||||
pScreen = window->drawable.pScreen;
|
||||
|
||||
dri3_get_supported_modifiers(pScreen, &window->drawable,
|
||||
stuff->depth, stuff->bpp,
|
||||
&nwindowmodifiers, &window_modifiers,
|
||||
&nscreenmodifiers, &screen_modifiers);
|
||||
|
||||
rep.numWindowModifiers = nwindowmodifiers;
|
||||
rep.numScreenModifiers = nscreenmodifiers;
|
||||
rep.length = bytes_to_int32(rep.numWindowModifiers * sizeof(CARD64)) +
|
||||
bytes_to_int32(rep.numScreenModifiers * sizeof(CARD64));
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swapl(&rep.numWindowModifiers);
|
||||
swapl(&rep.numScreenModifiers);
|
||||
for (i = 0; i < nwindowmodifiers; i++)
|
||||
swapll(&window_modifiers[i]);
|
||||
for (i = 0; i < nscreenmodifiers; i++)
|
||||
swapll(&screen_modifiers[i]);
|
||||
}
|
||||
|
||||
WriteToClient(client, sizeof(rep), &rep);
|
||||
WriteToClient(client, nwindowmodifiers * sizeof(CARD64), window_modifiers);
|
||||
WriteToClient(client, nscreenmodifiers * sizeof(CARD64), screen_modifiers);
|
||||
|
||||
free(window_modifiers);
|
||||
free(screen_modifiers);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_dri3_pixmap_from_buffers(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3PixmapFromBuffersReq);
|
||||
int fds[4];
|
||||
CARD32 strides[4], offsets[4];
|
||||
ScreenPtr screen;
|
||||
WindowPtr window;
|
||||
PixmapPtr pixmap;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
SetReqFds(client, stuff->num_buffers);
|
||||
REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
|
||||
LEGAL_NEW_RESOURCE(stuff->pixmap, client);
|
||||
rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
|
||||
if (rc != Success) {
|
||||
client->errorValue = stuff->window;
|
||||
return rc;
|
||||
}
|
||||
screen = window->drawable.pScreen;
|
||||
|
||||
if (!stuff->width || !stuff->height || !stuff->bpp || !stuff->depth) {
|
||||
client->errorValue = 0;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
if (stuff->width > 32767 || stuff->height > 32767)
|
||||
return BadAlloc;
|
||||
|
||||
if (stuff->depth != 1) {
|
||||
DepthPtr depth = screen->allowedDepths;
|
||||
int j;
|
||||
for (j = 0; j < screen->numDepths; j++, depth++)
|
||||
if (depth->depth == stuff->depth)
|
||||
break;
|
||||
if (j == screen->numDepths) {
|
||||
client->errorValue = stuff->depth;
|
||||
return BadValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stuff->num_buffers || stuff->num_buffers > 4) {
|
||||
client->errorValue = stuff->num_buffers;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
for (i = 0; i < stuff->num_buffers; i++) {
|
||||
fds[i] = ReadFdFromClient(client);
|
||||
if (fds[i] < 0) {
|
||||
while (--i >= 0)
|
||||
close(fds[i]);
|
||||
return BadValue;
|
||||
}
|
||||
}
|
||||
|
||||
strides[0] = stuff->stride0;
|
||||
strides[1] = stuff->stride1;
|
||||
strides[2] = stuff->stride2;
|
||||
strides[3] = stuff->stride3;
|
||||
offsets[0] = stuff->offset0;
|
||||
offsets[1] = stuff->offset1;
|
||||
offsets[2] = stuff->offset2;
|
||||
offsets[3] = stuff->offset3;
|
||||
|
||||
rc = dri3_pixmap_from_fds(&pixmap, screen,
|
||||
stuff->num_buffers, fds,
|
||||
stuff->width, stuff->height,
|
||||
strides, offsets,
|
||||
stuff->depth, stuff->bpp,
|
||||
stuff->modifier);
|
||||
|
||||
for (i = 0; i < stuff->num_buffers; i++)
|
||||
close (fds[i]);
|
||||
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
|
||||
pixmap->drawable.id = stuff->pixmap;
|
||||
|
||||
/* security creation/labeling check */
|
||||
rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
|
||||
pixmap, RT_NONE, NULL, DixCreateAccess);
|
||||
|
||||
if (rc != Success) {
|
||||
(*screen->DestroyPixmap) (pixmap);
|
||||
return rc;
|
||||
}
|
||||
if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
|
||||
return BadAlloc;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_dri3_buffers_from_pixmap(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3BuffersFromPixmapReq);
|
||||
xDRI3BuffersFromPixmapReply rep = {
|
||||
.type = X_Reply,
|
||||
.sequenceNumber = client->sequence,
|
||||
};
|
||||
int rc;
|
||||
int fds[4];
|
||||
int num_fds;
|
||||
uint32_t strides[4], offsets[4];
|
||||
uint64_t modifier;
|
||||
int i;
|
||||
PixmapPtr pixmap;
|
||||
|
||||
REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq);
|
||||
rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
|
||||
client, DixWriteAccess);
|
||||
if (rc != Success) {
|
||||
client->errorValue = stuff->pixmap;
|
||||
return rc;
|
||||
}
|
||||
|
||||
num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets, &modifier);
|
||||
if (num_fds == 0)
|
||||
return BadPixmap;
|
||||
|
||||
rep.nfd = num_fds;
|
||||
rep.length = bytes_to_int32(num_fds * 2 * sizeof(CARD32));
|
||||
rep.width = pixmap->drawable.width;
|
||||
rep.height = pixmap->drawable.height;
|
||||
rep.depth = pixmap->drawable.depth;
|
||||
rep.bpp = pixmap->drawable.bitsPerPixel;
|
||||
rep.modifier = modifier;
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swaps(&rep.width);
|
||||
swaps(&rep.height);
|
||||
swapll(&rep.modifier);
|
||||
for (i = 0; i < num_fds; i++) {
|
||||
swapl(&strides[i]);
|
||||
swapl(&offsets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_fds; i++) {
|
||||
if (WriteFdToClient(client, fds[i], TRUE) < 0) {
|
||||
while (i--)
|
||||
close(fds[i]);
|
||||
return BadAlloc;
|
||||
}
|
||||
}
|
||||
|
||||
WriteToClient(client, sizeof(rep), &rep);
|
||||
WriteToClient(client, num_fds * sizeof(CARD32), strides);
|
||||
WriteToClient(client, num_fds * sizeof(CARD32), offsets);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
|
||||
proc_dri3_query_version, /* 0 */
|
||||
proc_dri3_open, /* 1 */
|
||||
@@ -306,6 +565,9 @@ int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
|
||||
proc_dri3_buffer_from_pixmap, /* 3 */
|
||||
proc_dri3_fence_from_fd, /* 4 */
|
||||
proc_dri3_fd_from_fence, /* 5 */
|
||||
proc_dri3_get_supported_modifiers, /* 6 */
|
||||
proc_dri3_pixmap_from_buffers, /* 7 */
|
||||
proc_dri3_buffers_from_pixmap, /* 8 */
|
||||
};
|
||||
|
||||
int
|
||||
@@ -319,7 +581,7 @@ proc_dri3_dispatch(ClientPtr client)
|
||||
return (*proc_dri3_vector[stuff->data]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
static int _X_COLD
|
||||
sproc_dri3_query_version(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3QueryVersionReq);
|
||||
@@ -331,7 +593,7 @@ sproc_dri3_query_version(ClientPtr client)
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
static int _X_COLD
|
||||
sproc_dri3_open(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3OpenReq);
|
||||
@@ -343,7 +605,7 @@ sproc_dri3_open(ClientPtr client)
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
static int _X_COLD
|
||||
sproc_dri3_pixmap_from_buffer(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3PixmapFromBufferReq);
|
||||
@@ -359,7 +621,7 @@ sproc_dri3_pixmap_from_buffer(ClientPtr client)
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
static int _X_COLD
|
||||
sproc_dri3_buffer_from_pixmap(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3BufferFromPixmapReq);
|
||||
@@ -370,7 +632,7 @@ sproc_dri3_buffer_from_pixmap(ClientPtr client)
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
static int _X_COLD
|
||||
sproc_dri3_fence_from_fd(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3FenceFromFDReq);
|
||||
@@ -382,7 +644,7 @@ sproc_dri3_fence_from_fd(ClientPtr client)
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
static int _X_COLD
|
||||
sproc_dri3_fd_from_fence(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3FDFromFenceReq);
|
||||
@@ -394,6 +656,51 @@ sproc_dri3_fd_from_fence(ClientPtr client)
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int _X_COLD
|
||||
sproc_dri3_get_supported_modifiers(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3GetSupportedModifiersReq);
|
||||
REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
swapl(&stuff->window);
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int _X_COLD
|
||||
sproc_dri3_pixmap_from_buffers(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3PixmapFromBuffersReq);
|
||||
REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
swapl(&stuff->pixmap);
|
||||
swapl(&stuff->window);
|
||||
swaps(&stuff->width);
|
||||
swaps(&stuff->height);
|
||||
swapl(&stuff->stride0);
|
||||
swapl(&stuff->offset0);
|
||||
swapl(&stuff->stride1);
|
||||
swapl(&stuff->offset1);
|
||||
swapl(&stuff->stride2);
|
||||
swapl(&stuff->offset2);
|
||||
swapl(&stuff->stride3);
|
||||
swapl(&stuff->offset3);
|
||||
swapll(&stuff->modifier);
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int _X_COLD
|
||||
sproc_dri3_buffers_from_pixmap(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3BuffersFromPixmapReq);
|
||||
REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
swapl(&stuff->pixmap);
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
|
||||
sproc_dri3_query_version, /* 0 */
|
||||
sproc_dri3_open, /* 1 */
|
||||
@@ -401,9 +708,12 @@ int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
|
||||
sproc_dri3_buffer_from_pixmap, /* 3 */
|
||||
sproc_dri3_fence_from_fd, /* 4 */
|
||||
sproc_dri3_fd_from_fence, /* 5 */
|
||||
sproc_dri3_get_supported_modifiers, /* 6 */
|
||||
sproc_dri3_pixmap_from_buffers, /* 7 */
|
||||
sproc_dri3_buffers_from_pixmap, /* 8 */
|
||||
};
|
||||
|
||||
int
|
||||
int _X_COLD
|
||||
sproc_dri3_dispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xReq);
|
||||
|
||||
@@ -29,48 +29,50 @@
|
||||
#include <misync.h>
|
||||
#include <misyncshm.h>
|
||||
#include <randrstr.h>
|
||||
|
||||
static inline Bool has_open(dri3_screen_info_ptr info) {
|
||||
if (info == NULL)
|
||||
return FALSE;
|
||||
|
||||
return info->open != NULL ||
|
||||
(info->version >= 1 && info->open_client != NULL);
|
||||
}
|
||||
#include <drm_fourcc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd)
|
||||
{
|
||||
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
|
||||
dri3_screen_info_ptr info = ds->info;
|
||||
int rc;
|
||||
const dri3_screen_info_rec *info = ds->info;
|
||||
|
||||
if (!has_open(info))
|
||||
if (info == NULL)
|
||||
return BadMatch;
|
||||
|
||||
if (info->version >= 1 && info->open_client != NULL)
|
||||
rc = (*info->open_client) (client, screen, provider, fd);
|
||||
else
|
||||
rc = (*info->open) (screen, provider, fd);
|
||||
return (*info->open_client) (client, screen, provider, fd);
|
||||
if (info->open != NULL)
|
||||
return (*info->open) (screen, provider, fd);
|
||||
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
|
||||
return Success;
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
int
|
||||
dri3_pixmap_from_fd(PixmapPtr *ppixmap, ScreenPtr screen, int fd,
|
||||
CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp)
|
||||
dri3_pixmap_from_fds(PixmapPtr *ppixmap, ScreenPtr screen,
|
||||
CARD8 num_fds, const int *fds,
|
||||
CARD16 width, CARD16 height,
|
||||
const CARD32 *strides, const CARD32 *offsets,
|
||||
CARD8 depth, CARD8 bpp, CARD64 modifier)
|
||||
{
|
||||
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
|
||||
dri3_screen_info_ptr info = ds->info;
|
||||
const dri3_screen_info_rec *info = ds->info;
|
||||
PixmapPtr pixmap;
|
||||
|
||||
if (!info || !info->pixmap_from_fd)
|
||||
if (!info)
|
||||
return BadImplementation;
|
||||
|
||||
pixmap = (*info->pixmap_from_fd) (screen, fd, width, height, stride, depth, bpp);
|
||||
if (info->version >= 2 && info->pixmap_from_fds != NULL) {
|
||||
pixmap = (*info->pixmap_from_fds) (screen, num_fds, fds, width, height,
|
||||
strides, offsets, depth, bpp, modifier);
|
||||
} else if (info->pixmap_from_fd != NULL && num_fds == 1) {
|
||||
pixmap = (*info->pixmap_from_fd) (screen, fds[0], width, height,
|
||||
strides[0], depth, bpp);
|
||||
} else {
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
if (!pixmap)
|
||||
return BadAlloc;
|
||||
|
||||
@@ -79,20 +81,230 @@ dri3_pixmap_from_fd(PixmapPtr *ppixmap, ScreenPtr screen, int fd,
|
||||
}
|
||||
|
||||
int
|
||||
dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
|
||||
dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds,
|
||||
uint32_t *strides, uint32_t *offsets,
|
||||
uint64_t *modifier)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
|
||||
dri3_screen_info_ptr info = ds->info;
|
||||
int fd;
|
||||
const dri3_screen_info_rec *info = ds->info;
|
||||
|
||||
if (!info || !info->fd_from_pixmap)
|
||||
if (!info)
|
||||
return 0;
|
||||
|
||||
if (info->version >= 2 && info->fds_from_pixmap != NULL) {
|
||||
return (*info->fds_from_pixmap)(screen, pixmap, fds, strides, offsets,
|
||||
modifier);
|
||||
} else if (info->fd_from_pixmap != NULL) {
|
||||
CARD16 stride;
|
||||
CARD32 size;
|
||||
|
||||
fds[0] = (*info->fd_from_pixmap)(screen, pixmap, &stride, &size);
|
||||
if (fds[0] < 0)
|
||||
return 0;
|
||||
|
||||
strides[0] = stride;
|
||||
offsets[0] = 0;
|
||||
*modifier = DRM_FORMAT_MOD_INVALID;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dri3_fd_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
|
||||
const dri3_screen_info_rec *info = ds->info;
|
||||
uint32_t strides[4];
|
||||
uint32_t offsets[4];
|
||||
uint64_t modifier;
|
||||
int fds[4];
|
||||
int num_fds;
|
||||
|
||||
if (!info)
|
||||
return -1;
|
||||
|
||||
/* Preferentially use the old interface, allowing the implementation to
|
||||
* ensure the buffer is in a single-plane format which doesn't need
|
||||
* modifiers. */
|
||||
if (info->fd_from_pixmap != NULL)
|
||||
return (*info->fd_from_pixmap)(screen, pixmap, stride, size);
|
||||
|
||||
if (info->version < 2 || info->fds_from_pixmap == NULL)
|
||||
return -1;
|
||||
|
||||
/* If using the new interface, make sure that it's a single plane starting
|
||||
* at 0 within the BO. We don't check the modifier, as the client may
|
||||
* have an auxiliary mechanism for determining the modifier itself. */
|
||||
num_fds = info->fds_from_pixmap(screen, pixmap, fds, strides, offsets,
|
||||
&modifier);
|
||||
if (num_fds != 1 || offsets[0] != 0) {
|
||||
int i;
|
||||
for (i = 0; i < num_fds; i++)
|
||||
close(fds[i]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*stride = strides[0];
|
||||
*size = size[0];
|
||||
return fds[0];
|
||||
}
|
||||
|
||||
static int
|
||||
cache_formats_and_modifiers(ScreenPtr screen)
|
||||
{
|
||||
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
|
||||
const dri3_screen_info_rec *info = ds->info;
|
||||
CARD32 num_formats;
|
||||
CARD32 *formats;
|
||||
uint32_t num_modifiers;
|
||||
uint64_t *modifiers;
|
||||
int i;
|
||||
|
||||
if (ds->formats_cached)
|
||||
return Success;
|
||||
|
||||
if (!info)
|
||||
return BadImplementation;
|
||||
|
||||
fd = (*info->fd_from_pixmap)(screen, pixmap, stride, size);
|
||||
if (fd < 0)
|
||||
if (info->version < 2 || !info->get_formats || !info->get_modifiers) {
|
||||
ds->formats = NULL;
|
||||
ds->num_formats = 0;
|
||||
ds->formats_cached = TRUE;
|
||||
return Success;
|
||||
}
|
||||
|
||||
if (!info->get_formats(screen, &num_formats, &formats))
|
||||
return BadAlloc;
|
||||
*pfd = fd;
|
||||
|
||||
if (!num_formats) {
|
||||
ds->num_formats = 0;
|
||||
ds->formats_cached = TRUE;
|
||||
return Success;
|
||||
}
|
||||
|
||||
ds->formats = calloc(num_formats, sizeof(dri3_dmabuf_format_rec));
|
||||
if (!ds->formats)
|
||||
return BadAlloc;
|
||||
|
||||
for (i = 0; i < num_formats; i++) {
|
||||
dri3_dmabuf_format_ptr iter = &ds->formats[i];
|
||||
|
||||
if (!info->get_modifiers(screen, formats[i],
|
||||
&num_modifiers,
|
||||
&modifiers))
|
||||
continue;
|
||||
|
||||
if (!num_modifiers)
|
||||
continue;
|
||||
|
||||
iter->format = formats[i];
|
||||
iter->num_modifiers = num_modifiers;
|
||||
iter->modifiers = modifiers;
|
||||
}
|
||||
|
||||
ds->num_formats = i;
|
||||
ds->formats_cached = TRUE;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable,
|
||||
CARD8 depth, CARD8 bpp,
|
||||
CARD32 *num_intersect_modifiers,
|
||||
CARD64 **intersect_modifiers,
|
||||
CARD32 *num_screen_modifiers,
|
||||
CARD64 **screen_modifiers)
|
||||
{
|
||||
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
|
||||
const dri3_screen_info_rec *info = ds->info;
|
||||
int i, j;
|
||||
int ret;
|
||||
uint32_t num_drawable_mods;
|
||||
uint64_t *drawable_mods;
|
||||
CARD64 *intersect_mods = NULL;
|
||||
CARD64 *screen_mods = NULL;
|
||||
CARD32 format;
|
||||
dri3_dmabuf_format_ptr screen_format = NULL;
|
||||
|
||||
ret = cache_formats_and_modifiers(screen);
|
||||
if (ret != Success)
|
||||
return ret;
|
||||
|
||||
format = drm_format_for_depth(depth, bpp);
|
||||
if (format == 0)
|
||||
return BadValue;
|
||||
|
||||
/* Find screen-global modifiers from cache
|
||||
*/
|
||||
for (i = 0; i < ds->num_formats; i++) {
|
||||
if (ds->formats[i].format == format) {
|
||||
screen_format = &ds->formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (screen_format == NULL)
|
||||
return BadMatch;
|
||||
|
||||
if (screen_format->num_modifiers == 0) {
|
||||
*num_screen_modifiers = 0;
|
||||
*num_intersect_modifiers = 0;
|
||||
return Success;
|
||||
}
|
||||
|
||||
if (!info->get_drawable_modifiers ||
|
||||
!info->get_drawable_modifiers(drawable, format,
|
||||
&num_drawable_mods,
|
||||
&drawable_mods)) {
|
||||
num_drawable_mods = 0;
|
||||
drawable_mods = NULL;
|
||||
}
|
||||
|
||||
/* We're allocating slightly more memory than necessary but it reduces
|
||||
* the complexity of finding the intersection set.
|
||||
*/
|
||||
screen_mods = malloc(screen_format->num_modifiers * sizeof(CARD64));
|
||||
if (!screen_mods)
|
||||
return BadAlloc;
|
||||
if (num_drawable_mods > 0) {
|
||||
intersect_mods = malloc(screen_format->num_modifiers * sizeof(CARD64));
|
||||
if (!intersect_mods) {
|
||||
free(screen_mods);
|
||||
return BadAlloc;
|
||||
}
|
||||
}
|
||||
|
||||
*num_screen_modifiers = 0;
|
||||
*num_intersect_modifiers = 0;
|
||||
for (i = 0; i < screen_format->num_modifiers; i++) {
|
||||
CARD64 modifier = screen_format->modifiers[i];
|
||||
Bool intersect = FALSE;
|
||||
|
||||
for (j = 0; j < num_drawable_mods; j++) {
|
||||
if (drawable_mods[j] == modifier) {
|
||||
intersect = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (intersect) {
|
||||
intersect_mods[*num_intersect_modifiers] = modifier;
|
||||
*num_intersect_modifiers += 1;
|
||||
} else {
|
||||
screen_mods[*num_screen_modifiers] = modifier;
|
||||
*num_screen_modifiers += 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert(*num_intersect_modifiers + *num_screen_modifiers == screen_format->num_modifiers);
|
||||
|
||||
*intersect_modifiers = intersect_mods;
|
||||
*screen_modifiers = screen_mods;
|
||||
free(drawable_mods);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user