diff options
Diffstat (limited to 'xorg-server')
46 files changed, 1205 insertions, 421 deletions
diff --git a/xorg-server/dix/gc.c b/xorg-server/dix/gc.c index 1fb577e53..d7657c210 100644 --- a/xorg-server/dix/gc.c +++ b/xorg-server/dix/gc.c @@ -261,12 +261,14 @@ ChangeGC(ClientPtr client, GC * pGC, BITS32 mask, ChangeGCValPtr pUnion) case GCStipple: NEXT_PTR(PixmapPtr, pPixmap); - if ((pPixmap->drawable.depth != 1) || - (pPixmap->drawable.pScreen != pGC->pScreen)) { + if (pPixmap && ((pPixmap->drawable.depth != 1) || + (pPixmap->drawable.pScreen != pGC->pScreen))) + { error = BadMatch; } else { - pPixmap->refcnt++; + if (pPixmap) + pPixmap->refcnt++; if (pGC->stipple) (*pGC->pScreen->DestroyPixmap) (pGC->stipple); pGC->stipple = pPixmap; diff --git a/xorg-server/fb/fbblt.c b/xorg-server/fb/fbblt.c index 72a05f61a..c615106d1 100644 --- a/xorg-server/fb/fbblt.c +++ b/xorg-server/fb/fbblt.c @@ -56,42 +56,48 @@ fbBlt(FbBits * srcLine, int n, nmiddle; Bool destInvarient; int startbyte, endbyte; - int careful; FbDeclareMergeRop(); + if (alu == GXcopy && pm == FB_ALLONES && + !(srcX & 7) && !(dstX & 7) && !(width & 7)) + { + CARD8 *src_byte = (CARD8 *) srcLine + (srcX >> 3); + CARD8 *dst_byte = (CARD8 *) dstLine + (dstX >> 3); + FbStride src_byte_stride = srcStride << (FB_SHIFT - 3); + FbStride dst_byte_stride = dstStride << (FB_SHIFT - 3); + int width_byte = (width >> 3); + + /* Make sure there's no overlap; we can't use memcpy in that + * case as it's not well defined, so fall through to the + * general code + */ + if (src_byte + width_byte <= dst_byte || + dst_byte + width_byte <= src_byte) + { + int i; + + if (!upsidedown) + for (i = 0; i < height; i++) + MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride, + src_byte + i * src_byte_stride, + width_byte); + else + for (i = height - 1; i >= 0; i--) + MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride, + src_byte + i * src_byte_stride, + width_byte); + + return; + } + } + if (bpp == 24 && !FbCheck24Pix(pm)) { fbBlt24(srcLine, srcStride, srcX, dstLine, dstStride, dstX, width, height, alu, pm, reverse, upsidedown); return; } - careful = !((srcLine < dstLine && srcLine + width * (bpp >> 3) > dstLine) || - (dstLine < srcLine && dstLine + width * (bpp >> 3) > srcLine)) - || (bpp & 7); - - if (alu == GXcopy && pm == FB_ALLONES && !careful && - !(srcX & 7) && !(dstX & 7) && !(width & 7)) { - int i; - CARD8 *tmpsrc = (CARD8 *) srcLine; - CARD8 *tmpdst = (CARD8 *) dstLine; - - srcStride *= sizeof(FbBits); - dstStride *= sizeof(FbBits); - width >>= 3; - tmpsrc += (srcX >> 3); - tmpdst += (dstX >> 3); - - if (!upsidedown) - for (i = 0; i < height; i++) - MEMCPY_WRAPPED(tmpdst + i * dstStride, tmpsrc + i * srcStride, width); - else - for (i = height - 1; i >= 0; i--) - MEMCPY_WRAPPED(tmpdst + i * dstStride, tmpsrc + i * srcStride, width); - - return; - } - FbInitializeMergeRop(alu, pm); destInvarient = FbDestInvarientMergeRop(); if (upsidedown) { diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am index ffc8c23d8..8555e4087 100644 --- a/xorg-server/glamor/Makefile.am +++ b/xorg-server/glamor/Makefile.am @@ -20,8 +20,11 @@ libglamor_la_SOURCES = \ glamor_polylines.c \ glamor_putimage.c \ glamor_setspans.c \ + glamor_segment.c \ glamor_render.c \ glamor_gradient.c \ + glamor_program.c \ + glamor_transform.c \ glamor_trapezoid.c \ glamor_tile.c \ glamor_triangles.c\ @@ -29,7 +32,7 @@ libglamor_la_SOURCES = \ glamor_getimage.c\ glamor_copyplane.c\ glamor_glyphblt.c\ - glamor_polyops.c\ + glamor_points.c\ glamor_priv.h\ glamor_pixmap.c\ glamor_largepixmap.c\ diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c index 0f7d68b70..30944326b 100644 --- a/xorg-server/glamor/glamor.c +++ b/xorg-server/glamor/glamor.c @@ -76,6 +76,10 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type) pixmap_priv->base.glamor_priv = glamor_priv; } pixmap_priv->type = type; + pixmap_priv->base.box.x1 = 0; + pixmap_priv->base.box.x2 = pixmap->drawable.width; + pixmap_priv->base.box.y1 = 0; + pixmap_priv->base.box.y2 = pixmap->drawable.height; } _X_EXPORT void @@ -178,8 +182,14 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3; screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL); - if (type == GLAMOR_MEMORY_MAP || glamor_check_fbo_size(glamor_priv, w, h)) { + if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE || + glamor_check_fbo_size(glamor_priv, w, h)) + { pixmap_priv->type = type; + pixmap_priv->base.box.x1 = 0; + pixmap_priv->base.box.y1 = 0; + pixmap_priv->base.box.x2 = w; + pixmap_priv->base.box.y2 = h; fbo = glamor_create_fbo(glamor_priv, w, h, format, usage); } else { @@ -341,7 +351,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) else glamor_priv->gl_flavor = GLAMOR_GL_ES2; - gl_version = glamor_gl_get_version(); + gl_version = epoxy_gl_version(); /* We'd like to require GL_ARB_map_buffer_range or * GL_OES_map_buffer_range, since it offers more information to @@ -357,29 +367,31 @@ glamor_init(ScreenPtr screen, unsigned int flags) * 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"); + if (gl_version < 21) { + ErrorF("Require OpenGL version 2.1 or later.\n"); goto fail; } } else { - if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) { + if (gl_version < 20) { ErrorF("Require Open GLES2.0 or later.\n"); goto fail; } - if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) { + if (!epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888")) { ErrorF("GL_EXT_texture_format_BGRA8888 required\n"); goto fail; } } - glamor_priv->has_khr_debug = glamor_gl_has_extension("GL_KHR_debug"); + glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug"); glamor_priv->has_pack_invert = - glamor_gl_has_extension("GL_MESA_pack_invert"); + epoxy_has_gl_extension("GL_MESA_pack_invert"); glamor_priv->has_fbo_blit = - glamor_gl_has_extension("GL_EXT_framebuffer_blit"); + epoxy_has_gl_extension("GL_EXT_framebuffer_blit"); + glamor_priv->has_map_buffer_range = + epoxy_has_gl_extension("GL_ARB_map_buffer_range"); glamor_priv->has_buffer_storage = - glamor_gl_has_extension("GL_ARB_buffer_storage"); + epoxy_has_gl_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; diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h index d05d2f4ea..11ec49361 100644 --- a/xorg-server/glamor/glamor.h +++ b/xorg-server/glamor/glamor.h @@ -140,9 +140,16 @@ extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type); extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap); extern _X_EXPORT void glamor_block_handler(ScreenPtr screen); + extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage); +#define GLAMOR_CREATE_PIXMAP_CPU 0x100 +#define GLAMOR_CREATE_PIXMAP_FIXUP 0x101 +#define GLAMOR_CREATE_FBO_NO_FBO 0x103 +#define GLAMOR_CREATE_PIXMAP_MAP 0x104 +#define GLAMOR_CREATE_NO_LARGE 0x105 + /* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo). * * @front: front pixmap. diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c index 6c0b3c834..5711be72f 100644 --- a/xorg-server/glamor/glamor_core.c +++ b/xorg-server/glamor/glamor_core.c @@ -559,48 +559,3 @@ glamor_bitmap_to_region(PixmapPtr pixmap) return ret; } -/* Borrow from cairo. */ -Bool -glamor_gl_has_extension(const char *extension) -{ - const char *pext; - int ext_len; - - ext_len = strlen(extension); - - pext = (const char *) glGetString(GL_EXTENSIONS); - - if (pext == NULL || extension == NULL) - return FALSE; - - while ((pext = strstr(pext, extension)) != NULL) { - if (pext[ext_len] == ' ' || pext[ext_len] == '\0') - return TRUE; - pext += ext_len; - } - return FALSE; -} - -int -glamor_gl_get_version(void) -{ - int major, minor; - const char *version = (const char *) glGetString(GL_VERSION); - const char *dot = version == NULL ? NULL : strchr(version, '.'); - const char *major_start = dot; - - /* Sanity check */ - if (dot == NULL || dot == version || *(dot + 1) == '\0') { - major = 0; - minor = 0; - } - else { - /* Find the start of the major version in the string */ - while (major_start > version && *major_start != ' ') - --major_start; - major = strtol(major_start, NULL, 10); - minor = strtol(dot + 1, NULL, 10); - } - - return GLAMOR_GL_VERSION_ENCODE(major, minor); -} diff --git a/xorg-server/glamor/glamor_fbo.c b/xorg-server/glamor/glamor_fbo.c index 640b6fd81..4f6da67fb 100644 --- a/xorg-server/glamor/glamor_fbo.c +++ b/xorg-server/glamor/glamor_fbo.c @@ -361,9 +361,6 @@ glamor_create_fbo(glamor_screen_private *glamor_priv, GLint tex = 0; int cache_flag; - if (!glamor_check_fbo_size(glamor_priv, w, h)) - return NULL; - if (flag == GLAMOR_CREATE_FBO_NO_FBO) goto new_fbo; diff --git a/xorg-server/glamor/glamor_fill.c b/xorg-server/glamor/glamor_fill.c index 7461b62fa..2fa726e72 100644 --- a/xorg-server/glamor/glamor_fill.c +++ b/xorg-server/glamor/glamor_fill.c @@ -218,9 +218,6 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) } } - if (_X_UNLIKELY(nbox > 1)) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); diff --git a/xorg-server/glamor/glamor_glyphs.c b/xorg-server/glamor/glamor_glyphs.c index 2b2c735d4..a04ae8261 100644 --- a/xorg-server/glamor/glamor_glyphs.c +++ b/xorg-server/glamor/glamor_glyphs.c @@ -332,7 +332,7 @@ glamor_realize_glyph_caches(ScreenPtr pScreen) pixmap = pScreen->CreatePixmap(pScreen, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE, - depth, 0); + depth, GLAMOR_CREATE_NO_LARGE); if (!pixmap) goto bail; diff --git a/xorg-server/glamor/glamor_gradient.c b/xorg-server/glamor/glamor_gradient.c index f77d6a8e3..c24f3427f 100644 --- a/xorg-server/glamor/glamor_gradient.c +++ b/xorg-server/glamor/glamor_gradient.c @@ -247,7 +247,6 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, "{\n"\ " float t = 0.0;\n"\ " float sqrt_value;\n"\ - " int revserse = 0;\n"\ " t_invalid = 0;\n"\ " \n"\ " vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"\ @@ -295,30 +294,11 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, " }\n"\ " \n"\ " if(repeat_type == %d){\n" /* repeat normal*/\ - " while(t > 1.0) \n"\ - " t = t - 1.0; \n"\ - " while(t < 0.0) \n"\ - " t = t + 1.0; \n"\ + " t = fract(t);\n"\ " }\n"\ " \n"\ " if(repeat_type == %d) {\n" /* repeat reflect*/\ - " while(t > 1.0) {\n"\ - " t = t - 1.0; \n"\ - " if(revserse == 0)\n"\ - " revserse = 1;\n"\ - " else\n"\ - " revserse = 0;\n"\ - " }\n"\ - " while(t < 0.0) {\n"\ - " t = t + 1.0; \n"\ - " if(revserse == 0)\n"\ - " revserse = 1;\n"\ - " else\n"\ - " revserse = 0;\n"\ - " }\n"\ - " if(revserse == 1) {\n"\ - " t = 1.0 - t; \n"\ - " }\n"\ + " t = abs(fract(t * 0.5 + 0.5) * 2.0 - 1.0);\n"\ " }\n"\ " \n"\ " return t;\n"\ @@ -492,7 +472,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, " vec4 stop_color_before;\n"\ " vec4 stop_color_after;\n"\ " float new_alpha; \n"\ - " int revserse = 0;\n"\ " vec4 gradient_color;\n"\ " float percentage; \n"\ " vec3 source_texture_trans = transform_mat * tmp;\n"\ @@ -512,30 +491,11 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, " distance = distance - _p1_distance; \n"\ " \n"\ " if(repeat_type == %d){\n" /* repeat normal*/\ - " while(distance > _pt_distance) \n"\ - " distance = distance - (_pt_distance); \n"\ - " while(distance < 0.0) \n"\ - " distance = distance + (_pt_distance); \n"\ + " distance = mod(distance, _pt_distance);\n"\ " }\n"\ " \n"\ " if(repeat_type == %d) {\n" /* repeat reflect*/\ - " while(distance > _pt_distance) {\n"\ - " distance = distance - (_pt_distance); \n"\ - " if(revserse == 0)\n"\ - " revserse = 1;\n"\ - " else\n"\ - " revserse = 0;\n"\ - " }\n"\ - " while(distance < 0.0) {\n"\ - " distance = distance + (_pt_distance); \n"\ - " if(revserse == 0)\n"\ - " revserse = 1;\n"\ - " else\n"\ - " revserse = 0;\n"\ - " }\n"\ - " if(revserse == 1) {\n"\ - " distance = (_pt_distance) - distance; \n"\ - " }\n"\ + " distance = abs(mod(distance + _pt_distance, 2.0 * _pt_distance) - _pt_distance);\n"\ " }\n"\ " \n"\ " len_percentage = distance/(_pt_distance);\n"\ @@ -1160,9 +1120,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, free(stop_colors); } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); @@ -1181,9 +1138,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, free(stop_colors); } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glamor_put_context(glamor_priv); @@ -1511,9 +1465,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, free(stop_colors); } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); @@ -1532,9 +1483,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, free(stop_colors); } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glamor_put_context(glamor_priv); diff --git a/xorg-server/glamor/glamor_largepixmap.c b/xorg-server/glamor/glamor_largepixmap.c index b8c064038..b3a8d5d20 100644 --- a/xorg-server/glamor/glamor_largepixmap.c +++ b/xorg-server/glamor/glamor_largepixmap.c @@ -1015,7 +1015,6 @@ glamor_composite_largepixmap_region(CARD8 op, INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height) { - glamor_screen_private *glamor_priv; glamor_pixmap_clipped_regions *clipped_dest_regions; glamor_pixmap_clipped_regions *clipped_source_regions; glamor_pixmap_clipped_regions *clipped_mask_regions; @@ -1044,9 +1043,8 @@ glamor_composite_largepixmap_region(CARD8 op, else mask_repeat_type = RepeatNone; - glamor_priv = dest_pixmap_priv->base.glamor_priv; - fixed_block_width = glamor_priv->max_fbo_size; - fixed_block_height = glamor_priv->max_fbo_size; + fixed_block_width = dest_pixmap_priv->large.block_w; + fixed_block_height = dest_pixmap_priv->large.block_h; /* If we got an totally out-of-box region for a source or mask * region without repeat, we need to set it as null_source and * give it a solid color (0,0,0,0). */ @@ -1112,8 +1110,8 @@ glamor_composite_largepixmap_region(CARD8 op, /*compute the correct block width and height whose transformed source/mask *region can fit into one texture.*/ - if (force_clip || fixed_block_width < glamor_priv->max_fbo_size - || fixed_block_height < glamor_priv->max_fbo_size) + if (force_clip || fixed_block_width < dest_pixmap_priv->large.block_w + || fixed_block_height < dest_pixmap_priv->large.block_h) clipped_dest_regions = glamor_compute_clipped_regions_ext(dest_pixmap_priv, region, &n_dest_regions, diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c index 615faad33..891ecdd37 100644 --- a/xorg-server/glamor/glamor_pixmap.c +++ b/xorg-server/glamor/glamor_pixmap.c @@ -1013,10 +1013,9 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, clipped_regions = glamor_compute_clipped_regions_ext(pixmap_priv, ®ion, &n_region, - pixmap_priv->base. - glamor_priv->max_fbo_size, - pixmap_priv->base. - glamor_priv->max_fbo_size, 0, + pixmap_priv->large.block_w, + pixmap_priv->large.block_h, + 0, 0); DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap); for (i = 0; i < n_region; i++) { @@ -1374,10 +1373,9 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h, clipped_regions = glamor_compute_clipped_regions_ext(pixmap_priv, ®ion, &n_region, - pixmap_priv->base. - glamor_priv->max_fbo_size, - pixmap_priv->base. - glamor_priv->max_fbo_size, 0, + pixmap_priv->large.block_w, + pixmap_priv->large.block_h, + 0, 0); DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h); diff --git a/xorg-server/glamor/glamor_points.c b/xorg-server/glamor/glamor_points.c new file mode 100644 index 000000000..5399f96e8 --- /dev/null +++ b/xorg-server/glamor/glamor_points.c @@ -0,0 +1,129 @@ +/* + * Copyright © 2009 Intel Corporation + * Copyright © 1998 Keith Packard + * + * 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. + * + * Authors: + * Zhigang Gong <zhigang.gong@linux.intel.com> + * + */ + +#include "glamor_priv.h" +#include "glamor_transform.h" + +static const glamor_facet glamor_facet_point = { + .name = "poly_point", + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = GLAMOR_POS(gl_Position, primitive), +}; + +Bool +glamor_poly_point_nf(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPointPtr ppt) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_program *prog = &glamor_priv->point_prog; + glamor_pixmap_private *pixmap_priv; + int off_x, off_y; + GLshort *vbo_ppt; + char *vbo_offset; + int box_x, box_y; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + glamor_get_context(glamor_priv); + + if (prog->failed) + goto bail_ctx; + + if (!prog->prog) { + if (!glamor_build_program(screen, prog, + &glamor_facet_point, + &glamor_fill_solid)) + goto bail_ctx; + } + + if (!glamor_use_program(pixmap, gc, prog, NULL)) + goto bail_ctx; + + vbo_ppt = glamor_get_vbo_space(screen, npt * (2 * sizeof (INT16)), &vbo_offset); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 0, vbo_offset); + if (mode == CoordModePrevious) { + int n = npt; + INT16 x = 0, y = 0; + while (n--) { + vbo_ppt[0] = (x += ppt->x); + vbo_ppt[1] = (y += ppt->y); + vbo_ppt += 2; + ppt++; + } + } else + memcpy(vbo_ppt, ppt, npt * (2 * sizeof (INT16))); + glamor_put_vbo_space(screen); + + glEnable(GL_SCISSOR_TEST); + + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + int nbox = RegionNumRects(gc->pCompositeClip); + BoxPtr box = RegionRects(gc->pCompositeClip); + + glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y); + + while (nbox--) { + glScissor(box->x1 + off_x, + box->y1 + off_y, + box->x2 - box->x1, + box->y2 - box->y1); + box++; + glDrawArrays(GL_POINTS, 0, npt); + } + } + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + glamor_put_context(glamor_priv); + + glamor_priv->state = RENDER_STATE; + glamor_priv->render_idle_cnt = 0; + + return TRUE; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); + glamor_put_context(glamor_priv); +bail: + return FALSE; +} + +void +glamor_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int npt, + DDXPointPtr ppt) +{ + if (glamor_poly_point_nf(drawable, gc, mode, npt, ppt)) + return; + miPolyPoint(drawable, gc, mode, npt, ppt); +} diff --git a/xorg-server/glamor/glamor_polyops.c b/xorg-server/glamor/glamor_polyops.c deleted file mode 100644 index 1484d80f1..000000000 --- a/xorg-server/glamor/glamor_polyops.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * Copyright © 1998 Keith Packard - * - * 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. - * - * Authors: - * Zhigang Gong <zhigang.gong@linux.intel.com> - * - */ - -#include "glamor_priv.h" - -static Bool -_glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt, Bool fallback) -{ - if (!fallback && glamor_ddx_fallback_check_gc(pGC) - && glamor_ddx_fallback_check_pixmap(pDrawable)) - return FALSE; - - miPolyPoint(pDrawable, pGC, mode, npt, ppt); - - return TRUE; -} - -void -glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt) -{ - _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, TRUE); -} - -Bool -glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt) -{ - return _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, FALSE); -} - -static Bool -_glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg, Bool fallback) -{ - if (!fallback && glamor_ddx_fallback_check_gc(pGC) - && glamor_ddx_fallback_check_pixmap(pDrawable)) - return FALSE; - - miPolySegment(pDrawable, pGC, nseg, pSeg); - - return TRUE; -} - -void -glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg) -{ - _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, TRUE); -} - -Bool -glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg) -{ - return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE); -} diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h index bc7d3f827..4c305abfc 100644 --- a/xorg-server/glamor/glamor_priv.h +++ b/xorg-server/glamor/glamor_priv.h @@ -52,6 +52,7 @@ #include "glamor_debug.h" #include "glamor_context.h" +#include "glamor_program.h" #include <list.h> @@ -153,13 +154,6 @@ enum glamor_gl_flavor { GLAMOR_GL_ES2 // OPENGL ES2.0 API }; -#define GLAMOR_CREATE_PIXMAP_CPU 0x100 -#define GLAMOR_CREATE_PIXMAP_FIXUP 0x101 -#define GLAMOR_CREATE_FBO_NO_FBO 0x103 -#define GLAMOR_CREATE_PIXMAP_MAP 0x104 - -#define GLAMOR_CREATE_TEXTURE_EXACT_SIZE 0x104 - #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2 #define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024) @@ -213,6 +207,7 @@ typedef struct glamor_screen_private { enum glamor_gl_flavor gl_flavor; int has_pack_invert; int has_fbo_blit; + int has_map_buffer_range; int has_buffer_storage; int has_khr_debug; int max_fbo_size; @@ -225,6 +220,9 @@ typedef struct glamor_screen_private { GLint solid_prog; GLint solid_color_uniform_location; + /* glamor point shader */ + glamor_program point_prog; + /* vertext/elment_index buffer object for render */ GLuint vbo, ebo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ @@ -421,6 +419,7 @@ typedef struct glamor_pixmap_private_base { unsigned char gl_tex:1; glamor_pixmap_fbo *fbo; PixmapPtr pixmap; + BoxRec box; int drm_stride; glamor_screen_private *glamor_priv; PicturePtr picture; @@ -476,6 +475,52 @@ typedef struct glamor_pixmap_private { }; } glamor_pixmap_private; +static inline glamor_pixmap_fbo * +glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y) +{ + if (priv->type == GLAMOR_TEXTURE_LARGE) { + assert(x < priv->large.block_wcnt); + assert(y < priv->large.block_hcnt); + return priv->large.fbo_array[y * priv->large.block_wcnt + x]; + } + assert (x == 0); + assert (y == 0); + return priv->base.fbo; +} + +static inline BoxPtr +glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y) +{ + if (priv->type == GLAMOR_TEXTURE_LARGE) { + assert(x < priv->large.block_wcnt); + assert(y < priv->large.block_hcnt); + return &priv->large.box_array[y * priv->large.block_wcnt + x]; + } + assert (x == 0); + assert (y == 0); + return &priv->base.box; +} + +static inline int +glamor_pixmap_wcnt(glamor_pixmap_private *priv) +{ + if (priv->type == GLAMOR_TEXTURE_LARGE) + return priv->large.block_wcnt; + return 1; +} + +static inline int +glamor_pixmap_hcnt(glamor_pixmap_private *priv) +{ + if (priv->type == GLAMOR_TEXTURE_LARGE) + return priv->large.block_hcnt; + return 1; +} + +#define glamor_pixmap_loop(priv, x, y) \ + for (y = 0; y < glamor_pixmap_hcnt(priv); y++) \ + for (x = 0; x < glamor_pixmap_wcnt(priv); x++) + /* * Pixmap dynamic status, used by dynamic upload feature. * @@ -619,12 +664,6 @@ Bool glamor_set_alu(ScreenPtr screen, unsigned char alu); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); -Bool glamor_gl_has_extension(const char *extension); -int glamor_gl_get_version(void); - -#define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \ - ((major) * 256) \ - + ((minor) * 1)) /* glamor_fill.c */ Bool glamor_fill(DrawablePtr drawable, diff --git a/xorg-server/glamor/glamor_program.c b/xorg-server/glamor/glamor_program.c new file mode 100644 index 000000000..e2e1434ee --- /dev/null +++ b/xorg-server/glamor/glamor_program.c @@ -0,0 +1,394 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "glamor_priv.h" +#include "glamor_transform.h" +#include "glamor_program.h" + +static Bool +use_solid(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) +{ + return glamor_set_solid(pixmap, gc, TRUE, prog->fg_uniform); +} + +const glamor_facet glamor_fill_solid = { + .name = "solid", + .fs_exec = " gl_FragColor = fg;\n", + .locations = glamor_program_location_fg, + .use = use_solid, +}; + +static Bool +use_tile(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) +{ + return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform, prog->fill_size_uniform); +} + +static const glamor_facet glamor_fill_tile = { + .name = "tile", + .version = 130, + .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n", + .fs_exec = " gl_FragColor = texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0);\n", + .locations = glamor_program_location_fill, + .use = use_tile, +}; + +#if 0 +static Bool +use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog) +{ + return glamor_set_stippled(pixmap, gc, prog->fg_uniform, prog->fill_offset_uniform, prog->fill_size_uniform); +} + +static const glamor_facet glamor_fill_stipple = { + .name = "stipple", + .version = 130, + .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n"; + .fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n" + " discard;\n" + " gl_FragColor = fg;\n") + .locations = glamor_program_location_fg | glamor_program_location_fill + .use = use_stipple, +}; + +static const glamor_facet glamor_fill_opaque_stipple = { + .name = "opaque_stipple", + .version = 130, + .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n"; + .fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n" + " gl_FragColor = bg;\n" + " else\n" + " gl_FragColor = fg;\n"), + .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill + .use = use_opaque_stipple +}; +#endif + +static const glamor_facet *glamor_facet_fill[4] = { + &glamor_fill_solid, + &glamor_fill_tile, + NULL, + NULL, +}; + +typedef struct { + glamor_program_location location; + const char *vs_vars; + const char *fs_vars; +} glamor_location_var; + +static glamor_location_var location_vars[] = { + { + .location = glamor_program_location_fg, + .fs_vars = "uniform vec4 fg;\n" + }, + { + .location = glamor_program_location_bg, + .fs_vars = "uniform vec4 bg;\n" + }, + { + .location = glamor_program_location_fill, + .vs_vars = ("uniform vec2 fill_offset;\n" + "varying vec2 fill_pos;\n"), + .fs_vars = ("uniform sampler2D sampler;\n" + "uniform vec2 fill_size;\n" + "varying vec2 fill_pos;\n") + }, + { + .location = glamor_program_location_font, + .fs_vars = "uniform usampler2D font;\n", + }, +}; + +#define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0]) + +static char * +add_var(char *cur, const char *add) +{ + char *new; + + if (!add) + return cur; + + new = realloc(cur, strlen(cur) + strlen(add) + 1); + if (!new) { + free(cur); + return NULL; + } + strcat(new, add); + return new; +} + +static char * +vs_location_vars(glamor_program_location locations) +{ + int l; + char *vars = strdup(""); + + for (l = 0; vars && l < NUM_LOCATION_VARS; l++) + if (locations & location_vars[l].location) + vars = add_var(vars, location_vars[l].vs_vars); + return vars; +} + +static char * +fs_location_vars(glamor_program_location locations) +{ + int l; + char *vars = strdup(""); + + for (l = 0; vars && l < NUM_LOCATION_VARS; l++) + if (locations & location_vars[l].location) + vars = add_var(vars, location_vars[l].fs_vars); + return vars; +} + +static const char vs_template[] = + "%s" /* version */ + "%s" /* prim vs_vars */ + "%s" /* fill vs_vars */ + "%s" /* location vs_vars */ + GLAMOR_DECLARE_MATRIX + "void main() {\n" + "%s" /* prim vs_exec, outputs 'pos' and gl_Position */ + "%s" /* fill vs_exec */ + "}\n"; + +static const char fs_template[] = + "%s" /* version */ + GLAMOR_DEFAULT_PRECISION + "%s" /* prim fs_vars */ + "%s" /* fill fs_vars */ + "%s" /* location fs_vars */ + "void main() {\n" + "%s" /* prim fs_exec */ + "%s" /* fill fs_exec */ + "}\n"; + +static const char * +str(const char *s) +{ + if (!s) + return ""; + return s; +} + +static const glamor_facet facet_null_fill = { + .name = "" +}; + +static GLint +glamor_get_uniform(glamor_program *prog, + glamor_program_location location, + const char *name) +{ + GLint uniform; + if (location && (prog->locations & location) == 0) + return -2; + uniform = glGetUniformLocation(prog->prog, name); +#if DBG + ErrorF("%s uniform %d\n", name, uniform); +#endif + return uniform; +} + +Bool +glamor_build_program(ScreenPtr screen, + glamor_program *prog, + const glamor_facet *prim, + const glamor_facet *fill) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + glamor_program_location locations = prim->locations; + glamor_program_flag flags = prim->flags; + + int version = prim->version; + char *version_string = NULL; + + char *fs_vars = NULL; + char *vs_vars = NULL; + + char *vs_prog_string; + char *fs_prog_string; + + GLint fs_prog, vs_prog; + + if (!fill) + fill = &facet_null_fill; + + locations |= fill->locations; + flags |= fill->flags; + version = MAX(version, fill->version); + + if (version >= 130) { + + /* Would be nice to have a cleaner test for GLSL 1.30 support, + * but for now this should suffice + */ + if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP || + epoxy_gl_version() < 30) { + goto fail; + } + } + + vs_vars = vs_location_vars(locations); + fs_vars = fs_location_vars(locations); + + if (!vs_vars) + goto fail; + if (!fs_vars) + goto fail; + + if (version) { + if (asprintf(&version_string, "#version %d\n", version) < 0) + version_string = NULL; + if (!version_string) + goto fail; + } + + if (asprintf(&vs_prog_string, + vs_template, + str(version_string), + str(prim->vs_vars), + str(fill->vs_vars), + vs_vars, + str(prim->vs_exec), + str(fill->vs_exec)) < 0) + vs_prog_string = NULL; + + if (asprintf(&fs_prog_string, + fs_template, + str(version_string), + str(prim->fs_vars), + str(fill->fs_vars), + fs_vars, + str(prim->fs_exec), + str(fill->fs_exec)) < 0) + fs_prog_string = NULL; + + if (!vs_prog_string || !fs_prog_string) + goto fail; + +#define DBG 0 +#if DBG + ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s", + prim->name, fill->name, vs_prog_string, fs_prog_string); +#endif + + prog->prog = glCreateProgram(); + prog->flags = flags; + prog->locations = locations; + prog->prim_use = prim->use; + prog->fill_use = fill->use; + + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_prog_string); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_prog_string); + free(vs_prog_string); + free(fs_prog_string); + glAttachShader(prog->prog, vs_prog); + glDeleteShader(vs_prog); + glAttachShader(prog->prog, fs_prog); + glDeleteShader(fs_prog); + glBindAttribLocation(prog->prog, GLAMOR_VERTEX_POS, "primitive"); + + if (prim->source_name) { +#if DBG + ErrorF("Bind GLAMOR_VERTEX_SOURCE to %s\n", prim->source_name); +#endif + glBindAttribLocation(prog->prog, GLAMOR_VERTEX_SOURCE, prim->source_name); + } + + glamor_link_glsl_prog(screen, prog->prog, "%s_%s", prim->name, fill->name); + + prog->matrix_uniform = glamor_get_uniform(prog, glamor_program_location_none, "v_matrix"); + prog->fg_uniform = glamor_get_uniform(prog, glamor_program_location_fg, "fg"); + prog->bg_uniform = glamor_get_uniform(prog, glamor_program_location_bg, "bg"); + prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset"); + prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size"); + prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font"); + + if (glGetError() != GL_NO_ERROR) + goto fail; + + free(version_string); + free(fs_vars); + free(vs_vars); + return TRUE; +fail: + prog->failed = 1; + if (prog->prog) { + glDeleteProgram(prog->prog); + prog->prog = 0; + } + free(version_string); + free(fs_vars); + free(vs_vars); + return FALSE; +} + +Bool +glamor_use_program(PixmapPtr pixmap, + GCPtr gc, + glamor_program *prog, + void *arg) +{ + glUseProgram(prog->prog); + + if (prog->prim_use && !prog->prim_use(pixmap, gc, prog, arg)) + return FALSE; + + if (prog->fill_use && !prog->fill_use(pixmap, gc, prog, arg)) + return FALSE; + + return TRUE; +} + +glamor_program * +glamor_use_program_fill(PixmapPtr pixmap, + GCPtr gc, + glamor_program_fill *program_fill, + const glamor_facet *prim) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_program *prog = &program_fill->progs[gc->fillStyle]; + + int fill_style = gc->fillStyle; + const glamor_facet *fill; + + if (prog->failed) + return FALSE; + + if (!prog->prog) { + fill = glamor_facet_fill[fill_style]; + if (!fill) + return NULL; + + if (!glamor_build_program(screen, prog, prim, fill)) + return NULL; + } + + if (!glamor_use_program(pixmap, gc, prog, NULL)) + return NULL; + + return prog; +} diff --git a/xorg-server/glamor/glamor_program.h b/xorg-server/glamor/glamor_program.h new file mode 100644 index 000000000..88efc3593 --- /dev/null +++ b/xorg-server/glamor/glamor_program.h @@ -0,0 +1,94 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _GLAMOR_PROGRAM_H_ +#define _GLAMOR_PROGRAM_H_ + +typedef enum { + glamor_program_location_none = 0, + glamor_program_location_fg = 1, + glamor_program_location_bg = 2, + glamor_program_location_fill = 4, + glamor_program_location_font = 8, +} glamor_program_location; + +typedef enum { + glamor_program_flag_none = 0, +} glamor_program_flag; + +typedef struct _glamor_program glamor_program; + +typedef Bool (*glamor_use) (PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg); + +typedef struct { + const char *name; + const int version; + const char *vs_vars; + const char *vs_exec; + const char *fs_vars; + const char *fs_exec; + const glamor_program_location locations; + const glamor_program_flag flags; + const char *source_name; + glamor_use use; +} glamor_facet; + +struct _glamor_program { + GLint prog; + GLint failed; + GLint matrix_uniform; + GLint fg_uniform; + GLint bg_uniform; + GLint fill_size_uniform; + GLint fill_offset_uniform; + GLint font_uniform; + glamor_program_location locations; + glamor_program_flag flags; + glamor_use prim_use; + glamor_use fill_use; +}; + +typedef struct { + glamor_program progs[4]; +} glamor_program_fill; + +extern const glamor_facet glamor_fill_solid; + +Bool +glamor_build_program(ScreenPtr screen, + glamor_program *prog, + const glamor_facet *prim, + const glamor_facet *fill); + +Bool +glamor_use_program(PixmapPtr pixmap, + GCPtr gc, + glamor_program *prog, + void *arg); + +glamor_program * +glamor_use_program_fill(PixmapPtr pixmap, + GCPtr gc, + glamor_program_fill *program_fill, + const glamor_facet *prim); + +#endif /* _GLAMOR_PROGRAM_H_ */ diff --git a/xorg-server/glamor/glamor_render.c b/xorg-server/glamor/glamor_render.c index c0ee22c2f..cdf8effdc 100644 --- a/xorg-server/glamor/glamor_render.c +++ b/xorg-server/glamor/glamor_render.c @@ -412,29 +412,10 @@ glamor_init_composite_shaders(ScreenPtr screen) eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2; - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, NULL, GL_STATIC_DRAW); - eb = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - } - else { - eb = malloc(eb_size); - } - - if (eb == NULL) - FatalError - ("fatal error, fail to get element buffer. GL context may be not created correctly.\n"); + eb = XNFalloc(eb_size); glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT); - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - else { - glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - free(eb); - } + glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW); + free(eb); glamor_put_context(glamor_priv); } @@ -448,6 +429,7 @@ glamor_fini_composite_shaders(ScreenPtr screen) glamor_priv = glamor_get_screen_private(screen); glamor_get_context(glamor_priv); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDeleteBuffers(1, &glamor_priv->ebo); for (i = 0; i < SHADER_SOURCE_COUNT; i++) @@ -706,8 +688,6 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts) glamor_get_context(glamor_priv); 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, vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); @@ -1329,7 +1309,6 @@ glamor_composite_with_shader(CARD8 op, } } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); diff --git a/xorg-server/glamor/glamor_segment.c b/xorg-server/glamor/glamor_segment.c new file mode 100644 index 000000000..84b27acce --- /dev/null +++ b/xorg-server/glamor/glamor_segment.c @@ -0,0 +1,39 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "glamor_priv.h" + +Bool +glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc, int nseg, + xSegment *seg) +{ + return FALSE; +} + +void +glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg, + xSegment *seg) +{ + if (glamor_poly_segment_nf(drawable, gc, nseg, seg)) + return; + miPolySegment(drawable, gc, nseg, seg); +} diff --git a/xorg-server/glamor/glamor_transform.c b/xorg-server/glamor/glamor_transform.c new file mode 100644 index 000000000..d6ba56421 --- /dev/null +++ b/xorg-server/glamor/glamor_transform.c @@ -0,0 +1,215 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "glamor_priv.h" +#include "glamor_transform.h" + + +/* + * Set up rendering to target the specified drawable, computing an + * appropriate transform for the vertex shader to convert + * drawable-relative coordinates into pixmap-relative coordinates. If + * requested, the offset from pixmap origin coordinates back to window + * system coordinates will be returned in *p_off_x, *p_off_y so that + * clipping computations can be adjusted as appropriate + */ + +void +glamor_set_destination_drawable(DrawablePtr drawable, + int box_x, + int box_y, + Bool do_drawable_translate, + Bool center_offset, + GLint matrix_uniform_location, + int *p_off_x, + int *p_off_y) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + int off_x, off_y; + BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y); + int w = box->x2 - box->x1; + int h = box->y2 - box->y1; + float scale_x = 2.0f / (float) w; + float scale_y = 2.0f / (float) h; + float center_adjust = 0.0f; + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + + off_x -= box->x1; + off_y -= box->y1; + + if (p_off_x) { + *p_off_x = off_x; + *p_off_y = off_y; + } + + /* A tricky computation to find the right value for the two linear functions + * that transform rendering coordinates to pixmap coordinates + * + * pixmap_x = render_x + drawable->x + off_x + * pixmap_y = render_y + drawable->y + off_y + * + * gl_x = pixmap_x * 2 / width - 1 + * gl_y = pixmap_y * 2 / height - 1 + * + * gl_x = (render_x + drawable->x + off_x) * 2 / width - 1 + * + * gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1 + * + * I'll think about yInverted later, when I have some way to test + */ + + if (do_drawable_translate) { + off_x += drawable->x; + off_y += drawable->y; + } + + /* + * To get GL_POINTS drawn in the right spot, we need to adjust the + * coordinates by 1/2 a pixel. + */ + if (center_offset) + center_adjust = 0.5f; + + glUniform4f(matrix_uniform_location, + scale_x, (off_x + center_adjust) * scale_x - 1.0f, + scale_y, (off_y + center_adjust) * scale_y - 1.0f); + + glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y), + 0, 0, w, h); +} + +/* + * Set up for solid rendering to the specified pixmap using alu, fg and planemask + * from the specified GC. Load the target color into the specified uniform + */ + +void +glamor_set_color(PixmapPtr pixmap, + CARD32 pixel, + GLint uniform) +{ + float color[4]; + + glamor_get_rgba_from_pixel(pixel, + &color[0], &color[1], &color[2], &color[3], + format_for_pixmap(pixmap)); + + glUniform4fv(uniform, 1, color); +} + +Bool +glamor_set_solid(PixmapPtr pixmap, + GCPtr gc, + Bool use_alu, + GLint uniform) +{ + CARD32 pixel; + int alu = use_alu ? gc->alu : GXcopy; + + if (!glamor_set_planemask(pixmap, gc->planemask)) + return FALSE; + + pixel = gc->fgPixel; + + if (!glamor_set_alu(pixmap->drawable.pScreen, alu)) { + switch (gc->alu) { + case GXclear: + pixel = 0; + break; + case GXcopyInverted: + pixel = ~pixel; + break; + case GXset: + pixel = ~0 & gc->planemask; + break; + default: + return FALSE; + } + } + glamor_set_color(pixmap, gc->fgPixel, uniform); + + return TRUE; +} + +Bool +glamor_set_texture(PixmapPtr pixmap, + PixmapPtr texture, + int off_x, + int off_y, + GLint offset_uniform, + GLint size_uniform) +{ + glamor_pixmap_private *texture_priv; + + texture_priv = glamor_get_pixmap_private(texture); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv)) + return FALSE; + + if (texture_priv->type == GLAMOR_TEXTURE_LARGE) + return FALSE; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_priv->base.fbo->tex); + + glUniform2f(offset_uniform, off_x, off_y); + glUniform2f(size_uniform, texture->drawable.width, texture->drawable.height); + return TRUE; +} + +Bool +glamor_set_tiled(PixmapPtr pixmap, + GCPtr gc, + GLint offset_uniform, + GLint size_uniform) +{ + if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu)) + return FALSE; + + if (!glamor_set_planemask(pixmap, gc->planemask)) + return FALSE; + + return glamor_set_texture(pixmap, + gc->tile.pixmap, + -gc->patOrg.x, + -gc->patOrg.y, + offset_uniform, + size_uniform); +} + +Bool +glamor_set_stippled(PixmapPtr pixmap, + GCPtr gc, + GLint fg_uniform, + GLint offset_uniform, + GLint size_uniform) +{ + if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform)) + return FALSE; + + if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform)) + return FALSE; + + return TRUE; +} diff --git a/xorg-server/glamor/glamor_transform.h b/xorg-server/glamor/glamor_transform.h new file mode 100644 index 000000000..36b789af8 --- /dev/null +++ b/xorg-server/glamor/glamor_transform.h @@ -0,0 +1,87 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _GLAMOR_TRANSFORM_H_ +#define _GLAMOR_TRANSFORM_H_ + +void +glamor_set_destination_drawable(DrawablePtr drawable, + int box_x, + int box_y, + Bool do_drawable_translate, + Bool center_offset, + GLint matrix_uniform_location, + int *p_off_x, + int *p_off_y); + +void +glamor_set_color(PixmapPtr pixmap, + CARD32 pixel, + GLint uniform); + +Bool +glamor_set_texture(PixmapPtr pixmap, + PixmapPtr texture, + int off_x, + int off_y, + GLint offset_uniform, + GLint size_uniform); + +Bool +glamor_set_solid(PixmapPtr pixmap, + GCPtr gc, + Bool use_alu, + GLint uniform); + +Bool +glamor_set_tiled(PixmapPtr pixmap, + GCPtr gc, + GLint offset_uniform, + GLint size_uniform); + +Bool +glamor_set_stippled(PixmapPtr pixmap, + GCPtr gc, + GLint fg_uniform, + GLint offset_uniform, + GLint size_uniform); + +/* + * Vertex shader bits that transform X coordinates to pixmap + * coordinates using the matrix computed above + */ + +#define GLAMOR_DECLARE_MATRIX "uniform vec4 v_matrix;\n" +#define GLAMOR_X_POS(x) #x " *v_matrix.x + v_matrix.y" +#define GLAMOR_Y_POS(y) #y " *v_matrix.z + v_matrix.w" +#if 0 +#define GLAMOR_POS(dst,src) \ + " " #dst ".x = " #src ".x * v_matrix.x + v_matrix.y;\n" \ + " " #dst ".y = " #src ".y * v_matrix.z + v_matrix.w;\n" \ + " " #dst ".z = 0.0;\n" \ + " " #dst ".w = 1.0;\n" +#endif +#define GLAMOR_POS(dst,src) \ + " " #dst ".xy = " #src ".xy * v_matrix.xz + v_matrix.yw;\n" \ + " " #dst ".zw = vec2(0.0,1.0);\n" + +#endif /* _GLAMOR_TRANSFORM_H_ */ diff --git a/xorg-server/glamor/glamor_trapezoid.c b/xorg-server/glamor/glamor_trapezoid.c index 969ab68bc..c76b8bb2a 100644 --- a/xorg-server/glamor/glamor_trapezoid.c +++ b/xorg-server/glamor/glamor_trapezoid.c @@ -637,8 +637,6 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts) 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, @@ -977,7 +975,6 @@ _glamor_trapezoids_with_shader(CARD8 op, ret = TRUE; TRAPEZOID_RESET_GL: - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); @@ -1415,8 +1412,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale)); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - /* Now draw the Trapezoid mask. */ glUseProgram(trapezoid_prog); @@ -1562,7 +1557,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, } } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); diff --git a/xorg-server/glamor/glamor_vbo.c b/xorg-server/glamor/glamor_vbo.c index 5e98bfe47..2731692d6 100644 --- a/xorg-server/glamor/glamor_vbo.c +++ b/xorg-server/glamor/glamor_vbo.c @@ -96,7 +96,7 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset) *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) { + } else if (glamor_priv->has_map_buffer_range) { if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) { glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size); glamor_priv->vbo_offset = 0; @@ -147,7 +147,7 @@ glamor_put_vbo_space(ScreenPtr screen) * 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) { + } else if (glamor_priv->has_map_buffer_range) { glUnmapBuffer(GL_ARRAY_BUFFER); } else { glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, @@ -179,7 +179,7 @@ glamor_fini_vbo(ScreenPtr screen) glamor_get_context(glamor_priv); glDeleteBuffers(1, &glamor_priv->vbo); - if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP) + if (!glamor_priv->has_map_buffer_range) free(glamor_priv->vb); glamor_put_context(glamor_priv); diff --git a/xorg-server/hw/dmx/dmxinit.c b/xorg-server/hw/dmx/dmxinit.c index 3fd439300..c782a9bff 100644 --- a/xorg-server/hw/dmx/dmxinit.c +++ b/xorg-server/hw/dmx/dmxinit.c @@ -597,10 +597,8 @@ static void dmxAddExtensions(Bool glxSupported) { GlxExtensionInit, "GLX", &glxSupported }, #endif }; - int i; - for (i = 0; i < ARRAY_SIZE(dmxExtensions); i++) - LoadExtension(&dmxExtensions[i], TRUE); + LoadExtensionList(dmxExtensions, ARRAY_SIZE(dmxExtensions), TRUE); } /** This routine is called in Xserver/dix/main.c from \a main(). */ diff --git a/xorg-server/hw/kdrive/ephyr/Makefile.am b/xorg-server/hw/kdrive/ephyr/Makefile.am index 040993ce0..00a53d0df 100644 --- a/xorg-server/hw/kdrive/ephyr/Makefile.am +++ b/xorg-server/hw/kdrive/ephyr/Makefile.am @@ -38,7 +38,7 @@ if GLAMOR GLAMOR_SRCS = \ ephyr_glamor_glx.c \ ephyr_glamor_glx.h \ - () + $() endif if DRI diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c index 5b8d09ff0..5861da67f 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c @@ -66,10 +66,7 @@ static const ExtensionModule ephyrExtensions[] = { static void ephyrExtensionInit(void) { - int i; - - for (i = 0; i < ARRAY_SIZE(ephyrExtensions); i++) - LoadExtension(&ephyrExtensions[i], TRUE); + LoadExtensionList(ephyrExtensions, ARRAY_SIZE(ephyrExtensions), TRUE); } diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index 01ea6c756..8aadb2aab 100755 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -728,6 +728,12 @@ __asm int 3; malloc(scrpriv->ximg->stride * buffer_height); } + { + uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + uint32_t values[2] = {width, height}; + xcb_configure_window(HostX.conn, scrpriv->win, mask, values); + } + if (scrpriv->win_pre_existing == None && !EphyrWantResize) { /* Ask the WM to keep our size static */ xcb_size_hints_t size_hints = {0}; @@ -1286,7 +1292,9 @@ ephyr_glamor_create_screen_resources(ScreenPtr pScreen) screen_pixmap = pScreen->CreatePixmap(pScreen, pScreen->width, pScreen->height, - pScreen->rootDepth, 0); + pScreen->rootDepth, + GLAMOR_CREATE_NO_LARGE); + pScreen->SetScreenPixmap(screen_pixmap); /* Tell the GLX code what to GL texture to read from. */ diff --git a/xorg-server/hw/kdrive/src/kxv.c b/xorg-server/hw/kdrive/src/kxv.c index 445eb605b..9cc0edd8a 100644 --- a/xorg-server/hw/kdrive/src/kxv.c +++ b/xorg-server/hw/kdrive/src/kxv.c @@ -385,28 +385,7 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number) for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages; i < adaptorPtr->nImages; i++, pi++, imagePtr++) { - pi->id = imagePtr->id; - pi->type = imagePtr->type; - pi->byte_order = imagePtr->byte_order; - memcpy(pi->guid, imagePtr->guid, 16); - pi->bits_per_pixel = imagePtr->bits_per_pixel; - pi->format = imagePtr->format; - pi->num_planes = imagePtr->num_planes; - pi->depth = imagePtr->depth; - pi->red_mask = imagePtr->red_mask; - pi->green_mask = imagePtr->green_mask; - pi->blue_mask = imagePtr->blue_mask; - pi->y_sample_bits = imagePtr->y_sample_bits; - pi->u_sample_bits = imagePtr->u_sample_bits; - pi->v_sample_bits = imagePtr->v_sample_bits; - pi->horz_y_period = imagePtr->horz_y_period; - pi->horz_u_period = imagePtr->horz_u_period; - pi->horz_v_period = imagePtr->horz_v_period; - pi->vert_y_period = imagePtr->vert_y_period; - pi->vert_u_period = imagePtr->vert_u_period; - pi->vert_v_period = imagePtr->vert_v_period; - memcpy(pi->component_order, imagePtr->component_order, 32); - pi->scanline_order = imagePtr->scanline_order; + memcpy(pi, imagePtr, sizeof(*pi)); } pa->nImages = adaptorPtr->nImages; pa->pImages = pImage; @@ -417,9 +396,7 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number) calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) { for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) { - pat->flags = attributePtr->flags; - pat->min_value = attributePtr->min_value; - pat->max_value = attributePtr->max_value; + memcpy(pat, attributePtr, sizeof(*pat)); pat->name = strdup(attributePtr->name); } pa->nAttributes = adaptorPtr->nAttributes; diff --git a/xorg-server/hw/kdrive/src/kxv.h b/xorg-server/hw/kdrive/src/kxv.h index 4f644c246..85a030ee9 100644 --- a/xorg-server/hw/kdrive/src/kxv.h +++ b/xorg-server/hw/kdrive/src/kxv.h @@ -56,34 +56,7 @@ of the copyright holder. #define VIDEO_OVERLAID_STILLS 0x00000008 #define VIDEO_CLIP_TO_VIEWPORT 0x00000010 -typedef struct { - int id; - int type; - int byte_order; - unsigned char guid[16]; - int bits_per_pixel; - int format; - int num_planes; - - /* for RGB formats only */ - int depth; - unsigned int red_mask; - unsigned int green_mask; - unsigned int blue_mask; - - /* for YUV formats only */ - unsigned int y_sample_bits; - unsigned int u_sample_bits; - unsigned int v_sample_bits; - unsigned int horz_y_period; - unsigned int horz_u_period; - unsigned int horz_v_period; - unsigned int vert_y_period; - unsigned int vert_u_period; - unsigned int vert_v_period; - char component_order[32]; - int scanline_order; -} KdImageRec, *KdImagePtr; +typedef XvImageRec KdImageRec, *KdImagePtr; typedef struct { KdScreenInfo *screen; @@ -158,12 +131,7 @@ typedef struct { short class; } KdVideoFormatRec, *KdVideoFormatPtr; -typedef struct { - int flags; - int min_value; - int max_value; - char *name; -} KdAttributeRec, *KdAttributePtr; +typedef XvAttributeRec KdAttributeRec, *KdAttributePtr; typedef struct { unsigned int type; diff --git a/xorg-server/hw/vfb/InitOutput.c b/xorg-server/hw/vfb/InitOutput.c index 2175ac685..9c4926462 100644 --- a/xorg-server/hw/vfb/InitOutput.c +++ b/xorg-server/hw/vfb/InitOutput.c @@ -892,10 +892,7 @@ static const ExtensionModule vfbExtensions[] = { static void vfbExtensionInit(void) { - int i; - - for (i = 0; i < ARRAY_SIZE(vfbExtensions); i++) - LoadExtension(&vfbExtensions[i], TRUE); + LoadExtensionList(vfbExtensions, ARRAY_SIZE(vfbExtensions), TRUE); } void diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index a315bbc17..18fa99b08 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -43,7 +43,7 @@ SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \ DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ parser ramdac shadowfb vbe vgahw \ loader dixmods dri dri2 exa modes \ - utils doc man + utils doc man glamor_egl bin_PROGRAMS = Xorg nodist_Xorg_SOURCES = sdksyms.c diff --git a/xorg-server/hw/xfree86/common/xf86Extensions.c b/xorg-server/hw/xfree86/common/xf86Extensions.c index c80de34e6..25b2bc3d0 100644 --- a/xorg-server/hw/xfree86/common/xf86Extensions.c +++ b/xorg-server/hw/xfree86/common/xf86Extensions.c @@ -132,10 +132,7 @@ load_extension_config(void) void xf86ExtensionInit(void) { - int i; - load_extension_config(); - for (i = 0; i < ARRAY_SIZE(extensionModules); i++) - LoadExtension(&extensionModules[i], TRUE); + LoadExtensionList(extensionModules, ARRAY_SIZE(extensionModules), TRUE); } diff --git a/xorg-server/hw/xfree86/dixmods/glxmodule.c b/xorg-server/hw/xfree86/dixmods/glxmodule.c index bf7d182a2..d53c6652d 100644 --- a/xorg-server/hw/xfree86/dixmods/glxmodule.c +++ b/xorg-server/hw/xfree86/dixmods/glxmodule.c @@ -47,10 +47,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static MODULESETUPPROTO(glxSetup); -static const ExtensionModule GLXExt = { - GlxExtensionInit, - "GLX", - &noGlxExtension +static const ExtensionModule GLXExt[] = { + { GlxExtensionInit, "GLX", &noGlxExtension }, }; static XF86ModuleVersionInfo VersRec = { @@ -90,7 +88,7 @@ glxSetup(void *module, void *opts, int *errmaj, int *errmin) GlxPushProvider(provider); } - LoadExtension(&GLXExt, FALSE); + LoadExtensionList(GLXExt, ARRAY_SIZE(GLXExt), FALSE); return module; } diff --git a/xorg-server/hw/xfree86/doc/ddxDesign.xml b/xorg-server/hw/xfree86/doc/ddxDesign.xml index 7c2c20ff3..d1fd9af7b 100644 --- a/xorg-server/hw/xfree86/doc/ddxDesign.xml +++ b/xorg-server/hw/xfree86/doc/ddxDesign.xml @@ -5920,10 +5920,10 @@ These may be moved out of the loader at some point. <blockquote><para> <programlisting> - void LoadExtension(ExtensionModule *ext); + void LoadExtensionList(const ExtensionModule ext[]); </programlisting> <blockquote><para> - This registers the entry points for the extension identified by + This registers the entry points for the extension array identified by <parameter>ext</parameter>. The <structname>ExtensionModule</structname> struct is defined as: diff --git a/xorg-server/hw/xquartz/quartz.c b/xorg-server/hw/xquartz/quartz.c index bc6c8d048..d7229cecb 100644 --- a/xorg-server/hw/xquartz/quartz.c +++ b/xorg-server/hw/xquartz/quartz.c @@ -164,10 +164,7 @@ static const ExtensionModule quartzExtensions[] = { */ static void QuartzExtensionInit(void) { - int i; - - for (i = 0; i < ARRAY_SIZE(quartzExtensions); i++) - LoadExtension(&quartzExtensions[i], TRUE); + LoadExtensionList(quartzExtensions, ARRAY_SIZE(quartzExtensions), TRUE); } /* diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c index df670ff0e..640195993 100644 --- a/xorg-server/hw/xwin/InitOutput.c +++ b/xorg-server/hw/xwin/InitOutput.c @@ -156,8 +156,6 @@ static const ExtensionModule xwinExtensions[] = { static void XwinExtensionInit(void) { - int i; - #ifdef XWIN_GLX_WINDOWS if (g_fNativeGl) { /* install the native GL provider */ @@ -165,8 +163,7 @@ void XwinExtensionInit(void) } #endif - for (i = 0; i < ARRAY_SIZE(xwinExtensions); i++) - LoadExtension(&xwinExtensions[i], TRUE); + LoadExtensionList(xwinExtensions, ARRAY_SIZE(xwinExtensions), TRUE); } #if defined(DDXBEFORERESET) diff --git a/xorg-server/include/extension.h b/xorg-server/include/extension.h index acc6addb7..7c09af150 100644 --- a/xorg-server/include/extension.h +++ b/xorg-server/include/extension.h @@ -97,6 +97,7 @@ extern _X_EXPORT void InitExtensions(int argc, char **argv); extern _X_EXPORT void CloseDownExtensions(void); -extern _X_EXPORT void LoadExtension(const ExtensionModule *ext, Bool external); +extern _X_EXPORT void LoadExtensionList(const ExtensionModule ext[], + int listSize, Bool external); #endif /* EXTENSION_H */ diff --git a/xorg-server/include/opaque.h b/xorg-server/include/opaque.h index 73d40c345..7ec1d850f 100644 --- a/xorg-server/include/opaque.h +++ b/xorg-server/include/opaque.h @@ -74,5 +74,6 @@ extern _X_EXPORT Bool whiteRoot; extern _X_EXPORT Bool bgNoneRoot; extern _X_EXPORT Bool CoreDump; +extern _X_EXPORT Bool NoListenAll; #endif /* OPAQUE_H */ diff --git a/xorg-server/include/os.h b/xorg-server/include/os.h index eac227475..ed7e8806a 100644 --- a/xorg-server/include/os.h +++ b/xorg-server/include/os.h @@ -168,9 +168,9 @@ extern _X_EXPORT void MakeClientGrabImpervious(ClientPtr /*client */ ); extern _X_EXPORT void MakeClientGrabPervious(ClientPtr /*client */ ); -#ifdef XQUARTZ -extern void ListenOnOpenFD(int /* fd */ , int /* noxauth */ ); -#endif +extern _X_EXPORT void ListenOnOpenFD(int /* fd */ , int /* noxauth */ ); + +extern _X_EXPORT Bool AddClientOnOpenFD(int /* fd */ ); extern _X_EXPORT CARD32 GetTimeInMillis(void); extern _X_EXPORT CARD64 GetTimeInMicros(void); diff --git a/xorg-server/include/xkbsrv.h b/xorg-server/include/xkbsrv.h index ae43889e7..a1bb62110 100644 --- a/xorg-server/include/xkbsrv.h +++ b/xorg-server/include/xkbsrv.h @@ -824,6 +824,9 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr /* kbd */ , extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ , XkbDescPtr /* src */ ); +extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */, + DeviceIntPtr /* src */); + extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ , XkbDescPtr /* src */ ); diff --git a/xorg-server/mi/mibitblt.c b/xorg-server/mi/mibitblt.c index b0d14ae55..3ed4ed1cc 100644 --- a/xorg-server/mi/mibitblt.c +++ b/xorg-server/mi/mibitblt.c @@ -730,7 +730,7 @@ miPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, ChangeGC(NullClient, pGC, GCForeground | GCBackground, gcv); bytesPer = (long) h *BitmapBytePad(w + leftPad); - for (i = 1 << (depth - 1); i != 0; i >>= 1, pImage += bytesPer) { + for (i = (unsigned long) 1 << (depth - 1); i != 0; i >>= 1, pImage += bytesPer) { if (i & oldPlanemask) { gcv[0].val = (XID) i; ChangeGC(NullClient, pGC, GCPlaneMask, gcv); diff --git a/xorg-server/mi/miinitext.c b/xorg-server/mi/miinitext.c index e5648724c..5b45ab4c2 100644 --- a/xorg-server/mi/miinitext.c +++ b/xorg-server/mi/miinitext.c @@ -312,15 +312,13 @@ static void AddStaticExtensions(void) { static Bool listInitialised = FALSE; - int i; if (listInitialised) return; listInitialised = TRUE; /* Add built-in extensions to the list. */ - for (i = 0; i < ARRAY_SIZE(staticExtensions); i++) - LoadExtension(&staticExtensions[i], TRUE); + LoadExtensionList(staticExtensions, ARRAY_SIZE(staticExtensions), TRUE); } void @@ -331,7 +329,7 @@ InitExtensions(int argc, char *argv[]) AddStaticExtensions(); - for (i = 0; ExtensionModuleList[i].name != NULL; i++) { + for (i = 0; i < numExtensionModules; i++) { ext = &ExtensionModuleList[i]; if (ext->initFunc != NULL && (ext->disablePtr == NULL || !*ext->disablePtr)) { @@ -341,50 +339,52 @@ InitExtensions(int argc, char *argv[]) } static ExtensionModule * -NewExtensionModule(void) +NewExtensionModuleList(int size) { ExtensionModule *save = ExtensionModuleList; int n; - /* Make sure built-in extensions get added to the list before those - * in modules. */ - AddStaticExtensions(); - /* Sanity check */ if (!ExtensionModuleList) numExtensionModules = 0; - n = numExtensionModules + 1; + n = numExtensionModules + size; ExtensionModuleList = realloc(ExtensionModuleList, - (n + 1) * sizeof(ExtensionModule)); + n * sizeof(ExtensionModule)); if (ExtensionModuleList == NULL) { ExtensionModuleList = save; return NULL; } else { - numExtensionModules++; - ExtensionModuleList[numExtensionModules].name = NULL; - return ExtensionModuleList + (numExtensionModules - 1); + numExtensionModules += size; + return ExtensionModuleList + (numExtensionModules - size); } } void -LoadExtension(const ExtensionModule * e, Bool builtin) +LoadExtensionList(const ExtensionModule ext[], int size, Bool builtin) { ExtensionModule *newext; + const char *msg; + int i; - if (e == NULL || e->name == NULL) - return; + /* Make sure built-in extensions get added to the list before those + * in modules. */ + AddStaticExtensions(); - if (!(newext = NewExtensionModule())) + if (!(newext = NewExtensionModuleList(size))) return; if (builtin) - ErrorF("Initializing built-in extension %s\n", e->name); + msg = "Initializing built-in"; else - ErrorF("Loading extension %s\n", e->name); + msg = "Loading"; + + for (i = 0; i < size; i++, newext++) { + ErrorF("%s extension %s\n", msg, ext[i].name); - newext->name = e->name; - newext->initFunc = e->initFunc; - newext->disablePtr = e->disablePtr; + newext->name = ext[i].name; + newext->initFunc = ext[i].initFunc; + newext->disablePtr = ext[i].disablePtr; + } } diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c index 7c48d46b0..80489f0e2 100644 --- a/xorg-server/os/connection.c +++ b/xorg-server/os/connection.c @@ -145,6 +145,7 @@ fd_set OutputPending; /* clients with reply/event data ready to go */ int MaxClients = 0; Bool NewOutputPending; /* not yet attempted to write some new output */ Bool AnyClientsWriteBlocked; /* true if some client blocked on write */ +Bool NoListenAll; /* Don't establish any listening sockets */ #if !defined(_MSC_VER) static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */ @@ -438,7 +439,10 @@ CreateWellKnownSockets(void) /* display is initialized to "0" by main(). It is then set to the display * number if specified on the command line, or to NULL when the -displayfd * option is used. */ - if (display) { + if (NoListenAll) { + ListenTransCount = 0; + } + else if (display) { if (TryCreateSocket(atoi(display), &partial) && ListenTransCount >= 1) if (!PartialNetwork && partial) @@ -477,9 +481,10 @@ CreateWellKnownSockets(void) } } - if (!XFD_ANYSET(&WellKnownConnections)) + if (!XFD_ANYSET(&WellKnownConnections) && !NoListenAll) FatalError ("Cannot establish any listening sockets - Make sure an X server isn't already running"); + #if !defined(WIN32) OsSignal(SIGPIPE, SIG_IGN); OsSignal(SIGHUP, AutoResetServer); @@ -1300,8 +1305,7 @@ MakeClientGrabPervious(ClientPtr client) } } -#ifdef XQUARTZ -/* Add a fd (from launchd) to our listeners */ +/* Add a fd (from launchd or similar) to our listeners */ void ListenOnOpenFD(int fd, int noxauth) { @@ -1323,7 +1327,7 @@ ListenOnOpenFD(int fd, int noxauth) */ ciptr = _XSERVTransReopenCOTSServer(5, fd, port); if (ciptr == NULL) { - ErrorF("Got NULL while trying to Reopen launchd port.\n"); + ErrorF("Got NULL while trying to Reopen listen port.\n"); return; } @@ -1356,4 +1360,29 @@ ListenOnOpenFD(int fd, int noxauth) #endif } -#endif +/* based on TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) */ +Bool +AddClientOnOpenFD(int fd) +{ + XtransConnInfo ciptr; + CARD32 connect_time; + char port[20]; + + snprintf(port, sizeof(port), ":%d", atoi(display)); + ciptr = _XSERVTransReopenCOTSServer(5, fd, port); + if (ciptr == NULL) + return FALSE; + + _XSERVTransSetOption(ciptr, TRANS_NONBLOCKING, 1); + ciptr->flags |= TRANS_NOXAUTH; + + connect_time = GetTimeInMillis(); + + if (!AllocNewConnection(ciptr, fd, connect_time)) { + ErrorConnMax(ciptr); + _XSERVTransClose(ciptr); + return FALSE; + } + + return TRUE; +} diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c index cbd5c7ad5..c514ae11a 100644 --- a/xorg-server/os/utils.c +++ b/xorg-server/os/utils.c @@ -290,7 +290,7 @@ LockServer(void) int len; char port[20]; - if (nolock) + if (nolock || NoListenAll) return; /* * Path names @@ -411,7 +411,7 @@ LockServer(void) void UnlockServer(void) { - if (nolock) + if (nolock || NoListenAll) return; if (!StillLocking) { diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am index f8aa65950..88fb6aa96 100644 --- a/xorg-server/test/Makefile.am +++ b/xorg-server/test/Makefile.am @@ -30,7 +30,6 @@ endif xkb_LDADD=$(TEST_LDADD) input_LDADD=$(TEST_LDADD) xtest_LDADD=$(TEST_LDADD) -list_LDADD=$(TEST_LDADD) misc_LDADD=$(TEST_LDADD) fixes_LDADD=$(TEST_LDADD) xfree86_LDADD=$(TEST_LDADD) diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c index 6cf6e79df..c14a790df 100644 --- a/xorg-server/xkb/xkbUtils.c +++ b/xorg-server/xkb/xkbUtils.c @@ -2027,6 +2027,12 @@ XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc) return ret; } +Bool +XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src) +{ + return XkbDeviceApplyKeymap(dst, src->key->xkbInfo->desc); +} + int XkbGetEffectiveGroup(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 keycode) { |