aboutsummaryrefslogtreecommitdiff
path: root/xorg-server
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server')
-rw-r--r--xorg-server/config/config.c34
-rw-r--r--xorg-server/config/hal.c16
-rw-r--r--xorg-server/config/udev.c15
-rw-r--r--xorg-server/dix/devices.c3
-rw-r--r--xorg-server/glamor/Makefile.am1
-rw-r--r--xorg-server/glamor/glamor.c17
-rw-r--r--xorg-server/glamor/glamor.h1
-rw-r--r--xorg-server/glamor/glamor_gradient.c5
-rw-r--r--xorg-server/glamor/glamor_pixmap.c3
-rw-r--r--xorg-server/glamor/glamor_priv.h25
-rw-r--r--xorg-server/glamor/glamor_render.c108
-rw-r--r--xorg-server/glamor/glamor_trapezoid.c128
-rw-r--r--xorg-server/glamor/glamor_utils.h2
-rw-r--r--xorg-server/glamor/glamor_vbo.c186
-rw-r--r--xorg-server/glx/glxdricommon.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.c22
-rw-r--r--xorg-server/hw/xfree86/common/xf86platformBus.c28
-rw-r--r--xorg-server/hw/xfree86/common/xf86str.h3
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/systemd-logind.c3
-rw-r--r--xorg-server/include/systemd-logind.h4
-rw-r--r--xorg-server/include/xkbsrv.h4
-rw-r--r--xorg-server/test/hashtabletest.c2
-rw-r--r--xorg-server/xkb/xkbActions.c102
23 files changed, 479 insertions, 235 deletions
diff --git a/xorg-server/config/config.c b/xorg-server/config/config.c
index 7971b8740..46f2532ec 100644
--- a/xorg-server/config/config.c
+++ b/xorg-server/config/config.c
@@ -159,23 +159,38 @@ config_odev_find_attribute(struct OdevAttributes *attribs, int attrib_id)
return NULL;
}
+static struct OdevAttribute *
+config_odev_find_or_add_attribute(struct OdevAttributes *attribs, int attrib)
+{
+ struct OdevAttribute *oa;
+
+ oa = config_odev_find_attribute(attribs, attrib);
+ if (oa)
+ return oa;
+
+ oa = calloc(1, sizeof(struct OdevAttribute));
+ if (!oa)
+ return oa;
+
+ oa->attrib_id = attrib;
+ xorg_list_append(&oa->member, &attribs->list);
+
+ return oa;
+}
+
Bool
config_odev_add_attribute(struct OdevAttributes *attribs, int attrib,
const char *attrib_name)
{
struct OdevAttribute *oa;
- oa = config_odev_find_attribute(attribs, attrib);
- if (!oa)
- oa = calloc(1, sizeof(struct OdevAttribute));
+ oa = config_odev_find_or_add_attribute(attribs, attrib);
if (!oa)
return FALSE;
- oa->attrib_id = attrib;
free(oa->attrib_name);
oa->attrib_name = strdup(attrib_name);
oa->attrib_type = ODEV_ATTRIB_STRING;
- xorg_list_append(&oa->member, &attribs->list);
return TRUE;
}
@@ -185,16 +200,12 @@ config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib,
{
struct OdevAttribute *oa;
- oa = config_odev_find_attribute(attribs, attrib);
- if (!oa)
- oa = calloc(1, sizeof(struct OdevAttribute));
+ oa = config_odev_find_or_add_attribute(attribs, attrib);
if (!oa)
return FALSE;
- oa->attrib_id = attrib;
oa->attrib_value = attrib_value;
oa->attrib_type = ODEV_ATTRIB_INT;
- xorg_list_append(&oa->member, &attribs->list);
return TRUE;
}
@@ -246,7 +257,8 @@ config_odev_free_attributes(struct OdevAttributes *attribs)
case ODEV_ATTRIB_FD: fd = iter->attrib_value; break;
}
xorg_list_del(&iter->member);
- free(iter->attrib_name);
+ if (iter->attrib_type == ODEV_ATTRIB_STRING)
+ free(iter->attrib_name);
free(iter);
}
diff --git a/xorg-server/config/hal.c b/xorg-server/config/hal.c
index 94cb6e7cd..ea574ca52 100644
--- a/xorg-server/config/hal.c
+++ b/xorg-server/config/hal.c
@@ -185,8 +185,7 @@ device_added(LibHalContext * hal_ctx, const char *udi)
parent = get_prop_string(hal_ctx, udi, "info.parent");
if (parent) {
int usb_vendor, usb_product;
-
- attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id");
+ char *old_parent;
/* construct USB ID in lowercase - "0000:ffff" */
usb_vendor = libhal_device_get_property_int(hal_ctx, parent,
@@ -204,7 +203,18 @@ device_added(LibHalContext * hal_ctx, const char *udi)
== -1)
attrs.usb_id = NULL;
- free(parent);
+ attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id");
+ old_parent = parent;
+
+ while (!attrs.pnp_id &&
+ (parent = get_prop_string(hal_ctx, parent, "info.parent"))) {
+ attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id");
+
+ free(old_parent);
+ old_parent = parent;
+ }
+
+ free(old_parent);
}
input_options = input_option_new(NULL, "_source", "server/hal");
diff --git a/xorg-server/config/udev.c b/xorg-server/config/udev.c
index d70eeb48c..d88abaaa1 100644
--- a/xorg-server/config/udev.c
+++ b/xorg-server/config/udev.c
@@ -149,10 +149,6 @@ device_added(struct udev_device *udev_device)
LOG_PROPERTY(ppath, "NAME", name);
}
- if (pnp_id)
- attrs.pnp_id = strdup(pnp_id);
- LOG_SYSATTR(ppath, "id", pnp_id);
-
/* construct USB ID in lowercase hex - "0000:ffff" */
if (product &&
sscanf(product, "%*x/%4x/%4x/%*x", &usb_vendor, &usb_model) == 2) {
@@ -164,6 +160,17 @@ device_added(struct udev_device *udev_device)
LOG_PROPERTY(ppath, "PRODUCT", product);
attrs.usb_id = usb_id;
}
+
+ while (!pnp_id && (parent = udev_device_get_parent(parent))) {
+ pnp_id = udev_device_get_sysattr_value(parent, "id");
+ if (!pnp_id)
+ continue;
+
+ attrs.pnp_id = strdup(pnp_id);
+ ppath = udev_device_get_devnode(parent);
+ LOG_SYSATTR(ppath, "id", pnp_id);
+ }
+
}
if (!name)
name = "(unnamed)";
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c
index 1c86d5242..ab923d574 100644
--- a/xorg-server/dix/devices.c
+++ b/xorg-server/dix/devices.c
@@ -416,6 +416,8 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
XISendDeviceHierarchyEvent(flags);
}
+ if (!IsMaster(dev))
+ XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0);
RecalculateMasterButtons(dev);
/* initialise an idle timer for this device*/
@@ -2649,6 +2651,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
dev->spriteInfo->paired = master;
dev->spriteInfo->spriteOwner = FALSE;
+ XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0);
RecalculateMasterButtons(master);
}
diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am
index 77492bcaa..ffc8c23d8 100644
--- a/xorg-server/glamor/Makefile.am
+++ b/xorg-server/glamor/Makefile.am
@@ -34,6 +34,7 @@ libglamor_la_SOURCES = \
glamor_pixmap.c\
glamor_largepixmap.c\
glamor_picture.c\
+ glamor_vbo.c \
glamor_window.c\
glamor_fbo.c\
glamor_compositerects.c\
diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c
index fa753bb1a..e85617927 100644
--- a/xorg-server/glamor/glamor.c
+++ b/xorg-server/glamor/glamor.c
@@ -319,6 +319,19 @@ glamor_init(ScreenPtr screen, unsigned int flags)
gl_version = glamor_gl_get_version();
+ /* We'd like to require GL_ARB_map_buffer_range or
+ * GL_OES_map_buffer_range, since it offers more information to
+ * the driver than plain old glMapBuffer() or glBufferSubData().
+ * It's been supported on Mesa on the desktop since 2009 and on
+ * GLES2 since October 2012. It's supported on Apple's iOS
+ * drivers for SGX535 and A7, but apparently not on most Android
+ * devices (the OES extension spec wasn't released until June
+ * 2012).
+ *
+ * 82% of 0 A.D. players (desktop GL) submitting hardware reports
+ * have support for it, with most of the ones lacking it being on
+ * Windows with Intel 4-series (G45) graphics or older.
+ */
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
ErrorF("Require OpenGL version 1.3 or later.\n");
@@ -340,6 +353,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_gl_has_extension("GL_MESA_pack_invert");
glamor_priv->has_fbo_blit =
glamor_gl_has_extension("GL_EXT_framebuffer_blit");
+ glamor_priv->has_buffer_storage =
+ glamor_gl_has_extension("GL_ARB_buffer_storage");
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
#ifdef MAX_FBO_SIZE
glamor_priv->max_fbo_size = MAX_FBO_SIZE;
@@ -426,6 +441,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
ps->DestroyPicture = glamor_destroy_picture;
glamor_init_composite_shaders(screen);
#endif
+ glamor_init_vbo(screen);
glamor_init_pixmap_fbo(screen);
glamor_init_solid_shader(screen);
glamor_init_tile_shader(screen);
@@ -465,6 +481,7 @@ glamor_release_screen_priv(ScreenPtr screen)
#ifdef RENDER
glamor_fini_composite_shaders(screen);
#endif
+ glamor_fini_vbo(screen);
glamor_fini_pixmap_fbo(screen);
glamor_fini_solid_shader(screen);
glamor_fini_tile_shader(screen);
diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h
index e12f497cb..e25dc735c 100644
--- a/xorg-server/glamor/glamor.h
+++ b/xorg-server/glamor/glamor.h
@@ -324,6 +324,7 @@ extern _X_EXPORT int glamor_create_gc(GCPtr gc);
extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes,
DrawablePtr drawable);
+
/* Glamor rendering/drawing functions with XXX_nf.
* nf means no fallback within glamor internal if possible. If glamor
* fail to accelerate the operation, glamor will return a false, and the
diff --git a/xorg-server/glamor/glamor_gradient.c b/xorg-server/glamor/glamor_gradient.c
index 9f6f1b1cf..6a7b528f9 100644
--- a/xorg-server/glamor/glamor_gradient.c
+++ b/xorg-server/glamor/glamor_gradient.c
@@ -46,8 +46,6 @@ static const char *
_glamor_create_getcolor_fs_source(ScreenPtr screen, int stops_count,
int use_array)
{
- glamor_screen_private *glamor_priv;
-
char *gradient_fs = NULL;
#define gradient_fs_getcolor\
@@ -174,9 +172,6 @@ _glamor_create_getcolor_fs_source(ScreenPtr screen, int stops_count,
" return gradient_color;\n"
"}\n";
- glamor_priv = glamor_get_screen_private(screen);
- glamor_get_context(glamor_priv);
-
if (use_array) {
XNFasprintf(&gradient_fs,
gradient_fs_getcolor, stops_count, stops_count);
diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c
index 77197b5d1..119e4d9d1 100644
--- a/xorg-server/glamor/glamor_pixmap.c
+++ b/xorg-server/glamor/glamor_pixmap.c
@@ -697,7 +697,6 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
* Upload pixmap to a specified texture.
* This texture may not be the one attached to it.
**/
-int in_restore = 0;
static void
__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
GLenum format,
@@ -1529,7 +1528,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
drawable = &pixmap_priv->base.pixmap->drawable;
- if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))
+ if (!GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv))
return TRUE;
old_fbo = pixmap_priv->base.fbo;
diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h
index fe4b42332..d15eabd9e 100644
--- a/xorg-server/glamor/glamor_priv.h
+++ b/xorg-server/glamor/glamor_priv.h
@@ -208,6 +208,7 @@ typedef struct glamor_screen_private {
enum glamor_gl_flavor gl_flavor;
int has_pack_invert;
int has_fbo_blit;
+ int has_buffer_storage;
int max_fbo_size;
struct xorg_list
@@ -220,8 +221,15 @@ typedef struct glamor_screen_private {
/* vertext/elment_index buffer object for render */
GLuint vbo, ebo;
+ /** Next offset within the VBO that glamor_get_vbo_space() will use. */
int vbo_offset;
int vbo_size;
+ /**
+ * Pointer to glamor_get_vbo_space()'s current VBO mapping.
+ *
+ * Note that this is not necessarily equal to the pointer returned
+ * by glamor_get_vbo_space(), so it can't be used in place of that.
+ */
char *vb;
int vb_stride;
Bool has_source_coords, has_mask_coords;
@@ -702,11 +710,7 @@ void glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
glamor_composite_shader *shader,
struct blendinfo *op_info);
-void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
-void glamor_emit_composite_vert(ScreenPtr screen,
- const float *src_coords,
- const float *mask_coords,
- const float *dst_coords, int i);
+void *glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
/* glamor_trapezoid.c */
void glamor_trapezoids(CARD8 op,
@@ -748,6 +752,17 @@ void glamor_triangles(CARD8 op,
void glamor_pixmap_init(ScreenPtr screen);
void glamor_pixmap_fini(ScreenPtr screen);
+/* glamor_vbo.c */
+
+void glamor_init_vbo(ScreenPtr screen);
+void glamor_fini_vbo(ScreenPtr screen);
+
+void *
+glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset);
+
+void
+glamor_put_vbo_space(ScreenPtr screen);
+
/**
* Download a pixmap's texture to cpu memory. If success,
* One copy of current pixmap's texture will be put into
diff --git a/xorg-server/glamor/glamor_render.c b/xorg-server/glamor/glamor_render.c
index 093a2151d..086526d2e 100644
--- a/xorg-server/glamor/glamor_render.c
+++ b/xorg-server/glamor/glamor_render.c
@@ -403,12 +403,10 @@ glamor_init_composite_shaders(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
unsigned short *eb;
- float *vb = NULL;
int eb_size;
glamor_priv = glamor_get_screen_private(screen);
glamor_get_context(glamor_priv);
- glGenBuffers(1, &glamor_priv->vbo);
glGenBuffers(1, &glamor_priv->ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
@@ -419,9 +417,6 @@ glamor_init_composite_shaders(ScreenPtr screen)
eb = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
}
else {
- vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2);
- if (vb == NULL)
- FatalError("Failed to allocate vb memory.\n");
eb = malloc(eb_size);
}
@@ -438,14 +433,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
- glBufferData(GL_ARRAY_BUFFER,
- GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) *
- 2, NULL, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
free(eb);
- glamor_priv->vb = (char *) vb;
}
glamor_put_context(glamor_priv);
@@ -460,7 +448,6 @@ glamor_fini_composite_shaders(ScreenPtr screen)
glamor_priv = glamor_get_screen_private(screen);
glamor_get_context(glamor_priv);
- glDeleteBuffers(1, &glamor_priv->vbo);
glDeleteBuffers(1, &glamor_priv->ebo);
for (i = 0; i < SHADER_SOURCE_COUNT; i++)
@@ -470,8 +457,6 @@ glamor_fini_composite_shaders(ScreenPtr screen)
if (shader->prog)
glDeleteProgram(shader->prog);
}
- if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && glamor_priv->vb)
- free(glamor_priv->vb);
glamor_put_context(glamor_priv);
}
@@ -584,7 +569,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|| pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
if (picture->transform
- || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
+ || (GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv)))
repeat_type += RepeatFix;
}
if (repeat_type >= RepeatFix) {
@@ -701,11 +686,13 @@ glamor_composite_with_copy(CARD8 op,
return ret;
}
-void
+void *
glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
int vert_size;
+ char *vbo_offset;
+ float *vb;
glamor_priv->render_nr_verts = 0;
glamor_priv->vb_stride = 2 * sizeof(float);
@@ -717,78 +704,32 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
vert_size = n_verts * glamor_priv->vb_stride;
glamor_get_context(glamor_priv);
- glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
- glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
- glamor_priv->vb_stride;
- glamor_priv->vbo_offset = 0;
- glBufferData(GL_ARRAY_BUFFER,
- glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
- }
-
- glamor_priv->vb = glMapBufferRange(GL_ARRAY_BUFFER,
- glamor_priv->vbo_offset,
- vert_size,
- GL_MAP_WRITE_BIT |
- GL_MAP_UNSYNCHRONIZED_BIT);
- assert(glamor_priv->vb != NULL);
- glamor_priv->vb -= glamor_priv->vbo_offset;
- }
- else
- glamor_priv->vbo_offset = 0;
+ vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
- glamor_priv->vb_stride,
- (void *) ((long)
- glamor_priv->vbo_offset));
+ glamor_priv->vb_stride, vbo_offset);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
if (glamor_priv->has_source_coords) {
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
GL_FLOAT, GL_FALSE,
glamor_priv->vb_stride,
- (void *) ((long) glamor_priv->vbo_offset +
- 2 * sizeof(float)));
+ vbo_offset + 2 * sizeof(float));
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
}
if (glamor_priv->has_mask_coords) {
glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE,
glamor_priv->vb_stride,
- (void *) ((long) glamor_priv->vbo_offset +
- (glamor_priv->has_source_coords ?
- 4 : 2) * sizeof(float)));
+ vbo_offset + (glamor_priv->has_source_coords ?
+ 4 : 2) * sizeof(float));
glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
}
glamor_put_context(glamor_priv);
-}
-
-void
-glamor_emit_composite_vert(ScreenPtr screen,
- const float *src_coords,
- const float *mask_coords,
- const float *dst_coords, int i)
-{
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- float *vb = (float *) (glamor_priv->vb + glamor_priv->vbo_offset);
- int j = 0;
- vb[j++] = dst_coords[i * 2 + 0];
- vb[j++] = dst_coords[i * 2 + 1];
- if (glamor_priv->has_source_coords) {
- vb[j++] = src_coords[i * 2 + 0];
- vb[j++] = src_coords[i * 2 + 1];
- }
- if (glamor_priv->has_mask_coords) {
- vb[j++] = mask_coords[i * 2 + 0];
- vb[j++] = mask_coords[i * 2 + 1];
- }
-
- glamor_priv->render_nr_verts++;
- glamor_priv->vbo_offset += glamor_priv->vb_stride;
+ return vb;
}
static void
@@ -797,14 +738,6 @@ glamor_flush_composite_rects(ScreenPtr screen)
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_get_context(glamor_priv);
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
- glUnmapBuffer(GL_ARRAY_BUFFER);
- else {
-
- glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
- glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
- glamor_priv->vb, GL_DYNAMIC_DRAW);
- }
if (!glamor_priv->render_nr_verts)
return;
@@ -1250,14 +1183,12 @@ glamor_composite_with_shader(CARD8 op,
GLfloat dst_xscale, dst_yscale;
GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
struct shader_key key, key_ca;
- float *vertices;
int dest_x_off, dest_y_off;
int source_x_off, source_y_off;
int mask_x_off, mask_y_off;
PictFormatShort saved_source_format = 0;
float src_matrix[9], mask_matrix[9];
float *psrc_matrix = NULL, *pmask_matrix = NULL;
- int vert_stride = 4;
int nrect_max;
Bool ret = FALSE;
glamor_composite_shader *shader = NULL, *shader_ca = NULL;
@@ -1306,7 +1237,6 @@ glamor_composite_with_shader(CARD8 op,
psrc_matrix = src_matrix;
glamor_picture_get_matrixf(source, psrc_matrix);
}
- vert_stride += 4;
}
if (glamor_priv->has_mask_coords) {
@@ -1318,18 +1248,17 @@ glamor_composite_with_shader(CARD8 op,
pmask_matrix = mask_matrix;
glamor_picture_get_matrixf(mask, pmask_matrix);
}
- vert_stride += 4;
}
- nrect_max = (vert_stride * nrect) > GLAMOR_COMPOSITE_VBO_VERT_CNT ?
- (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nrect;
+ nrect_max = MIN(nrect, GLAMOR_COMPOSITE_VBO_VERT_CNT / 4);
while (nrect) {
int mrect, rect_processed;
int vb_stride;
+ float *vertices;
mrect = nrect > nrect_max ? nrect_max : nrect;
- glamor_setup_composite_vbo(screen, mrect * vert_stride);
+ vertices = glamor_setup_composite_vbo(screen, mrect * 4);
rect_processed = mrect;
vb_stride = glamor_priv->vb_stride / sizeof(float);
while (mrect--) {
@@ -1355,9 +1284,7 @@ glamor_composite_with_shader(CARD8 op,
("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n",
x_dest, y_dest, x_source, y_source, x_mask, y_mask, width,
height);
- vertices = (float *) (glamor_priv->vb + glamor_priv->vbo_offset);
- assert(glamor_priv->vbo_offset <
- glamor_priv->vbo_size - glamor_priv->vb_stride);
+
glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
dst_yscale, x_dest, y_dest,
x_dest + width, y_dest + height,
@@ -1385,11 +1312,15 @@ glamor_composite_with_shader(CARD8 op,
y_mask + height,
glamor_priv->yInverted,
vertices, vb_stride);
+ vertices += 2;
}
glamor_priv->render_nr_verts += 4;
- glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
rects++;
+
+ /* We've incremented by one of our 4 verts, now do the other 3. */
+ vertices += 3 * vb_stride;
}
+ glamor_put_vbo_space(screen);
glamor_flush_composite_rects(screen);
nrect -= rect_processed;
if (two_pass_ca) {
@@ -1402,7 +1333,6 @@ glamor_composite_with_shader(CARD8 op,
}
}
- glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
diff --git a/xorg-server/glamor/glamor_trapezoid.c b/xorg-server/glamor/glamor_trapezoid.c
index 7bc925a25..0064f2a24 100644
--- a/xorg-server/glamor/glamor_trapezoid.c
+++ b/xorg-server/glamor/glamor_trapezoid.c
@@ -190,14 +190,44 @@ point_inside_trapezoid(int point[2], xTrapezoid *trap, xFixed cut_y)
}
static void
+glamor_emit_composite_vert(ScreenPtr screen,
+ float *vb,
+ const float *src_coords,
+ const float *mask_coords,
+ const float *dst_coords, int i)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ int j = 0;
+
+ vb += i * glamor_priv->vb_stride / sizeof(float);
+
+ vb[j++] = dst_coords[i * 2 + 0];
+ vb[j++] = dst_coords[i * 2 + 1];
+ if (glamor_priv->has_source_coords) {
+ vb[j++] = src_coords[i * 2 + 0];
+ vb[j++] = src_coords[i * 2 + 1];
+ }
+ if (glamor_priv->has_mask_coords) {
+ vb[j++] = mask_coords[i * 2 + 0];
+ vb[j++] = mask_coords[i * 2 + 1];
+ }
+
+ glamor_priv->render_nr_verts++;
+}
+
+static void
glamor_emit_composite_triangle(ScreenPtr screen,
+ float *vb,
const float *src_coords,
const float *mask_coords,
const float *dst_coords)
{
- glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
- glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1);
- glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
+ glamor_emit_composite_vert(screen, vb,
+ src_coords, mask_coords, dst_coords, 0);
+ glamor_emit_composite_vert(screen, vb,
+ src_coords, mask_coords, dst_coords, 1);
+ glamor_emit_composite_vert(screen, vb,
+ src_coords, mask_coords, dst_coords, 2);
}
static void
@@ -206,14 +236,7 @@ glamor_flush_composite_triangles(ScreenPtr screen)
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_get_context(glamor_priv);
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
- glUnmapBuffer(GL_ARRAY_BUFFER);
- else {
-
- glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
- glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
- glamor_priv->vb, GL_DYNAMIC_DRAW);
- }
+ glamor_put_vbo_space(screen);
if (!glamor_priv->render_nr_verts)
return;
@@ -576,12 +599,14 @@ _glamor_clip_trapezoid_vertex(xTrapezoid *trap, BoxPtr pbox,
return TRUE;
}
-static void
+static void *
glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
int stride;
int vert_size;
+ char *vbo_offset;
+ void *vb;
glamor_priv->render_nr_verts = 0;
@@ -610,66 +635,43 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
- glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
- glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
- glamor_priv->vb_stride;
- glamor_priv->vbo_offset = 0;
- glBufferData(GL_ARRAY_BUFFER,
- glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
- }
-
- glamor_priv->vb = glMapBufferRange(GL_ARRAY_BUFFER,
- glamor_priv->vbo_offset,
- vert_size,
- GL_MAP_WRITE_BIT |
- GL_MAP_UNSYNCHRONIZED_BIT);
-
- assert(glamor_priv->vb != NULL);
- glamor_priv->vb -= glamor_priv->vbo_offset;
- }
- else {
- glamor_priv->vbo_offset = 0;
- }
+ vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
/* Set the vertex pointer. */
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
GL_FALSE, glamor_priv->vb_stride,
- (void *) ((long) glamor_priv->vbo_offset));
+ vbo_offset);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
stride = 2;
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
GL_FALSE, glamor_priv->vb_stride,
- (void *) ((long) glamor_priv->vbo_offset +
- stride * sizeof(float)));
+ vbo_offset + stride * sizeof(float));
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
stride += 2;
glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
- GL_FALSE, glamor_priv->vb_stride,
- (void *) ((long) glamor_priv->vbo_offset +
- stride * sizeof(float)));
+ GL_FALSE, glamor_priv->vb_stride,
+ vbo_offset + stride * sizeof(float));
glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
stride += 2;
glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
- GL_FALSE, glamor_priv->vb_stride,
- (void *) ((long) glamor_priv->vbo_offset +
- stride * sizeof(float)));
+ GL_FALSE, glamor_priv->vb_stride,
+ vbo_offset + stride * sizeof(float));
glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
stride += 4;
glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
- GL_FALSE, glamor_priv->vb_stride,
- (void *) ((long) glamor_priv->vbo_offset +
- stride * sizeof(float)));
+ GL_FALSE, glamor_priv->vb_stride,
+ vbo_offset + stride * sizeof(float));
glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
glamor_put_context(glamor_priv);
+
+ return vb;
}
static Bool
@@ -862,6 +864,8 @@ _glamor_trapezoids_with_shader(CARD8 op,
nclip_rect = nbox;
while (nclip_rect) {
+ float *vb;
+
mclip_rect = (nclip_rect * ntrap * 4) > ntriangle_per_loop ?
(ntriangle_per_loop / (4 * ntrap)) : nclip_rect;
@@ -879,8 +883,9 @@ _glamor_trapezoids_with_shader(CARD8 op,
NTRAPS_LOOP_AGAIN:
- glamor_setup_composite_vbo(screen,
- mclip_rect * traps_count * 4 * vert_stride);
+ vb = glamor_setup_composite_vbo(screen,
+ (mclip_rect * traps_count *
+ 4 * vert_stride));
clip_processed = mclip_rect;
while (mclip_rect--) {
@@ -938,8 +943,10 @@ _glamor_trapezoids_with_shader(CARD8 op,
source_texcoords[4], source_texcoords[5]);
}
- glamor_emit_composite_triangle(screen, source_texcoords,
+ glamor_emit_composite_triangle(screen, vb,
+ source_texcoords,
NULL, vertices);
+ vb += 3 * glamor_priv->vb_stride / sizeof(float);
}
}
@@ -970,7 +977,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
ret = TRUE;
TRAPEZOID_RESET_GL:
- glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
@@ -1384,7 +1390,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
BoxRec one_trap_bound;
int nrect_max;
int i, j;
- float *vertices;
float params[4];
glamor_priv = glamor_get_screen_private(screen);
@@ -1413,7 +1418,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
- glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
/* Now draw the Trapezoid mask. */
@@ -1425,11 +1429,12 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
nrect_max = GLAMOR_COMPOSITE_VBO_VERT_CNT / (4 * GLAMOR_VERTEX_RIGHT_PARAM);
for (i = 0; i < ntrap;) {
+ float *vertices;
int mrect;
int stride;
mrect = (ntrap - i) > nrect_max ? nrect_max : (ntrap - i);
- glamor_setup_composite_vbo_for_trapezoid(screen, 4 * mrect);
+ vertices = glamor_setup_composite_vbo_for_trapezoid(screen, 4 * mrect);
stride = glamor_priv->vb_stride / sizeof(float);
for (j = 0; j < mrect; j++) {
@@ -1452,8 +1457,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
miTrapezoidBounds(1, ptrap, &one_trap_bound);
- vertices =
- (float *) (glamor_priv->vb + glamor_priv->vbo_offset) + 2;
+ vertices += 2;
glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
(pixmap_priv->base.pixmap->drawable.height),
(one_trap_bound.x1), (one_trap_bound.y1),
@@ -1525,6 +1529,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
}
params[2] = right_slope;
glamor_set_const_ext(params, 4, vertices, 4, stride);
+ vertices += 4;
DEBUGF("trap_top = %f, trap_bottom = %f, "
"trap_left_x = %f, trap_left_y = %f, left_slope = %f, "
@@ -1537,23 +1542,17 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
((float) ptrap->right.p1.y) / 65536, right_slope);
glamor_priv->render_nr_verts += 4;
- glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
+ vertices += 3 * stride;
}
i += mrect;
+ glamor_put_vbo_space(screen);
+
/* Now rendering. */
if (!glamor_priv->render_nr_verts)
continue;
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
- glUnmapBuffer(GL_ARRAY_BUFFER);
- else {
- glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
- glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
- glamor_priv->vb, GL_DYNAMIC_DRAW);
- }
-
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
glDrawRangeElements(GL_TRIANGLES, 0,
glamor_priv->render_nr_verts,
@@ -1566,7 +1565,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
}
}
- glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
diff --git a/xorg-server/glamor/glamor_utils.h b/xorg-server/glamor/glamor_utils.h
index 9374c9d4d..f9550b73c 100644
--- a/xorg-server/glamor/glamor_utils.h
+++ b/xorg-server/glamor/glamor_utils.h
@@ -53,7 +53,7 @@
*(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height; \
} while(0)
-#define GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(priv) \
+#define GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(priv) \
(priv->base.fbo->width != priv->base.pixmap->drawable.width \
|| priv->base.fbo->height != priv->base.pixmap->drawable.height) \
diff --git a/xorg-server/glamor/glamor_vbo.c b/xorg-server/glamor/glamor_vbo.c
new file mode 100644
index 000000000..5e98bfe47
--- /dev/null
+++ b/xorg-server/glamor/glamor_vbo.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * @file glamor_vbo.c
+ *
+ * Helpers for managing streamed vertex bufffers used in glamor.
+ */
+
+#include "glamor_priv.h"
+
+/** Default size of the VBO, in bytes.
+ *
+ * If a single request is larger than this size, we'll resize the VBO
+ * and return an appropriate mapping, but we'll resize back down after
+ * that to avoid hogging that memory forever. We don't anticipate
+ * normal usage actually requiring larger VBO sizes.
+ */
+#define GLAMOR_VBO_SIZE (512 * 1024)
+
+/**
+ * Returns a pointer to @size bytes of VBO storage, which should be
+ * accessed by the GL using vbo_offset within the VBO.
+ */
+void *
+glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ void *data;
+
+ glamor_get_context(glamor_priv);
+
+ glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+
+ if (glamor_priv->has_buffer_storage) {
+ if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) {
+ if (glamor_priv->vbo_size)
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ if (size > glamor_priv->vbo_size) {
+ glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size);
+
+ /* We aren't allowed to resize glBufferStorage()
+ * buffers, so we need to gen a new one.
+ */
+ glDeleteBuffers(1, &glamor_priv->vbo);
+ glGenBuffers(1, &glamor_priv->vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+
+ assert(glGetError() == GL_NO_ERROR);
+ glBufferStorage(GL_ARRAY_BUFFER, glamor_priv->vbo_size, NULL,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_PERSISTENT_BIT |
+ GL_MAP_COHERENT_BIT);
+
+ if (glGetError() != GL_NO_ERROR) {
+ /* If the driver failed our coherent mapping, fall
+ * back to the ARB_mbr path.
+ */
+ glamor_priv->has_buffer_storage = false;
+ glamor_priv->vbo_size = 0;
+ glamor_put_context(glamor_priv);
+
+ return glamor_get_vbo_space(screen, size, vbo_offset);
+ }
+ }
+
+ glamor_priv->vbo_offset = 0;
+ glamor_priv->vb = glMapBufferRange(GL_ARRAY_BUFFER,
+ 0, glamor_priv->vbo_size,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_INVALIDATE_BUFFER_BIT |
+ GL_MAP_PERSISTENT_BIT |
+ GL_MAP_COHERENT_BIT);
+ }
+ *vbo_offset = (void *)(uintptr_t)glamor_priv->vbo_offset;
+ data = glamor_priv->vb + glamor_priv->vbo_offset;
+ glamor_priv->vbo_offset += size;
+ } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+ if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) {
+ glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size);
+ glamor_priv->vbo_offset = 0;
+ glBufferData(GL_ARRAY_BUFFER,
+ glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
+ }
+
+ data = glMapBufferRange(GL_ARRAY_BUFFER,
+ glamor_priv->vbo_offset,
+ size,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_UNSYNCHRONIZED_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT);
+ assert(data != NULL);
+ *vbo_offset = (char *)(uintptr_t)glamor_priv->vbo_offset;
+ glamor_priv->vbo_offset += size;
+ } else {
+ /* Return a pointer to the statically allocated non-VBO
+ * memory. We'll upload it through glBufferData() later.
+ */
+ if (glamor_priv->vbo_size < size) {
+ glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size);
+ free(glamor_priv->vb);
+ glamor_priv->vb = XNFalloc(size);
+ }
+ *vbo_offset = NULL;
+ /* We point to the start of glamor_priv->vb every time, and
+ * the vbo_offset determines the size of the glBufferData().
+ */
+ glamor_priv->vbo_offset = size;
+ data = glamor_priv->vb;
+ }
+
+ glamor_put_context(glamor_priv);
+
+ return data;
+}
+
+void
+glamor_put_vbo_space(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_get_context(glamor_priv);
+
+ if (glamor_priv->has_buffer_storage) {
+ /* If we're in the ARB_buffer_storage path, we have a
+ * persistent mapping, so we can leave it around until we
+ * reach the end of the buffer.
+ */
+ } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ } else {
+ glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
+ glamor_priv->vb, GL_DYNAMIC_DRAW);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glamor_put_context(glamor_priv);
+}
+
+void
+glamor_init_vbo(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_get_context(glamor_priv);
+
+ glGenBuffers(1, &glamor_priv->vbo);
+
+ glamor_put_context(glamor_priv);
+}
+
+void
+glamor_fini_vbo(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_get_context(glamor_priv);
+
+ glDeleteBuffers(1, &glamor_priv->vbo);
+ if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP)
+ free(glamor_priv->vb);
+
+ glamor_put_context(glamor_priv);
+}
diff --git a/xorg-server/glx/glxdricommon.c b/xorg-server/glx/glxdricommon.c
index 69d4b297e..62cce131d 100644
--- a/xorg-server/glx/glxdricommon.c
+++ b/xorg-server/glx/glxdricommon.c
@@ -132,7 +132,7 @@ createModeFromConfig(const __DRIcoreExtension * core,
unsigned int attrib, value;
int i;
- config = malloc(sizeof *config);
+ config = calloc(1, sizeof *config);
config->driConfig = driConfig;
diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c
index 7c3e479e5..36b92a9f7 100644
--- a/xorg-server/hw/xfree86/common/xf86Xinput.c
+++ b/xorg-server/hw/xfree86/common/xf86Xinput.c
@@ -81,6 +81,7 @@
#include <stdarg.h>
#include <stdint.h> /* for int64_t */
+#include <sys/stat.h>
#include <unistd.h>
#include "mi.h"
@@ -804,6 +805,18 @@ xf86InputDevicePostInit(DeviceIntPtr dev)
return Success;
}
+static void
+xf86stat(const char *path, int *maj, int *min)
+{
+ struct stat st;
+
+ if (stat(path, &st) == -1)
+ return;
+
+ *maj = major(st.st_rdev);
+ *min = minor(st.st_rdev);
+}
+
/**
* Create a new input device, activate and enable it.
*
@@ -828,6 +841,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
DeviceIntPtr dev = NULL;
Bool paused;
int rval;
+ const char *path;
/* Memory leak for every attached device if we don't
* test if the module is already loaded first */
@@ -841,9 +855,13 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
goto unwind;
}
- if (drv->capabilities & XI86_DRV_CAP_SERVER_FD) {
+ path = xf86CheckStrOption(pInfo->options, "Device", NULL);
+ if (path && pInfo->major == 0 && pInfo->minor == 0)
+ xf86stat(path, &pInfo->major, &pInfo->minor);
+
+ if (path && (drv->capabilities & XI86_DRV_CAP_SERVER_FD)){
int fd = systemd_logind_take_fd(pInfo->major, pInfo->minor,
- pInfo->attrs->device, &paused);
+ path, &paused);
if (fd != -1) {
if (paused) {
/* Put on new_input_devices list for delayed probe */
diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.c b/xorg-server/hw/xfree86/common/xf86platformBus.c
index 4447e19df..4e80f9ee3 100644
--- a/xorg-server/hw/xfree86/common/xf86platformBus.c
+++ b/xorg-server/hw/xfree86/common/xf86platformBus.c
@@ -38,6 +38,7 @@
#include <unistd.h>
#include "os.h"
#include "hotplug.h"
+#include "systemd-logind.h"
#include "xf86.h"
#include "xf86_OSproc.h"
@@ -310,15 +311,15 @@ static Bool doPlatformProbe(struct xf86_platform_device *dev, DriverPtr drvp,
GDevPtr gdev, int flags, intptr_t match_data)
{
Bool foundScreen = FALSE;
- int entity;
+ int entity, fd, major, minor;
- if (gdev->screen == 0 && !xf86_check_platform_slot(dev))
+ if (gdev && gdev->screen == 0 && !xf86_check_platform_slot(dev))
return FALSE;
entity = xf86ClaimPlatformSlot(dev, drvp, 0,
- gdev, gdev->active);
+ gdev, gdev ? gdev->active : 0);
- if ((entity == -1) && (gdev->screen > 0)) {
+ if ((entity == -1) && gdev && (gdev->screen > 0)) {
unsigned nent;
for (nent = 0; nent < xf86NumEntities; nent++) {
@@ -334,6 +335,17 @@ static Bool doPlatformProbe(struct xf86_platform_device *dev, DriverPtr drvp,
}
}
if (entity != -1) {
+ if ((dev->flags & XF86_PDEV_SERVER_FD) && (!drvp->driverFunc ||
+ !drvp->driverFunc(NULL, SUPPORTS_SERVER_FDS, NULL))) {
+ fd = xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_FD, -1);
+ major = xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_MAJOR, 0);
+ minor = xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_MINOR, 0);
+ systemd_logind_release_fd(major, minor);
+ close(fd);
+ config_odev_add_int_attribute(dev->attribs, ODEV_ATTRIB_FD, -1);
+ dev->flags &= ~XF86_PDEV_SERVER_FD;
+ }
+
if (drvp->platformProbe(drvp, entity, flags, dev, match_data))
foundScreen = TRUE;
else
@@ -420,7 +432,6 @@ xf86platformAddDevice(int index)
{
int i, old_screens, scr_index;
DriverPtr drvp = NULL;
- int entity;
screenLayoutPtr layout;
static const char *hotplug_driver_name = "modesetting";
@@ -440,11 +451,8 @@ xf86platformAddDevice(int index)
return -1;
old_screens = xf86NumGPUScreens;
- entity = xf86ClaimPlatformSlot(&xf86_platform_devices[index],
- drvp, 0, 0, 0);
- if (!drvp->platformProbe(drvp, entity, PLATFORM_PROBE_GPU_SCREEN, &xf86_platform_devices[index], 0)) {
- xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
- }
+ doPlatformProbe(&xf86_platform_devices[index], drvp, NULL,
+ PLATFORM_PROBE_GPU_SCREEN, 0);
if (old_screens == xf86NumGPUScreens)
return -1;
i = old_screens;
diff --git a/xorg-server/hw/xfree86/common/xf86str.h b/xorg-server/hw/xfree86/common/xf86str.h
index b164b7f21..a81e88614 100644
--- a/xorg-server/hw/xfree86/common/xf86str.h
+++ b/xorg-server/hw/xfree86/common/xf86str.h
@@ -256,7 +256,8 @@ typedef enum {
RR_GET_INFO,
RR_SET_CONFIG,
RR_GET_MODE_MM,
- GET_REQUIRED_HW_INTERFACES = 10
+ GET_REQUIRED_HW_INTERFACES = 10,
+ SUPPORTS_SERVER_FDS = 11,
} xorgDriverFuncOp;
typedef Bool xorgDriverFuncProc(ScrnInfoPtr, xorgDriverFuncOp, void *);
diff --git a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
index abb8e44d9..a8406d8be 100644
--- a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
@@ -347,7 +347,6 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
if (pdev) {
pdev->flags &= ~XF86_PDEV_PAUSED;
- systemd_logind_vtenter();
}
else {
pInfo->fd = fd;
@@ -355,6 +354,8 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
if (info->vt_active)
xf86EnableInputDeviceForVTSwitch(pInfo);
}
+ /* Always call vtenter(), in case there are only legacy video devs */
+ systemd_logind_vtenter();
}
return DBUS_HANDLER_RESULT_HANDLED;
}
diff --git a/xorg-server/include/systemd-logind.h b/xorg-server/include/systemd-logind.h
index 8b0908186..06dd03134 100644
--- a/xorg-server/include/systemd-logind.h
+++ b/xorg-server/include/systemd-logind.h
@@ -36,8 +36,8 @@ void systemd_logind_vtenter(void);
#else
#define systemd_logind_init()
#define systemd_logind_fini()
-#define systemd_logind_take_fd(major, minor, path) -1
-#define systemd_logind_release_fd(dev)
+#define systemd_logind_take_fd(major, minor, path, paus) -1
+#define systemd_logind_release_fd(major, minor)
#define systemd_logind_controls_session() 0
#define systemd_logind_vtenter()
#endif
diff --git a/xorg-server/include/xkbsrv.h b/xorg-server/include/xkbsrv.h
index e79979927..f857b2280 100644
--- a/xorg-server/include/xkbsrv.h
+++ b/xorg-server/include/xkbsrv.h
@@ -638,6 +638,10 @@ extern _X_EXPORT void XkbHandleActions(DeviceIntPtr /* dev */ ,
DeviceEvent * /* event */
);
+extern void XkbPushLockedStateToSlaves(DeviceIntPtr /* master */,
+ int /* evtype */,
+ int /* key */);
+
extern _X_EXPORT Bool XkbEnableDisableControls(XkbSrvInfoPtr /* xkbi */ ,
unsigned long /* change */ ,
unsigned long /* newValues */ ,
diff --git a/xorg-server/test/hashtabletest.c b/xorg-server/test/hashtabletest.c
index ceadfa7a3..86a0c58c6 100644
--- a/xorg-server/test/hashtabletest.c
+++ b/xorg-server/test/hashtabletest.c
@@ -12,7 +12,7 @@ static void
print_xid(void* ptr, void* v)
{
XID *x = v;
- printf("%ld", *x);
+ printf("%ld", (long)(*x));
}
static void
diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c
index 1443498f6..c44f44bc1 100644
--- a/xorg-server/xkb/xkbActions.c
+++ b/xorg-server/xkb/xkbActions.c
@@ -1127,13 +1127,78 @@ _XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction)
return send;
}
+static int
+_XkbEnsureStateChange(XkbSrvInfoPtr xkbi)
+{
+ Bool genStateNotify = FALSE;
+
+ /* The state may change, so if we're not in the middle of sending a state
+ * notify, prepare for it */
+ if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
+ xkbi->prev_state = xkbi->state;
+ xkbi->flags |= _XkbStateNotifyInProgress;
+ genStateNotify = TRUE;
+ }
+
+ return genStateNotify;
+}
+
+static void
+_XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key)
+{
+ XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+ int changed;
+
+ XkbComputeDerivedState(xkbi);
+
+ changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
+ if (genStateNotify) {
+ if (changed) {
+ xkbStateNotify sn;
+
+ sn.keycode = key;
+ sn.eventType = evtype;
+ sn.requestMajor = sn.requestMinor = 0;
+ sn.changed = changed;
+ XkbSendStateNotify(dev, &sn);
+ }
+ xkbi->flags &= ~_XkbStateNotifyInProgress;
+ }
+
+ changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
+ if (changed) {
+ XkbEventCauseRec cause;
+ XkbSetCauseKey(&cause, key, evtype);
+ XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
+ }
+}
+
+void
+XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
+{
+ DeviceIntPtr dev;
+ Bool genStateNotify;
+
+ nt_list_for_each_entry(dev, inputInfo.devices, next) {
+ if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master)
+ continue;
+
+ genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo);
+
+ dev->key->xkbInfo->state.locked_mods =
+ master->key->xkbInfo->state.locked_mods;
+
+ _XkbApplyState(dev, genStateNotify, evtype, key);
+ }
+}
+
void
XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
{
int key, bit, i;
XkbSrvInfoPtr xkbi;
KeyClassPtr keyc;
- int changed, sendEvent;
+ int sendEvent;
Bool genStateNotify;
XkbAction act;
XkbFilterPtr filter;
@@ -1146,15 +1211,8 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
keyc = kbd->key;
xkbi = keyc->xkbInfo;
key = event->detail.key;
- /* The state may change, so if we're not in the middle of sending a state
- * notify, prepare for it */
- if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
- xkbi->prev_state = xkbi->state;
- xkbi->flags |= _XkbStateNotifyInProgress;
- genStateNotify = TRUE;
- }
- else
- genStateNotify = FALSE;
+
+ genStateNotify = _XkbEnsureStateChange(xkbi);
xkbi->clearMods = xkbi->setMods = 0;
xkbi->groupChange = 0;
@@ -1287,28 +1345,8 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
FixKeyState(event, dev);
}
- XkbComputeDerivedState(xkbi);
- changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
- if (genStateNotify) {
- if (changed) {
- xkbStateNotify sn;
-
- sn.keycode = key;
- sn.eventType = event->type;
- sn.requestMajor = sn.requestMinor = 0;
- sn.changed = changed;
- XkbSendStateNotify(dev, &sn);
- }
- xkbi->flags &= ~_XkbStateNotifyInProgress;
- }
- changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
- if (changed) {
- XkbEventCauseRec cause;
-
- XkbSetCauseKey(&cause, key, event->type);
- XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
- }
- return;
+ _XkbApplyState(dev, genStateNotify, event->type, key);
+ XkbPushLockedStateToSlaves(dev, event->type, key);
}
int