diff options
author | marha <marha@users.sourceforge.net> | 2014-03-12 16:45:42 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-03-12 16:45:42 +0100 |
commit | cc6db22a772cc52ead6a5c11d7d02e7364f6326c (patch) | |
tree | d80b42172d703ec20ccd99c68a067505e2706899 /xorg-server | |
parent | 2112b7dec49833ba872bd3ebcd7288930fec0796 (diff) | |
parent | cd8b0d0de3fcb53f6d3ece8ce26d97aaab2c0914 (diff) | |
download | vcxsrv-cc6db22a772cc52ead6a5c11d7d02e7364f6326c.tar.gz vcxsrv-cc6db22a772cc52ead6a5c11d7d02e7364f6326c.tar.bz2 vcxsrv-cc6db22a772cc52ead6a5c11d7d02e7364f6326c.zip |
Merge remote-tracking branch 'origin/released'
* origin/released:
mesa xserver xkbcomp git update 12 Mar 2014
Diffstat (limited to 'xorg-server')
23 files changed, 479 insertions, 235 deletions
diff --git a/xorg-server/config/config.c b/xorg-server/config/config.c index 732670038..883402bb5 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 4e20b50d4..903417f77 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -417,6 +417,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*/ @@ -2650,6 +2652,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 087169596..777c2d721 100644 --- a/xorg-server/glx/glxdricommon.c +++ b/xorg-server/glx/glxdricommon.c @@ -145,7 +145,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 7b3db0f86..20d3a9a17 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 3fbf05183..9df42bd6b 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 |