From d0c30e7945e76ac119f6d867e27137c8a76f7e15 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 19 Jul 2014 15:00:38 +0200 Subject: fontconfig plink libX11 libxcb mesa git update 19 July 2014 plink revision 10207 xserver commit cfa302d6224d10860e60491333950544c4fb9b04 libxcb commit 49a61c8b459ab19c7f39e653bbb0d0339ea8f00f libX11 commit 5525e8433f93bce464412f27cffa203ea628f368 fontconfig commit 6781c6baef062eeea5b5b68e4a9c31ea6cd7539b mesa commit f6fc80734533140a69b30361fe0d4773a03515db --- xorg-server/glamor/Makefile.am | 16 +- xorg-server/glamor/glamor.c | 51 +-- xorg-server/glamor/glamor.h | 23 +- xorg-server/glamor/glamor_copy.c | 693 ++++++++++++++++++++++++++++++++ xorg-server/glamor/glamor_copyarea.c | 626 ----------------------------- xorg-server/glamor/glamor_copyplane.c | 75 ---- xorg-server/glamor/glamor_copywindow.c | 56 --- xorg-server/glamor/glamor_core.c | 202 ++++------ xorg-server/glamor/glamor_dash.c | 370 +++++++++++++++++ xorg-server/glamor/glamor_fill.c | 356 ---------------- xorg-server/glamor/glamor_glyphblt.c | 154 +++---- xorg-server/glamor/glamor_glyphs.c | 10 +- xorg-server/glamor/glamor_gradient.c | 19 +- xorg-server/glamor/glamor_largepixmap.c | 13 +- xorg-server/glamor/glamor_lines.c | 187 +++++++++ xorg-server/glamor/glamor_picture.c | 18 - xorg-server/glamor/glamor_pixmap.c | 509 +---------------------- xorg-server/glamor/glamor_points.c | 3 - xorg-server/glamor/glamor_polylines.c | 136 ------- xorg-server/glamor/glamor_prepare.c | 274 +++++++++++++ xorg-server/glamor/glamor_prepare.h | 52 +++ xorg-server/glamor/glamor_priv.h | 266 ++++++------ xorg-server/glamor/glamor_program.c | 56 ++- xorg-server/glamor/glamor_program.h | 6 + xorg-server/glamor/glamor_render.c | 105 ++--- xorg-server/glamor/glamor_segment.c | 44 -- xorg-server/glamor/glamor_segs.c | 188 +++++++++ xorg-server/glamor/glamor_spans.c | 3 - xorg-server/glamor/glamor_sync.c | 117 ++++++ xorg-server/glamor/glamor_text.c | 6 - xorg-server/glamor/glamor_tile.c | 293 -------------- xorg-server/glamor/glamor_transfer.c | 48 +-- xorg-server/glamor/glamor_transform.c | 72 +++- xorg-server/glamor/glamor_trapezoid.c | 22 +- xorg-server/glamor/glamor_utils.c | 79 ++++ xorg-server/glamor/glamor_utils.h | 218 ++++------ xorg-server/glamor/glamor_xv.c | 265 ++++-------- 37 files changed, 2643 insertions(+), 2988 deletions(-) create mode 100644 xorg-server/glamor/glamor_copy.c delete mode 100644 xorg-server/glamor/glamor_copyarea.c delete mode 100644 xorg-server/glamor/glamor_copyplane.c delete mode 100644 xorg-server/glamor/glamor_copywindow.c create mode 100644 xorg-server/glamor/glamor_dash.c delete mode 100644 xorg-server/glamor/glamor_fill.c create mode 100644 xorg-server/glamor/glamor_lines.c delete mode 100644 xorg-server/glamor/glamor_polylines.c create mode 100644 xorg-server/glamor/glamor_prepare.c create mode 100644 xorg-server/glamor/glamor_prepare.h delete mode 100644 xorg-server/glamor/glamor_segment.c create mode 100644 xorg-server/glamor/glamor_segs.c create mode 100644 xorg-server/glamor/glamor_sync.c delete mode 100644 xorg-server/glamor/glamor_tile.c create mode 100644 xorg-server/glamor/glamor_utils.c (limited to 'xorg-server/glamor') diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am index bde58b632..db72cb11c 100644 --- a/xorg-server/glamor/Makefile.am +++ b/xorg-server/glamor/Makefile.am @@ -7,20 +7,21 @@ AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ glamor_context.h \ - glamor_copyarea.c \ - glamor_copywindow.c \ + glamor_copy.c \ glamor_core.c \ + glamor_dash.c \ glamor_debug.h \ - glamor_fill.c \ glamor_font.c \ glamor_font.h \ glamor_glx.c \ glamor_glyphs.c \ - glamor_polylines.c \ - glamor_segment.c \ glamor_image.c \ + glamor_lines.c \ + glamor_segs.c \ glamor_render.c \ glamor_gradient.c \ + glamor_prepare.c \ + glamor_prepare.h \ glamor_program.c \ glamor_program.h \ glamor_rects.c \ @@ -31,10 +32,8 @@ libglamor_la_SOURCES = \ glamor_transform.c \ glamor_transform.h \ glamor_trapezoid.c \ - glamor_tile.c \ glamor_triangles.c\ glamor_addtraps.c\ - glamor_copyplane.c\ glamor_glyphblt.c\ glamor_points.c\ glamor_priv.h\ @@ -45,7 +44,10 @@ libglamor_la_SOURCES = \ glamor_window.c\ glamor_fbo.c\ glamor_compositerects.c\ + glamor_utils.c\ glamor_utils.h\ + glamor_xv.c \ + glamor_sync.c \ glamor.h libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c index 358890375..521bc25c8 100644 --- a/xorg-server/glamor/glamor.c +++ b/xorg-server/glamor/glamor.c @@ -35,10 +35,9 @@ #include "glamor_priv.h" -static DevPrivateKeyRec glamor_screen_private_key_index; -DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index; -static DevPrivateKeyRec glamor_pixmap_private_key_index; -DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index; +DevPrivateKeyRec glamor_screen_private_key; +DevPrivateKeyRec glamor_pixmap_private_key; +DevPrivateKeyRec glamor_gc_private_key; /** * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable. @@ -68,7 +67,7 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type) glamor_get_screen_private(pixmap->drawable.pScreen); pixmap_priv = dixLookupPrivate(&pixmap->devPrivates, - glamor_pixmap_private_key); + &glamor_pixmap_private_key); if (pixmap_priv == NULL) { pixmap_priv = calloc(sizeof(*pixmap_priv), 1); glamor_set_pixmap_private(pixmap, pixmap_priv); @@ -251,11 +250,6 @@ glamor_block_handler(ScreenPtr screen) glamor_priv->tick++; glFlush(); glamor_fbo_expire(glamor_priv); - if (glamor_priv->state == RENDER_STATE - && glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) { - glamor_priv->state = IDLE_STATE; - glamor_priv->render_idle_cnt = 0; - } } static void @@ -330,13 +324,8 @@ glamor_init(ScreenPtr screen, unsigned int flags) return FALSE; glamor_priv->flags = flags; - if (flags & GLAMOR_INVERTED_Y_AXIS) { - glamor_priv->yInverted = TRUE; - } - else - glamor_priv->yInverted = FALSE; - if (!dixRegisterPrivateKey(glamor_screen_private_key, PRIVATE_SCREEN, 0)) { + if (!dixRegisterPrivateKey(&glamor_screen_private_key, PRIVATE_SCREEN, 0)) { LogMessage(X_WARNING, "glamor%d: Failed to allocate screen private\n", screen->myNum); @@ -345,11 +334,19 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_set_screen_private(screen, glamor_priv); - if (!dixRegisterPrivateKey(glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) { + if (!dixRegisterPrivateKey(&glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) { LogMessage(X_WARNING, "glamor%d: Failed to allocate pixmap private\n", screen->myNum); - goto fail;; + goto fail; + } + + if (!dixRegisterPrivateKey(&glamor_gc_private_key, PRIVATE_GC, + sizeof (glamor_gc_private))) { + LogMessage(X_WARNING, + "glamor%d: Failed to allocate gc private\n", + screen->myNum); + goto fail; } if (epoxy_is_desktop_gl()) @@ -398,6 +395,10 @@ glamor_init(ScreenPtr screen, unsigned int flags) } } + glamor_priv->has_rw_pbo = FALSE; + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + glamor_priv->has_rw_pbo = TRUE; + glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug"); glamor_priv->has_pack_invert = epoxy_has_gl_extension("GL_MESA_pack_invert"); @@ -407,6 +408,10 @@ glamor_init(ScreenPtr screen, unsigned int flags) epoxy_has_gl_extension("GL_ARB_map_buffer_range"); glamor_priv->has_buffer_storage = epoxy_has_gl_extension("GL_ARB_buffer_storage"); + glamor_priv->has_nv_texture_barrier = + epoxy_has_gl_extension("GL_NV_texture_barrier"); + + glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size); glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size); glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[0]); @@ -505,8 +510,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_init_vbo(screen); glamor_init_pixmap_fbo(screen); - glamor_init_solid_shader(screen); - glamor_init_tile_shader(screen); #ifdef GLAMOR_TRAPEZOID_SHADER glamor_init_trapezoid_shader(screen); #endif @@ -516,6 +519,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) #endif glamor_pixmap_init(screen); glamor_glyphs_init(screen); + glamor_sync_init(screen); glamor_priv->screen = screen; @@ -538,8 +542,6 @@ glamor_release_screen_priv(ScreenPtr screen) #endif glamor_fini_vbo(screen); glamor_fini_pixmap_fbo(screen); - glamor_fini_solid_shader(screen); - glamor_fini_tile_shader(screen); #ifdef GLAMOR_TRAPEZOID_SHADER glamor_fini_trapezoid_shader(screen); #endif @@ -559,7 +561,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv) glamor_pixmap_private *old_priv; glamor_pixmap_fbo *fbo; - old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); + old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key); if (priv) { assert(old_priv == NULL); @@ -572,7 +574,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv) free(old_priv); } - dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key, priv); + dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key, priv); } Bool @@ -587,6 +589,7 @@ glamor_close_screen(ScreenPtr screen) #endif glamor_priv = glamor_get_screen_private(screen); flags = glamor_priv->flags; + glamor_sync_close(screen); glamor_glyphs_fini(screen); screen->CloseScreen = glamor_priv->saved_procs.close_screen; screen->CreateScreenResources = diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h index b0f2212d9..405dbe8ed 100644 --- a/xorg-server/glamor/glamor.h +++ b/xorg-server/glamor/glamor.h @@ -63,7 +63,7 @@ typedef enum glamor_pixmap_type { } glamor_pixmap_type_t; #define GLAMOR_EGL_EXTERNAL_BUFFER 3 -#define GLAMOR_INVERTED_Y_AXIS 1 +#define GLAMOR_INVERTED_Y_AXIS 1 /* compat stub */ #define GLAMOR_USE_SCREEN (1 << 1) #define GLAMOR_USE_PICTURE_SCREEN (1 << 2) #define GLAMOR_USE_EGL_SCREEN (1 << 3) @@ -79,12 +79,6 @@ typedef enum glamor_pixmap_type { * @screen: Current screen pointer. * @flags: Please refer the flags description above. * - * @GLAMOR_INVERTED_Y_AXIS: - * set 1 means the GL env's origin (0,0) is at top-left. - * EGL/DRM platform is an example need to set this bit. - * glx platform's origin is at bottom-left thus need to - * clear this bit. - * * @GLAMOR_USE_SCREEN: * If running in an pre-existing X environment, and the * gl context is GLX, then you should set this bit and @@ -321,6 +315,10 @@ extern _X_EXPORT int glamor_create_gc(GCPtr gc); extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable); +extern _X_EXPORT void glamor_destroy_gc(GCPtr gc); + +#define HAS_GLAMOR_DESTROY_GC 1 + extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region); @@ -354,6 +352,17 @@ extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src, Bool upsidedown, Pixel bitplane, void *closure); +extern _X_EXPORT Bool glamor_copy_nf(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, Pixel bitplane, + void *closure); + extern _X_EXPORT Bool glamor_composite_nf(CARD8 op, PicturePtr source, PicturePtr mask, diff --git a/xorg-server/glamor/glamor_copy.c b/xorg-server/glamor/glamor_copy.c new file mode 100644 index 000000000..bfcde43db --- /dev/null +++ b/xorg-server/glamor/glamor_copy.c @@ -0,0 +1,693 @@ +/* + * 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_transfer.h" +#include "glamor_prepare.h" +#include "glamor_transform.h" + +struct copy_args { + PixmapPtr src_pixmap; + glamor_pixmap_fbo *src; + uint32_t bitplane; + int dx, dy; +}; + +static Bool +use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg) +{ + struct copy_args *args = arg; + glamor_pixmap_fbo *src = args->src; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, src->tex); + + glUniform2f(prog->fill_offset_uniform, args->dx, args->dy); + glUniform2f(prog->fill_size_uniform, src->width, src->height); + + return TRUE; +} + +static const glamor_facet glamor_facet_copyarea = { + "copy_area", + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = (GLAMOR_POS(gl_Position, primitive.xy) + " fill_pos = (fill_offset + primitive.xy) / fill_size;\n"), + .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n", + .locations = glamor_program_location_fill, + .use = use_copyarea, +}; + +/* + * Configure the copy plane program for the current operation + */ + +static Bool +use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg) +{ + struct copy_args *args = arg; + glamor_pixmap_fbo *src = args->src; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, src->tex); + + glUniform2f(prog->fill_offset_uniform, args->dx, args->dy); + glUniform2f(prog->fill_size_uniform, src->width, src->height); + + glamor_set_color(dst, gc->fgPixel, prog->fg_uniform); + glamor_set_color(dst, gc->bgPixel, prog->bg_uniform); + + /* XXX handle 2 10 10 10 and 1555 formats; presumably the pixmap private knows this? */ + switch (args->src_pixmap->drawable.depth) { + case 24: + glUniform4ui(prog->bitplane_uniform, + (args->bitplane >> 16) & 0xff, + (args->bitplane >> 8) & 0xff, + (args->bitplane ) & 0xff, + 0); + + glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0); + break; + case 32: + glUniform4ui(prog->bitplane_uniform, + (args->bitplane >> 16) & 0xff, + (args->bitplane >> 8) & 0xff, + (args->bitplane ) & 0xff, + (args->bitplane >> 24) & 0xff); + + glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0xff); + break; + case 16: + glUniform4ui(prog->bitplane_uniform, + (args->bitplane >> 11) & 0x1f, + (args->bitplane >> 5) & 0x3f, + (args->bitplane ) & 0x1f, + 0); + + glUniform4f(prog->bitmul_uniform, 0x1f, 0x3f, 0x1f, 0); + break; + case 15: + glUniform4ui(prog->bitplane_uniform, + (args->bitplane >> 10) & 0x1f, + (args->bitplane >> 5) & 0x1f, + (args->bitplane ) & 0x1f, + 0); + + glUniform4f(prog->bitmul_uniform, 0x1f, 0x1f, 0x1f, 0); + break; + case 8: + glUniform4ui(prog->bitplane_uniform, + 0, 0, 0, args->bitplane); + glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff); + break; + case 1: + glUniform4ui(prog->bitplane_uniform, + 0, 0, 0, args->bitplane); + glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff); + break; + } + + return TRUE; +} + +static const glamor_facet glamor_facet_copyplane = { + "copy_plane", + .version = 130, + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy)) + " fill_pos = (fill_offset + primitive.xy) / fill_size;\n"), + .fs_exec = (" uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n" + " if ((bits & bitplane) != uvec4(0,0,0,0))\n" + " gl_FragColor = fg;\n" + " else\n" + " gl_FragColor = bg;\n"), + .locations = glamor_program_location_fill|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane, + .use = use_copyplane, +}; + +/* + * When all else fails, pull the bits out of the GPU and do the + * operation with fb + */ + +static void +glamor_copy_bail(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + if (bitplane) { + if (src->bitsPerPixel > 1) + fbCopyNto1(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + else + fbCopy1toN(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } else { + fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } + } + glamor_finish_access(dst); + glamor_finish_access(src); +} + +/** + * Implements CopyPlane and CopyArea from the GPU to the GPU by using + * the source as a texture and painting that into the destination. + * + * This requires that source and dest are different textures, or that + * (if the copy area doesn't overlap), GL_NV_texture_barrier is used + * to ensure that the caches are flushed at the right times. + */ +static Bool +glamor_copy_cpu_fbo(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + FbBits *src_bits; + FbStride src_stride; + int src_bpp; + int src_xoff, src_yoff; + int dst_xoff, dst_yoff; + + if (gc && gc->alu != GXcopy) + goto bail; + + if (gc && !glamor_pm_is_solid(dst, gc->planemask)) + goto bail; + + glamor_make_current(glamor_priv); + glamor_prepare_access(src, GLAMOR_ACCESS_RO); + + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff); + + fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff); + + glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy, + dst_xoff, dst_yoff, + (uint8_t *) src_bits, src_stride * sizeof (FbBits)); + glamor_finish_access(src); + + return TRUE; + +bail: + return FALSE; +} + +/* + * Copy from GPU to GPU by using the source + * as a texture and painting that into the destination + */ + +static Bool +glamor_copy_fbo_fbo_draw(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); + glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap); + int src_box_x, src_box_y, dst_box_x, dst_box_y; + int dst_off_x, dst_off_y; + int src_off_x, src_off_y; + GLshort *v; + char *vbo_offset; + struct copy_args args; + glamor_program *prog; + const glamor_facet *copy_facet; + Bool set_scissor; + int n; + + glamor_make_current(glamor_priv); + + if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask)) + goto bail_ctx; + + if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy)) + goto bail_ctx; + + if (bitplane) { + prog = &glamor_priv->copy_plane_prog; + copy_facet = &glamor_facet_copyplane; + } else { + prog = &glamor_priv->copy_area_prog; + copy_facet = &glamor_facet_copyarea; + } + + if (prog->failed) + goto bail_ctx; + + if (!prog->prog) { + if (!glamor_build_program(screen, prog, + copy_facet, NULL)) + goto bail_ctx; + } + + args.src_pixmap = src_pixmap; + args.bitplane = bitplane; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(dst->pScreen, nbox * 8 * sizeof (int16_t), &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, + 2 * sizeof (GLshort), vbo_offset); + + for (n = 0; n < nbox; n++) { + v[0] = box->x1; v[1] = box->y1; + v[2] = box->x1; v[3] = box->y2; + v[4] = box->x2; v[5] = box->y2; + v[6] = box->x2; v[7] = box->y1; + v += 8; + box++; + } + + glamor_put_vbo_space(screen); + + glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y); + + set_scissor = src_priv->type == GLAMOR_TEXTURE_LARGE; + if (set_scissor) + glEnable(GL_SCISSOR_TEST); + + glamor_pixmap_loop(src_priv, src_box_x, src_box_y) { + BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y); + + args.dx = dx + src_off_x - src_box->x1; + args.dy = dy + src_off_y - src_box->y1; + args.src = glamor_pixmap_fbo_at(src_priv, src_box_x, src_box_y); + + if (!glamor_use_program(dst_pixmap, gc, prog, &args)) + goto bail_ctx; + + glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) { + glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE, + prog->matrix_uniform, &dst_off_x, &dst_off_y); + + if (set_scissor) + glScissor(dst_off_x - args.dx, + dst_off_y - args.dy, + src_box->x2 - src_box->x1, + src_box->y2 - src_box->y1); + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + glDrawArrays(GL_QUADS, 0, nbox * 4); + else { + int i; + for (i = 0; i < nbox; i++) + glDrawArrays(GL_TRIANGLE_FAN, i*4, 4); + } + } + } + if (set_scissor) + glDisable(GL_SCISSOR_TEST); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + glDisable(GL_COLOR_LOGIC_OP); + return TRUE; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); + return FALSE; +} + +/** + * Copies from the GPU to the GPU using a temporary pixmap in between, + * to correctly handle overlapping copies. + */ + +static Bool +glamor_copy_fbo_fbo_temp(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + PixmapPtr tmp_pixmap; + BoxRec bounds; + int n; + BoxPtr tmp_box; + + if (nbox == 0) + return TRUE; + + /* Sanity check state to avoid getting halfway through and bailing + * at the last second. Might be nice to have checks that didn't + * involve setting state. + */ + glamor_make_current(glamor_priv); + + if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask)) + goto bail_ctx; + + if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy)) + goto bail_ctx; + glDisable(GL_COLOR_LOGIC_OP); + + /* Find the size of the area to copy + */ + bounds = box[0]; + for (n = 1; n < nbox; n++) { + bounds.x1 = min(bounds.x1, box[n].x1); + bounds.x2 = max(bounds.x2, box[n].x2); + bounds.y1 = min(bounds.y1, box[n].y1); + bounds.y2 = max(bounds.y2, box[n].y2); + } + + /* Allocate a suitable temporary pixmap + */ + tmp_pixmap = glamor_create_pixmap(screen, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1, + src->depth, 0); + if (!tmp_pixmap) + goto bail; + + tmp_box = calloc(nbox, sizeof (BoxRec)); + if (!tmp_box) + goto bail_pixmap; + + /* Convert destination boxes into tmp pixmap boxes + */ + for (n = 0; n < nbox; n++) { + tmp_box[n].x1 = box[n].x1 - bounds.x1; + tmp_box[n].x2 = box[n].x2 - bounds.x1; + tmp_box[n].y1 = box[n].y1 - bounds.y1; + tmp_box[n].y2 = box[n].y2 - bounds.y1; + } + + if (!glamor_copy_fbo_fbo_draw(src, + &tmp_pixmap->drawable, + NULL, + tmp_box, + nbox, + dx + bounds.x1, + dy + bounds.y1, + FALSE, FALSE, + 0, NULL)) + goto bail_box; + + if (!glamor_copy_fbo_fbo_draw(&tmp_pixmap->drawable, + dst, + gc, + box, + nbox, + -bounds.x1, + -bounds.y1, + FALSE, FALSE, + bitplane, closure)) + goto bail_box; + + free(tmp_box); + + glamor_destroy_pixmap(tmp_pixmap); + + return TRUE; +bail_box: + free(tmp_box); +bail_pixmap: + glamor_destroy_pixmap(tmp_pixmap); +bail: + return FALSE; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); + return FALSE; +} + +/** + * Returns TRUE if the copy has to be implemented with + * glamor_copy_fbo_fbo_temp() instead of glamor_copy_fbo_fbo(). + * + * If the src and dst are in the same pixmap, then glamor_copy_fbo_fbo()'s + * sampling would give undefined results (since the same texture would be + * bound as an FBO destination and as a texture source). However, if we + * have GL_NV_texture_barrier, we can take advantage of the exception it + * added: + * + * "- If a texel has been written, then in order to safely read the result + * a texel fetch must be in a subsequent Draw separated by the command + * + * void TextureBarrierNV(void); + * + * TextureBarrierNV() will guarantee that writes have completed and caches + * have been invalidated before subsequent Draws are executed." + */ +static Bool +glamor_copy_needs_temp(DrawablePtr src, + DrawablePtr dst, + BoxPtr box, + int nbox, + int dx, + int dy) +{ + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + int n; + int dst_off_x, dst_off_y; + int src_off_x, src_off_y; + BoxRec bounds; + + if (src_pixmap != dst_pixmap) + return FALSE; + + if (nbox == 0) + return FALSE; + + if (!glamor_priv->has_nv_texture_barrier) + return TRUE; + + glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y); + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y); + + bounds = box[0]; + for (n = 1; n < nbox; n++) { + bounds.x1 = min(bounds.x1, box[n].x1); + bounds.y1 = min(bounds.y1, box[n].y1); + + bounds.x2 = max(bounds.x2, box[n].x2); + bounds.y2 = max(bounds.y2, box[n].y2); + } + + /* Check to see if the pixmap-relative boxes overlap in both X and Y, + * in which case we can't rely on NV_texture_barrier and must + * make a temporary copy + * + * dst.x1 < src.x2 && + * src.x1 < dst.x2 && + * + * dst.y1 < src.y2 && + * src.y1 < dst.y2 + */ + if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x && + bounds.x1 + dx + src_off_x < bounds.x2 + dst_off_x && + + bounds.y1 + dst_off_y < bounds.y2 + dy + src_off_y && + bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) { + return TRUE; + } + + glTextureBarrierNV(); + + return FALSE; +} + +static Bool +glamor_copy_gl(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); + glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap); + + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_priv)) { + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv)) { + if (glamor_copy_needs_temp(src, dst, box, nbox, dx, dy)) + return glamor_copy_fbo_fbo_temp(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + else + return glamor_copy_fbo_fbo_draw(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } + if (bitplane == 0) + return glamor_copy_cpu_fbo(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } + return FALSE; +} + +void +glamor_copy(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure)) + return; + glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); +} + +RegionPtr +glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty) +{ + return miDoCopy(src, dst, gc, + srcx, srcy, width, height, + dstx, dsty, glamor_copy, 0, NULL); +} + +RegionPtr +glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty, + unsigned long bitplane) +{ + if ((bitplane & FbFullMask(src->depth)) == 0) + return miHandleExposures(src, dst, gc, + srcx, srcy, width, height, dstx, dsty, + bitplane); + return miDoCopy(src, dst, gc, + srcx, srcy, width, height, + dstx, dsty, glamor_copy, bitplane, NULL); +} + +void +glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(&window->drawable); + DrawablePtr drawable = &pixmap->drawable; + RegionRec dst_region; + int dx, dy; + + dx = old_origin.x - window->drawable.x; + dy = old_origin.y - window->drawable.y; + RegionTranslate(src_region, -dx, -dy); + + RegionNull(&dst_region); + + RegionIntersect(&dst_region, &window->borderClip, src_region); + +#ifdef COMPOSITE + if (pixmap->screen_x || pixmap->screen_y) + RegionTranslate(&dst_region, -pixmap->screen_x, -pixmap->screen_y); +#endif + + miCopyRegion(drawable, drawable, + 0, &dst_region, dx, dy, glamor_copy, 0, 0); + + RegionUninit(&dst_region); +} + +Bool +glamor_copy_n_to_n_nf(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, Pixel bitplane, + void *closure) +{ + if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure)) + return TRUE; + if (glamor_ddx_fallback_check_pixmap(src) && glamor_ddx_fallback_check_pixmap(dst)) + return FALSE; + glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); + return TRUE; +} + +Bool +glamor_copy_plane_nf(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int w, int h, int dstx, int dsty, + unsigned long bitplane, RegionPtr *region) +{ + if (glamor_ddx_fallback_check_pixmap(src) && + glamor_ddx_fallback_check_pixmap(dst) && + glamor_ddx_fallback_check_gc(gc)) + return FALSE; + + *region = glamor_copy_plane(src, dst, gc, + srcx, srcy, w, h, dstx, dsty, + bitplane); + return TRUE; +} diff --git a/xorg-server/glamor/glamor_copyarea.c b/xorg-server/glamor/glamor_copyarea.c deleted file mode 100644 index e1988225f..000000000 --- a/xorg-server/glamor/glamor_copyarea.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * Copyright © 1998 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - * - * Authors: - * Eric Anholt - * Zhigang Gong - */ - -#include "glamor_priv.h" - -/** @file glamor_copyarea.c - * - * GC CopyArea implementation - */ -static Bool -glamor_copy_n_to_n_fbo_blit(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, BoxPtr box, int nbox, int dx, int dy) -{ - ScreenPtr screen = dst->pScreen; - PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); - PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); - glamor_pixmap_private *src_pixmap_priv, *dst_pixmap_priv; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - int dst_x_off, dst_y_off, src_x_off, src_y_off, i; - int fbo_x_off, fbo_y_off; - int src_fbo_x_off, src_fbo_y_off; - - if (!glamor_priv->has_fbo_blit) { - glamor_delayed_fallback(screen, "no EXT_framebuffer_blit\n"); - return FALSE; - } - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - - if (gc) { - if (gc->alu != GXcopy) { - glamor_delayed_fallback(screen, "non-copy ALU\n"); - return FALSE; - } - } - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { - glamor_delayed_fallback(screen, "no src fbo\n"); - return FALSE; - } - - if (glamor_set_destination_pixmap(dst_pixmap)) - return FALSE; - - pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off); - pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off); - - glamor_make_current(glamor_priv); - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->base.fbo->fb); - glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); - glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); - dst_x_off += fbo_x_off; - dst_y_off += fbo_y_off; - src_y_off += dy + src_fbo_y_off; - src_x_off += src_fbo_x_off; - - for (i = 0; i < nbox; i++) { - if (glamor_priv->yInverted) { - glBlitFramebuffer(box[i].x1 + dx + src_x_off, - box[i].y1 + src_y_off, - box[i].x2 + dx + src_x_off, - box[i].y2 + src_y_off, - box[i].x1 + dst_x_off, - box[i].y1 + dst_y_off, - box[i].x2 + dst_x_off, - box[i].y2 + dst_y_off, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - else { - int flip_dst_y1 = - dst_pixmap->drawable.height - (box[i].y2 + dst_y_off); - int flip_dst_y2 = - dst_pixmap->drawable.height - (box[i].y1 + dst_y_off); - int flip_src_y1 = - src_pixmap->drawable.height - (box[i].y2 + src_y_off); - int flip_src_y2 = - src_pixmap->drawable.height - (box[i].y1 + src_y_off); - - glBlitFramebuffer(box[i].x1 + dx + src_x_off, - flip_src_y1, - box[i].x2 + dx + src_x_off, - flip_src_y2, - box[i].x1 + dst_x_off, - flip_dst_y1, - box[i].x2 + dst_x_off, - flip_dst_y2, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - } - glamor_priv->state = BLIT_STATE; - return TRUE; -} - -static Bool -glamor_copy_n_to_n_textured(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, BoxPtr box, int nbox, int dx, int dy) -{ - glamor_screen_private *glamor_priv = - glamor_get_screen_private(dst->pScreen); - PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); - PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); - int i; - float vertices[8], texcoords[8]; - glamor_pixmap_private *src_pixmap_priv; - glamor_pixmap_private *dst_pixmap_priv; - int src_x_off, src_y_off, dst_x_off, dst_y_off; - enum glamor_pixmap_status src_status = GLAMOR_NONE; - GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; - - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - - if (src_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) { -#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD - glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); - return FALSE; -#else - src_status = glamor_upload_pixmap_to_texture(src_pixmap); - if (src_status != GLAMOR_UPLOAD_DONE) - return FALSE; - - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); -#endif - } - - pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); - pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); - - glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); - - glamor_make_current(glamor_priv); - - glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - - glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); - dx += src_x_off; - dy += src_y_off; - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, - 2 * sizeof(float), texcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(glamor_priv->finish_access_prog[0]); - glUniform1i(glamor_priv->finish_access_revert[0], REVERT_NONE); - glUniform1i(glamor_priv->finish_access_swap_rb[0], SWAP_NONE_UPLOADING); - - for (i = 0; i < nbox; i++) { - - glamor_set_normalize_vcoords(dst_pixmap_priv, - dst_xscale, dst_yscale, - box[i].x1 + dst_x_off, - box[i].y1 + dst_y_off, - box[i].x2 + dst_x_off, - box[i].y2 + dst_y_off, - glamor_priv->yInverted, vertices); - - glamor_set_normalize_tcoords(src_pixmap_priv, - src_xscale, - src_yscale, - box[i].x1 + dx, - box[i].y1 + dy, - box[i].x2 + dx, - box[i].y2 + dy, - glamor_priv->yInverted, texcoords); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - /* The source texture is bound to a fbo, we have to flush it here. */ - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - return TRUE; -} - -static Bool -__glamor_copy_n_to_n(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, - BoxPtr box, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure) -{ - PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL; - DrawablePtr temp_src = src; - glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; - glamor_screen_private *glamor_priv; - BoxRec bound; - ScreenPtr screen; - int temp_dx = dx; - int temp_dy = dy; - int src_x_off, src_y_off, dst_x_off, dst_y_off; - int i; - int overlaped = 0; - Bool ret = FALSE; - - dst_pixmap = glamor_get_drawable_pixmap(dst); - dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - src_pixmap = glamor_get_drawable_pixmap(src); - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - screen = dst_pixmap->drawable.pScreen; - glamor_priv = glamor_get_screen_private(dst->pScreen); - glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); - - glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); - - if (src_pixmap_priv->base.fbo - && src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) { - int x_shift = abs(src_x_off - dx - dst_x_off); - int y_shift = abs(src_y_off - dy - dst_y_off); - - for (i = 0; i < nbox; i++) { - if (x_shift < abs(box[i].x2 - box[i].x1) - && y_shift < abs(box[i].y2 - box[i].y1)) { - overlaped = 1; - break; - } - } - } - DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n", - box[0].x1, box[0].y1, - box[0].x2 - box[0].x1, box[0].y2 - box[0].y1, - dx, dy, src_pixmap, dst_pixmap); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && - !overlaped && - (glamor_priv->state != RENDER_STATE - || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex) - && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { - ret = TRUE; - goto done; - } - glamor_calculate_boxes_bound(&bound, box, nbox); - - /* Overlaped indicate the src and dst are the same pixmap. */ - if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) - && (((bound.x2 - bound.x1) * (bound.y2 - bound.y1) - * 4 > - src_pixmap->drawable.width * - src_pixmap->drawable.height) - || !(glamor_check_fbo_size(glamor_priv, - src_pixmap->drawable.width, - src_pixmap->drawable. - height))))) { - - temp_pixmap = glamor_create_pixmap(screen, - bound.x2 - bound.x1, - bound.y2 - bound.y1, - src_pixmap->drawable.depth, - overlaped ? 0 : - GLAMOR_CREATE_PIXMAP_CPU); - assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size); - assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size); - if (!temp_pixmap) - goto done; - glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1); - temp_src = &temp_pixmap->drawable; - - if (overlaped) - glamor_copy_n_to_n_textured(src, temp_src, gc, box, - nbox, - temp_dx + bound.x1, temp_dy + bound.y1); - else - fbCopyNtoN(src, temp_src, gc, box, nbox, - temp_dx + bound.x1, temp_dy + bound.y1, - reverse, upsidedown, bitplane, closure); - glamor_translate_boxes(box, nbox, bound.x1, bound.y1); - temp_dx = -bound.x1; - temp_dy = -bound.y1; - } - else { - temp_dx = dx; - temp_dy = dy; - temp_src = src; - } - - if (glamor_copy_n_to_n_textured - (temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) { - ret = TRUE; - } - done: - if (temp_src != src) - glamor_destroy_pixmap(temp_pixmap); - return ret; -} - -static Bool -_glamor_copy_n_to_n(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, - BoxPtr box, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, Pixel bitplane, - void *closure, Bool fallback) -{ - ScreenPtr screen = dst->pScreen; - PixmapPtr dst_pixmap, src_pixmap; - glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; - glamor_screen_private *glamor_priv; - BoxPtr extent; - RegionRec region; - int src_x_off, src_y_off, dst_x_off, dst_y_off; - Bool ok = FALSE; - int force_clip = 0; - - if (nbox == 0) - return TRUE; - dst_pixmap = glamor_get_drawable_pixmap(dst); - dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - src_pixmap = glamor_get_drawable_pixmap(src); - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - - glamor_priv = glamor_get_screen_private(screen); - - DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n", - box[0].x1, box[0].y1, - box[0].x2 - box[0].x1, box[0].y2 - box[0].y1, - dx, dy, src_pixmap, dst_pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) - goto fall_back; - - if (gc) { - if (!glamor_set_planemask(dst_pixmap, gc->planemask)) - goto fall_back; - glamor_make_current(glamor_priv); - if (!glamor_set_alu(screen, gc->alu)) { - goto fail_noregion; - } - } - - if (!src_pixmap_priv) { - glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY); - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - } - - glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); - glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); - - RegionInitBoxes(®ion, box, nbox); - extent = RegionExtents(®ion); - - if (!glamor_check_fbo_size(glamor_priv, - extent->x2 - extent->x1, extent->y2 - extent->y1) - && (src_pixmap_priv->type == GLAMOR_MEMORY - || (src_pixmap_priv == dst_pixmap_priv))) { - force_clip = 1; - } - - if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE - || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - glamor_pixmap_clipped_regions *clipped_dst_regions; - int n_dst_region, i, j; - PixmapPtr temp_source_pixmap; - glamor_pixmap_private *temp_source_priv = NULL; - - RegionTranslate(®ion, dst_x_off, dst_y_off); - if (!force_clip) - clipped_dst_regions = - glamor_compute_clipped_regions(dst_pixmap_priv, ®ion, - &n_dst_region, 0, reverse, - upsidedown); - else - clipped_dst_regions = - glamor_compute_clipped_regions_ext(dst_pixmap_priv, ®ion, - &n_dst_region, - glamor_priv->max_fbo_size, - glamor_priv->max_fbo_size, - reverse, upsidedown); - for (i = 0; i < n_dst_region; i++) { - int n_src_region; - glamor_pixmap_clipped_regions *clipped_src_regions; - BoxPtr current_boxes; - int n_current_boxes; - - SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, - clipped_dst_regions[i].block_idx); - - temp_source_pixmap = NULL; - if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - RegionTranslate(clipped_dst_regions[i].region, - -dst_x_off + src_x_off + dx, - -dst_y_off + src_y_off + dy); - clipped_src_regions = - glamor_compute_clipped_regions(src_pixmap_priv, - clipped_dst_regions[i]. - region, &n_src_region, 0, - reverse, upsidedown); - DEBUGF("Source is large pixmap.\n"); - for (j = 0; j < n_src_region; j++) { - if (src_pixmap_priv != dst_pixmap_priv) - SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, - clipped_src_regions[j]. - block_idx); - else if (src_pixmap_priv == dst_pixmap_priv && - clipped_src_regions[j].block_idx != - clipped_dst_regions[i].block_idx) { - /* source and the dest are the same, but need different block_idx. - * we create a empty pixmap and fill the required source fbo and box to - * it. It's a little hacky, but avoid extra copy. */ - temp_source_pixmap = - glamor_create_pixmap(src->pScreen, 0, 0, src->depth, - 0); - if (!temp_source_pixmap) { - ok = FALSE; - goto fail; - } - src->pScreen->ModifyPixmapHeader(temp_source_pixmap, - src_pixmap->drawable. - width, - src_pixmap->drawable. - height, 0, 0, - src_pixmap->devKind, - NULL); - temp_source_priv = - glamor_get_pixmap_private(temp_source_pixmap); - *temp_source_priv = *src_pixmap_priv; - temp_source_priv->large.box = - src_pixmap_priv->large. - box_array[clipped_src_regions[j].block_idx]; - temp_source_priv->base.fbo = - src_pixmap_priv->large. - fbo_array[clipped_src_regions[j].block_idx]; - temp_source_priv->base.pixmap = temp_source_pixmap; - } - assert(temp_source_pixmap || - !(src_pixmap_priv == dst_pixmap_priv && - (clipped_src_regions[j].block_idx != - clipped_dst_regions[i].block_idx))); - - RegionTranslate(clipped_src_regions[j].region, - -src_x_off - dx, -src_y_off - dy); - current_boxes = RegionRects(clipped_src_regions[j].region); - n_current_boxes = - RegionNumRects(clipped_src_regions[j].region); - DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n", - clipped_dst_regions[i].block_idx, - clipped_src_regions[j].block_idx); - DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n", - current_boxes[0].x1, current_boxes[0].y1, - current_boxes[0].x2, current_boxes[0].y2, dx, dy, - src_pixmap, dst_pixmap); - if (!temp_source_pixmap) - ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes, - n_current_boxes, dx, dy, - reverse, upsidedown, bitplane, - closure); - else { - ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable, - dst, gc, current_boxes, - n_current_boxes, dx, dy, - reverse, upsidedown, bitplane, - closure); - temp_source_priv->type = GLAMOR_MEMORY; - temp_source_priv->base.fbo = NULL; - glamor_destroy_pixmap(temp_source_pixmap); - temp_source_pixmap = NULL; - } - - RegionDestroy(clipped_src_regions[j].region); - if (!ok) { - assert(0); - goto fail; - } - } - - if (n_src_region == 0) - ok = TRUE; - free(clipped_src_regions); - } - else { - RegionTranslate(clipped_dst_regions[i].region, - -dst_x_off, -dst_y_off); - current_boxes = RegionRects(clipped_dst_regions[i].region); - n_current_boxes = RegionNumRects(clipped_dst_regions[i].region); - - DEBUGF("dest pixmap fbo idx %d \n", - clipped_dst_regions[i].block_idx); - DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n", - current_boxes[0].x1, current_boxes[0].y1, - current_boxes[0].x2, current_boxes[0].y2, - dx, dy, src_pixmap, dst_pixmap); - - ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes, - n_current_boxes, dx, dy, reverse, - upsidedown, bitplane, closure); - - } - RegionDestroy(clipped_dst_regions[i].region); - } - if (n_dst_region == 0) - ok = TRUE; - free(clipped_dst_regions); - } - else { - ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy, - reverse, upsidedown, bitplane, closure); - } - - fail: - RegionUninit(®ion); - fail_noregion: - glamor_make_current(glamor_priv); - glamor_set_alu(screen, GXcopy); - - if (ok) - return TRUE; - fall_back: - if (!fallback && glamor_ddx_fallback_check_pixmap(src) - && glamor_ddx_fallback_check_pixmap(dst)) - goto done; - - if (src_pixmap_priv->type == GLAMOR_DRM_ONLY - || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) { - LogMessage(X_WARNING, - "Access a DRM only pixmap is not allowed within glamor.\n"); - return TRUE; - } - glamor_report_delayed_fallbacks(src->pScreen); - glamor_report_delayed_fallbacks(dst->pScreen); - - glamor_fallback("from %p to %p (%c,%c)\n", src, dst, - glamor_get_drawable_location(src), - glamor_get_drawable_location(dst)); - - if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && - glamor_prepare_access(src, GLAMOR_ACCESS_RO) && - glamor_prepare_access_gc(gc)) { - fbCopyNtoN(src, dst, gc, box, nbox, - dx, dy, reverse, upsidedown, bitplane, closure); - } - glamor_finish_access_gc(gc); - glamor_finish_access(src); - glamor_finish_access(dst); - ok = TRUE; - - done: - glamor_clear_delayed_fallbacks(src->pScreen); - glamor_clear_delayed_fallbacks(dst->pScreen); - return ok; -} - -RegionPtr -glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, - int srcx, int srcy, int width, int height, int dstx, int dsty) -{ - RegionPtr region; - - region = miDoCopy(src, dst, gc, - srcx, srcy, width, height, - dstx, dsty, glamor_copy_n_to_n, 0, NULL); - - return region; -} - -void -glamor_copy_n_to_n(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, - BoxPtr box, - int nbox, - int dx, - int dy, - Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) -{ - _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, - dy, reverse, upsidedown, bitplane, closure, TRUE); -} - -Bool -glamor_copy_n_to_n_nf(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, - BoxPtr box, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure) -{ - return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, - dy, reverse, upsidedown, bitplane, closure, - FALSE); -} diff --git a/xorg-server/glamor/glamor_copyplane.c b/xorg-server/glamor/glamor_copyplane.c deleted file mode 100644 index 2bd2de30d..000000000 --- a/xorg-server/glamor/glamor_copyplane.c +++ /dev/null @@ -1,75 +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 - * - */ - -#include "glamor_priv.h" - -static Bool -_glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane, RegionPtr *pRegion, Bool fallback) -{ - if (!fallback && glamor_ddx_fallback_check_gc(pGC) - && glamor_ddx_fallback_check_pixmap(pSrc) - && glamor_ddx_fallback_check_pixmap(pDst)) - goto fail; - - if (glamor_prepare_access(pDst, GLAMOR_ACCESS_RW) && - glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO) && - glamor_prepare_access_gc(pGC)) { - *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, bitPlane); - } - glamor_finish_access_gc(pGC); - glamor_finish_access(pSrc); - glamor_finish_access(pDst); - return TRUE; - - fail: - return FALSE; -} - -RegionPtr -glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane) -{ - RegionPtr ret; - - _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, bitPlane, &ret, TRUE); - return ret; -} - -Bool -glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane, RegionPtr *pRegion) -{ - return _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, bitPlane, pRegion, FALSE); -} diff --git a/xorg-server/glamor/glamor_copywindow.c b/xorg-server/glamor/glamor_copywindow.c deleted file mode 100644 index 1ced4b336..000000000 --- a/xorg-server/glamor/glamor_copywindow.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * Copyright © 1998 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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" - -/** @file glamor_copywindow.c - * - * Screen CopyWindow implementation. - */ - -void -glamor_copy_window(WindowPtr win, DDXPointRec old_origin, RegionPtr src_region) -{ - RegionRec dst_region; - int dx, dy; - PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win); - - dx = old_origin.x - win->drawable.x; - dy = old_origin.y - win->drawable.y; - REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy); - - REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0); - - REGION_INTERSECT(win->drawable.pScreen, &dst_region, - &win->borderClip, src_region); -#ifdef COMPOSITE - if (pixmap->screen_x || pixmap->screen_y) - REGION_TRANSLATE(win->drawable.pScreen, &dst_region, - -pixmap->screen_x, -pixmap->screen_y); -#endif - - miCopyRegion(&pixmap->drawable, &pixmap->drawable, - NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL); - - REGION_UNINIT(win->drawable.pScreen, &dst_region); -} diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c index b34943761..737b2744b 100644 --- a/xorg-server/glamor/glamor_core.c +++ b/xorg-server/glamor/glamor_core.c @@ -114,27 +114,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) } } -Bool -glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) -{ - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (pixmap->devPrivate.ptr) { - /* Already mapped, nothing needs to be done. Note that we - * aren't allowing promotion from RO to RW, because it would - * require re-mapping the PBO. - */ - assert(!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) || - access == GLAMOR_ACCESS_RO || - pixmap_priv->base.map_access == GLAMOR_ACCESS_RW); - return TRUE; - } - pixmap_priv->base.map_access = access; - - return glamor_download_pixmap_to_cpu(pixmap, access); -} - /* * When downloading a unsupported color format to CPU memory, we need to shuffle the color elements and then use a supported @@ -313,102 +292,6 @@ glamor_fini_finish_access_shaders(ScreenPtr screen) glDeleteProgram(glamor_priv->finish_access_prog[1]); } -void -glamor_finish_access(DrawablePtr drawable) -{ - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - glamor_screen_private *glamor_priv = - glamor_get_screen_private(drawable->pScreen); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)) - return; - - /* If we are doing a series of unmaps from a nested map, we're - * done. None of the callers do any rendering to maps after - * starting an unmap sequence, so we don't need to delay until the - * last nested unmap. - */ - if (!pixmap->devPrivate.ptr) - return; - - if (pixmap_priv->base.map_access == GLAMOR_ACCESS_RW) { - glamor_restore_pixmap_to_texture(pixmap); - } - - if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) { - assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - - glamor_make_current(glamor_priv); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo); - - pixmap_priv->base.fbo->pbo_valid = FALSE; - pixmap_priv->base.fbo->pbo = 0; - } - else { - free(pixmap->devPrivate.ptr); - } - - if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) - pixmap->devKind = pixmap_priv->base.drm_stride; - - if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED) - pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL; - - pixmap->devPrivate.ptr = NULL; -} - -/** - * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the - * current fill style. - * - * Solid doesn't use an extra pixmap source, so we don't worry about them. - * Stippled/OpaqueStippled are 1bpp and can be in fb, so we should worry - * about them. - */ -Bool -glamor_prepare_access_gc(GCPtr gc) -{ - if (gc->stipple) { - if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO)) - return FALSE; - } - if (gc->fillStyle == FillTiled) { - if (!glamor_prepare_access(&gc->tile.pixmap->drawable, - GLAMOR_ACCESS_RO)) { - if (gc->stipple) - glamor_finish_access(&gc->stipple->drawable); - return FALSE; - } - } - return TRUE; -} - -/** - * Finishes access to the tile in the GC, if used. - */ -void -glamor_finish_access_gc(GCPtr gc) -{ - if (gc->fillStyle == FillTiled) - glamor_finish_access(&gc->tile.pixmap->drawable); - if (gc->stipple) - glamor_finish_access(&gc->stipple->drawable); -} - -Bool -glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, - int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - unsigned long fg_pixel, unsigned long bg_pixel, - int stipple_x, int stipple_y) -{ - glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth); - return FALSE; -} - GCOps glamor_gc_ops = { .FillSpans = glamor_fill_spans, .SetSpans = glamor_set_spans, @@ -432,6 +315,58 @@ GCOps glamor_gc_ops = { .PushPixels = glamor_push_pixels, }; +/* + * When the stipple is changed or drawn to, invalidate any + * cached copy + */ +static void +glamor_invalidate_stipple(GCPtr gc) +{ + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + if (gc_priv->stipple) { + if (gc_priv->stipple_damage) + DamageUnregister(gc_priv->stipple_damage); + glamor_destroy_pixmap(gc_priv->stipple); + gc_priv->stipple = NULL; + } +} + +static void +glamor_stipple_damage_report(DamagePtr damage, RegionPtr region, + void *closure) +{ + GCPtr gc = closure; + + glamor_invalidate_stipple(gc); +} + +static void +glamor_stipple_damage_destroy(DamagePtr damage, void *closure) +{ + GCPtr gc = closure; + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + gc_priv->stipple_damage = NULL; + glamor_invalidate_stipple(gc); +} + +void +glamor_track_stipple(GCPtr gc) +{ + if (gc->stipple) { + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + if (!gc_priv->stipple_damage) + gc_priv->stipple_damage = DamageCreate(glamor_stipple_damage_report, + glamor_stipple_damage_destroy, + DamageReportNonEmpty, + TRUE, gc->pScreen, gc); + if (gc_priv->stipple_damage) + DamageRegister(&gc->stipple->drawable, gc_priv->stipple_damage); + } +} + /** * uxa_validate_gc() sets the ops to glamor's implementations, which may be * accelerated or may sync the card and fall back to fb. @@ -502,6 +437,9 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) changes &= ~GCTile; } + if (changes & GCStipple) + glamor_invalidate_stipple(gc); + if (changes & GCStipple && gc->stipple) { /* We can't inline stipple handling like we do for GCTile because * it sets fbgc privates. @@ -515,14 +453,38 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) fbValidateGC(gc, changes, drawable); } + if (changes & GCDashList) { + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + if (gc_priv->dash) { + glamor_destroy_pixmap(gc_priv->dash); + gc_priv->dash = NULL; + } + } + gc->ops = &glamor_gc_ops; } +void +glamor_destroy_gc(GCPtr gc) +{ + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + if (gc_priv->dash) { + glamor_destroy_pixmap(gc_priv->dash); + gc_priv->dash = NULL; + } + glamor_invalidate_stipple(gc); + if (gc_priv->stipple_damage) + DamageDestroy(gc_priv->stipple_damage); + miDestroyGC(gc); +} + static GCFuncs glamor_gc_funcs = { glamor_validate_gc, miChangeGC, miCopyGC, - miDestroyGC, + glamor_destroy_gc, miChangeClip, miDestroyClip, miCopyClip @@ -535,6 +497,10 @@ static GCFuncs glamor_gc_funcs = { int glamor_create_gc(GCPtr gc) { + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + gc_priv->dash = NULL; + gc_priv->stipple = NULL; if (!fbCreateGC(gc)) return FALSE; diff --git a/xorg-server/glamor/glamor_dash.c b/xorg-server/glamor/glamor_dash.c new file mode 100644 index 000000000..e8f60fa10 --- /dev/null +++ b/xorg-server/glamor/glamor_dash.c @@ -0,0 +1,370 @@ +/* + * 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_program.h" +#include "glamor_transform.h" +#include "glamor_transfer.h" +#include "glamor_prepare.h" + +static const char dash_vs_vars[] = + "attribute vec3 primitive;\n" + "varying float dash_offset;\n"; + +static const char dash_vs_exec[] = + " dash_offset = primitive.z / dash_length;\n" + GLAMOR_POS(gl_Position, primitive.xy); + +static const char dash_fs_vars[] = + "varying float dash_offset;\n"; + +static const char on_off_fs_exec[] = + " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n" + " if (pattern == 0.0)\n" + " discard;\n"; + +/* XXX deal with stippled double dashed lines once we have stippling support */ +static const char double_fs_exec[] = + " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n" + " if (pattern == 0.0)\n" + " gl_FragColor = bg;\n" + " else\n" + " gl_FragColor = fg;\n"; + + +static const glamor_facet glamor_facet_on_off_dash_lines = { + .version = 130, + .name = "poly_lines_on_off_dash", + .vs_vars = dash_vs_vars, + .vs_exec = dash_vs_exec, + .fs_vars = dash_fs_vars, + .fs_exec = on_off_fs_exec, + .locations = glamor_program_location_dash, +}; + +static const glamor_facet glamor_facet_double_dash_lines = { + .version = 130, + .name = "poly_lines_double_dash", + .vs_vars = dash_vs_vars, + .vs_exec = dash_vs_exec, + .fs_vars = dash_fs_vars, + .fs_exec = double_fs_exec, + .locations = (glamor_program_location_dash| + glamor_program_location_fg| + glamor_program_location_bg), +}; + +static PixmapPtr +glamor_get_dash_pixmap(GCPtr gc) +{ + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + ScreenPtr screen = gc->pScreen; + PixmapPtr pixmap; + int offset; + int d; + uint32_t pixel; + GCPtr scratch_gc; + + if (gc_priv->dash) + return gc_priv->dash; + + offset = 0; + for (d = 0; d < gc->numInDashList; d++) + offset += gc->dash[d]; + + pixmap = glamor_create_pixmap(screen, offset, 1, 8, 0); + if (!pixmap) + goto bail; + + scratch_gc = GetScratchGC(8, screen); + if (!scratch_gc) + goto bail_pixmap; + + pixel = 0xffffffff; + offset = 0; + for (d = 0; d < gc->numInDashList; d++) { + xRectangle rect; + ChangeGCVal changes; + + changes.val = pixel; + (void) ChangeGC(NullClient, scratch_gc, + GCForeground, &changes); + ValidateGC(&pixmap->drawable, scratch_gc); + rect.x = offset; + rect.y = 0; + rect.width = gc->dash[d]; + rect.height = 1; + scratch_gc->ops->PolyFillRect (&pixmap->drawable, scratch_gc, 1, &rect); + offset += gc->dash[d]; + pixel = ~pixel; + } + FreeScratchGC(scratch_gc); + + gc_priv->dash = pixmap; + return pixmap; + +bail_pixmap: + glamor_destroy_pixmap(pixmap); +bail: + return NULL; +} + +static glamor_program * +glamor_dash_setup(DrawablePtr drawable, GCPtr gc) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + PixmapPtr dash_pixmap; + glamor_pixmap_private *dash_priv; + glamor_program *prog; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + if (gc->lineWidth != 0) + goto bail; + + dash_pixmap = glamor_get_dash_pixmap(gc); + dash_priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dash_priv)) + goto bail; + + glamor_make_current(glamor_priv); + + switch (gc->lineStyle) { + case LineOnOffDash: + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->on_off_dash_line_progs, + &glamor_facet_on_off_dash_lines); + if (!prog) + goto bail_ctx; + break; + case LineDoubleDash: + if (gc->fillStyle != FillSolid) + goto bail_ctx; + + prog = &glamor_priv->double_dash_line_prog; + + if (!prog->prog) { + if (!glamor_build_program(screen, prog, + &glamor_facet_double_dash_lines, + NULL)) + goto bail_ctx; + } + + if (!glamor_use_program(pixmap, gc, prog, NULL)) + goto bail_ctx; + + glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform); + glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform); + break; + + default: + goto bail_ctx; + } + + + /* Set the dash pattern as texture 1 */ + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, dash_priv->base.fbo->tex); + glUniform1i(prog->dash_uniform, 1); + glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width); + + return prog; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); +bail: + return NULL; +} + +static void +glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog, + int n, GLenum mode) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + int box_x, box_y; + int off_x, off_y; + + 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(mode, 0, n); + } + } + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); +} + +static int +glamor_line_length(short x1, short y1, short x2, short y2) +{ + return max(abs(x2 - x1), abs(y2 - y1)); +} + +Bool +glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + ScreenPtr screen = drawable->pScreen; + glamor_program *prog; + short *v; + char *vbo_offset; + int add_last; + int dash_pos; + int prev_x, prev_y; + int i; + + if (n < 2) + return TRUE; + + if (!(prog = glamor_dash_setup(drawable, gc))) + return FALSE; + + add_last = 0; + if (gc->capStyle != CapNotLast) + add_last = 1; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, + (n + add_last) * 3 * sizeof (short), + &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE, + 3 * sizeof (short), vbo_offset); + + dash_pos = gc->dashOffset; + prev_x = prev_y = 0; + for (i = 0; i < n; i++) { + int this_x = points[i].x; + int this_y = points[i].y; + if (i) { + if (mode == CoordModePrevious) { + this_x += prev_x; + this_y += prev_y; + } + dash_pos += glamor_line_length(prev_x, prev_y, + this_x, this_y); + } + v[0] = prev_x = this_x; + v[1] = prev_y = this_y; + v[2] = dash_pos; + v += 3; + } + + if (add_last) { + v[0] = prev_x + 1; + v[1] = prev_y; + v[2] = dash_pos + 1; + } + + glamor_put_vbo_space(screen); + + glamor_dash_loop(drawable, gc, prog, n + add_last, GL_LINE_STRIP); + + return TRUE; +} + +static short * +glamor_add_segment(short *v, short x1, short y1, short x2, short y2, + int dash_start, int dash_end) +{ + v[0] = x1; + v[1] = y1; + v[2] = dash_start; + + v[3] = x2; + v[4] = y2; + v[5] = dash_end; + return v + 6; +} + +Bool +glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + ScreenPtr screen = drawable->pScreen; + glamor_program *prog; + short *v; + char *vbo_offset; + int dash_start = gc->dashOffset; + int add_last; + int i; + + if (!(prog = glamor_dash_setup(drawable, gc))) + return FALSE; + + add_last = 0; + if (gc->capStyle != CapNotLast) + add_last = 1; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, + (nseg< - * Zhigang Gong - */ - -#include "glamor_priv.h" - -/** @file glamor_fill.c - * - * GC fill implementation, based loosely on fb_fill.c - */ - -/** - * Fills the given rectangle of a drawable with the GC's fill style. - */ -Bool -glamor_fill(DrawablePtr drawable, - GCPtr gc, int x, int y, int width, int height, Bool fallback) -{ - PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); - int off_x, off_y; - PixmapPtr sub_pixmap = NULL; - glamor_access_t sub_pixmap_access; - DrawablePtr saved_drawable = NULL; - int saved_x = x, saved_y = y; - - glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y); - - switch (gc->fillStyle) { - case FillSolid: - if (!glamor_solid(dst_pixmap, - x + off_x, - y + off_y, - width, height, gc->alu, gc->planemask, gc->fgPixel)) - goto fail; - break; - case FillStippled: - case FillOpaqueStippled: - if (!glamor_stipple(dst_pixmap, - gc->stipple, - x + off_x, - y + off_y, - width, - height, - gc->alu, - gc->planemask, - gc->fgPixel, - gc->bgPixel, gc->patOrg.x, gc->patOrg.y)) - goto fail; - break; - case FillTiled: - if (!glamor_tile(dst_pixmap, - gc->tile.pixmap, - x + off_x, - y + off_y, - width, - height, - gc->alu, - gc->planemask, - x - drawable->x - gc->patOrg.x, - y - drawable->y - gc->patOrg.y)) - goto fail; - break; - } - return TRUE; - - fail: - if (!fallback) { - if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable) - && glamor_ddx_fallback_check_gc(gc)) - return FALSE; - } - /* Is it possible to set the access as WO? */ - - sub_pixmap_access = GLAMOR_ACCESS_RW; - - sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x, - y + off_y, width, height, - sub_pixmap_access); - - if (sub_pixmap != NULL) { - if (gc->fillStyle != FillSolid) { - gc->patOrg.x += (drawable->x - x); - gc->patOrg.y += (drawable->y - y); - } - saved_drawable = drawable; - drawable = &sub_pixmap->drawable; - saved_x = x; - saved_y = y; - x = 0; - y = 0; - } - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && - glamor_prepare_access_gc(gc)) { - fbFill(drawable, gc, x, y, width, height); - } - glamor_finish_access_gc(gc); - glamor_finish_access(drawable); - - if (sub_pixmap != NULL) { - if (gc->fillStyle != FillSolid) { - gc->patOrg.x -= (saved_drawable->x - saved_x); - gc->patOrg.y -= (saved_drawable->y - saved_y); - } - - x = saved_x; - y = saved_y; - - glamor_put_sub_pixmap(sub_pixmap, dst_pixmap, - x + off_x, y + off_y, - width, height, sub_pixmap_access); - } - - return TRUE; -} - -void -glamor_init_solid_shader(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv; - const char *solid_vs = - "attribute vec4 v_position;" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - "}\n"; - const char *solid_fs = - GLAMOR_DEFAULT_PRECISION - "uniform vec4 color;\n" - "void main()\n" - "{\n" - " gl_FragColor = color;\n" - "}\n"; - GLint fs_prog, vs_prog; - - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - glamor_priv->solid_prog = glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs); - glAttachShader(glamor_priv->solid_prog, vs_prog); - glAttachShader(glamor_priv->solid_prog, fs_prog); - - glBindAttribLocation(glamor_priv->solid_prog, - GLAMOR_VERTEX_POS, "v_position"); - glamor_link_glsl_prog(screen, glamor_priv->solid_prog, "solid"); - - glamor_priv->solid_color_uniform_location = - glGetUniformLocation(glamor_priv->solid_prog, "color"); -} - -void -glamor_fini_solid_shader(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv; - - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - glDeleteProgram(glamor_priv->solid_prog); -} - -static void -_glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) -{ - ScreenPtr screen = pixmap->drawable.pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - GLfloat xscale, yscale; - float stack_vertices[32]; - float *vertices = stack_vertices; - int valid_nbox = ARRAY_SIZE(stack_vertices) / (4 * 2); - - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - - glamor_make_current(glamor_priv); - glUseProgram(glamor_priv->solid_prog); - - glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); - - pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); - - if (nbox > valid_nbox) { - int allocated_nbox; - float *new_vertices; - - if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6) - allocated_nbox = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6; - else - allocated_nbox = nbox; - new_vertices = malloc(allocated_nbox * 4 * 2 * sizeof(float)); - if (new_vertices) { - vertices = new_vertices; - valid_nbox = allocated_nbox; - } - } - - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - - while (nbox) { - int box_cnt, i; - float *next_box; - - next_box = vertices; - box_cnt = nbox > valid_nbox ? valid_nbox : nbox; - for (i = 0; i < box_cnt; i++) { - glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale, - box[i].x1, box[i].y1, - box[i].x2, box[i].y2, - glamor_priv->yInverted, - next_box); - next_box += 4 * 2; - } - if (box_cnt == 1) - glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4); - else { - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6, - GL_UNSIGNED_SHORT, NULL); - } else { - glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT, - NULL); - } - } - nbox -= box_cnt; - box += box_cnt; - } - - if (vertices != stack_vertices) - free(vertices); - - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; -} - -/** - * Fills the given rectangles of pixmap with an X pixel value. - * - * This is a helper used by other code after clipping and translation - * of coordinates to a glamor backing pixmap. - */ -Bool -glamor_solid_boxes(PixmapPtr pixmap, - BoxPtr box, int nbox, unsigned long fg_pixel) -{ - glamor_pixmap_private *pixmap_priv; - GLfloat color[4]; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return FALSE; - - glamor_get_rgba_from_pixel(fg_pixel, - &color[0], - &color[1], - &color[2], &color[3], format_for_pixmap(pixmap)); - - if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - RegionRec region; - int n_region; - glamor_pixmap_clipped_regions *clipped_regions; - int i; - - RegionInitBoxes(®ion, box, nbox); - clipped_regions = - glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, 0, - 0, 0); - for (i = 0; i < n_region; i++) { - BoxPtr inner_box; - int inner_nbox; - - SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx); - - inner_box = RegionRects(clipped_regions[i].region); - inner_nbox = RegionNumRects(clipped_regions[i].region); - _glamor_solid_boxes(pixmap, inner_box, inner_nbox, color); - RegionDestroy(clipped_regions[i].region); - } - free(clipped_regions); - RegionUninit(®ion); - } - else - _glamor_solid_boxes(pixmap, box, nbox, color); - - return TRUE; -} - -/** - * Fills a rectangle of a pixmap with an X pixel value. - * - * This is a helper used by other glamor code mostly for clearing of - * buffers to 0. - */ -Bool -glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, unsigned long fg_pixel) -{ - ScreenPtr screen = pixmap->drawable.pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_pixmap_private *pixmap_priv; - BoxRec box; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return FALSE; - - if (!glamor_set_planemask(pixmap, planemask)) { - glamor_fallback("Failedto set planemask in glamor_solid.\n"); - return FALSE; - } - - glamor_make_current(glamor_priv); - if (!glamor_set_alu(screen, alu)) { - if (alu == GXclear) - fg_pixel = 0; - else { - glamor_fallback("unsupported alu %x\n", alu); - return FALSE; - } - } - box.x1 = x; - box.y1 = y; - box.x2 = x + width; - box.y2 = y + height; - glamor_solid_boxes(pixmap, &box, 1, fg_pixel); - - glamor_set_alu(screen, GXcopy); - - return TRUE; -} diff --git a/xorg-server/glamor/glamor_glyphblt.c b/xorg-server/glamor/glamor_glyphblt.c index 1c511ff2b..73b1df51e 100644 --- a/xorg-server/glamor/glamor_glyphblt.c +++ b/xorg-server/glamor/glamor_glyphblt.c @@ -56,7 +56,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, glamor_make_current(glamor_priv); - prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs, + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_glyph_blt_progs, &glamor_facet_poly_glyph_blt); if (!prog) goto bail_ctx; @@ -74,7 +75,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, int off_x, off_y; char *vbo_offset; - glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, prog->matrix_uniform, &off_x, &off_y); + glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, + prog->matrix_uniform, &off_x, &off_y); max_points = 500; num_points = 0; @@ -105,10 +107,12 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, if (!num_points) { points = glamor_get_vbo_space(screen, - max_points * (2 * sizeof (INT16)), + max_points * + (2 * sizeof (INT16)), &vbo_offset); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, + glVertexAttribPointer(GLAMOR_VERTEX_POS, + 2, GL_SHORT, GL_FALSE, 0, vbo_offset); } @@ -149,7 +153,8 @@ glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc, int start_x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyph_base) { - if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base)) + if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, + pglyph_base)) return; miPolyGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base); @@ -160,10 +165,13 @@ glamor_poly_glyph_blt_nf(DrawablePtr drawable, GCPtr gc, int start_x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyph_base) { - if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base)) + if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, + pglyph_base)) return TRUE; - if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc)) + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_gc(gc)) { return FALSE; + } miPolyGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base); return TRUE; @@ -179,8 +187,8 @@ glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc, } static Bool -glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap, - DrawablePtr drawable, int w, int h, int x, int y) +glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap, + DrawablePtr drawable, int w, int h, int x, int y) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -188,65 +196,40 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap, glamor_pixmap_private *pixmap_priv; uint8_t *bitmap_data = bitmap->devPrivate.ptr; int bitmap_stride = bitmap->devKind; - int off_x, off_y; + glamor_program *prog; + RegionPtr clip = gc->pCompositeClip; + int box_x, box_y; int yy, xx; - GLfloat xscale, yscale; - float color[4]; - unsigned long fg_pixel = gc->fgPixel; - float *points, *next_point; - int num_points = 0; + int num_points; + INT16 *points = NULL; char *vbo_offset; - RegionPtr clip; if (w * h > MAXINT / (2 * sizeof(float))) - return FALSE; - - if (gc->fillStyle != FillSolid) { - glamor_fallback("gc fillstyle not solid\n"); - return FALSE; - } + goto bail; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return FALSE; + goto bail; glamor_make_current(glamor_priv); - if (!glamor_set_alu(screen, gc->alu)) { - if (gc->alu == GXclear) - fg_pixel = 0; - else { - glamor_fallback("unsupported alu %x\n", gc->alu); - return FALSE; - } - } - - if (!glamor_set_planemask(pixmap, gc->planemask)) { - glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__); - return FALSE; - } - - glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); - - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); - glUseProgram(glamor_priv->solid_prog); + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_glyph_blt_progs, + &glamor_facet_poly_glyph_blt); + if (!prog) + goto bail_ctx; - glamor_get_rgba_from_pixel(fg_pixel, - &color[0], &color[1], &color[2], &color[3], - format_for_pixmap(pixmap)); - glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - points = glamor_get_vbo_space(screen, w * h * sizeof(float) * 2, + points = glamor_get_vbo_space(screen, w * h * sizeof(INT16) * 2, &vbo_offset); - next_point = points; - - clip = fbGetCompositeClip(gc); + num_points = 0; /* Note that because fb sets miTranslate in the GC, our incoming X * and Y are in screen coordinate space (same for spans, but not * other operations). */ + for (yy = 0; yy < h; yy++) { uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride; for (xx = 0; xx < w; xx++) { @@ -255,63 +238,58 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap, x + xx, y + yy, NULL)) { - next_point[0] = v_from_x_coord_x(xscale, x + xx + off_x + 0.5); - if (glamor_priv->yInverted) - next_point[1] = v_from_x_coord_y_inverted(yscale, y + yy + off_y + 0.5); - else - next_point[1] = v_from_x_coord_y(yscale, y + yy + off_y + 0.5); - - next_point += 2; + *points++ = x + xx; + *points++ = y + yy; num_points++; } } } - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - vbo_offset); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, + GL_FALSE, 0, vbo_offset); glamor_put_vbo_space(screen); - glDrawArrays(GL_POINTS, 0, num_points); - - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - - return TRUE; -} - -static Bool -_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y, - Bool fallback) -{ - glamor_pixmap_private *pixmap_priv; - - if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) - && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable) - && glamor_ddx_fallback_check_gc(pGC)) - return FALSE; + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, + prog->matrix_uniform, NULL, NULL); - pixmap_priv = glamor_get_pixmap_private(pBitmap); - if (pixmap_priv->type == GLAMOR_MEMORY) { - if (glamor_push_pixels_points(pGC, pBitmap, pDrawable, w, h, x, y)) - return TRUE; + glDrawArrays(GL_POINTS, 0, num_points); } - miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return TRUE; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); +bail: + return FALSE; } void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y) { - _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE); + if (glamor_push_pixels_gl(pGC, pBitmap, pDrawable, w, h, x, y)) + return; + + miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); } Bool -glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y) +glamor_push_pixels_nf(GCPtr gc, PixmapPtr bitmap, + DrawablePtr drawable, int w, int h, int x, int y) { - return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE); + if (glamor_push_pixels_gl(gc, bitmap, drawable, w, h, x, y)) + return TRUE; + + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_pixmap(&bitmap->drawable) && + glamor_ddx_fallback_check_gc(gc)) + { + return FALSE; + } + + miPushPixels(gc, bitmap, drawable, w, h, x, y); + return TRUE; } diff --git a/xorg-server/glamor/glamor_glyphs.c b/xorg-server/glamor/glamor_glyphs.c index 42f5f65f6..f570d7519 100644 --- a/xorg-server/glamor/glamor_glyphs.c +++ b/xorg-server/glamor/glamor_glyphs.c @@ -168,7 +168,7 @@ clear_mask_cache(struct glamor_glyph_mask_cache *maskcache) struct glamor_glyph_mask_cache_entry *mce; glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE, - MASK_CACHE_MAX_SIZE, GXcopy, 0xFFFFFFFF, 0); + MASK_CACHE_MAX_SIZE, 0); mce = &maskcache->mcache[0]; while (cnt--) { mce->width = 0; @@ -448,9 +448,9 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen, box.y1 = y; box.x2 = x + glyph->info.width; box.y2 = y + glyph->info.height; - glamor_copy_n_to_n_nf(&scratch->drawable, - &pCachePixmap->drawable, NULL, - &box, 1, -x, -y, FALSE, FALSE, 0, NULL); + glamor_copy(&scratch->drawable, + &pCachePixmap->drawable, NULL, + &box, 1, -x, -y, FALSE, FALSE, 0, NULL); if (scratch != pGlyphPixmap) screen->DestroyPixmap(scratch); @@ -1433,7 +1433,7 @@ glamor_glyphs_via_mask(CARD8 op, glamor_destroy_pixmap(mask_pixmap); return; } - glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0); + glamor_solid(mask_pixmap, 0, 0, width, height, 0); component_alpha = NeedsComponent(mask_format->format); mask = CreatePicture(0, &mask_pixmap->drawable, mask_format, CPComponentAlpha, diff --git a/xorg-server/glamor/glamor_gradient.c b/xorg-server/glamor/glamor_gradient.c index 28d66917f..4ded89dcd 100644 --- a/xorg-server/glamor/glamor_gradient.c +++ b/xorg-server/glamor/glamor_gradient.c @@ -699,7 +699,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen, width), (INT16) (dst_picture->pDrawable-> height), - glamor_priv->yInverted, vertices); + vertices); if (tex_normalize) { glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale, @@ -710,17 +710,14 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen, (INT16) (dst_picture-> pDrawable->height + y_source), - glamor_priv->yInverted, tex_vertices); } else { - glamor_set_tcoords_tri_strip((INT16) (dst_picture->pDrawable->width), - (INT16) (dst_picture->pDrawable->height), - x_source, y_source, + glamor_set_tcoords_tri_strip(x_source, y_source, (INT16) (dst_picture->pDrawable->width) + x_source, (INT16) (dst_picture->pDrawable->height) + - y_source, glamor_priv->yInverted, + y_source, tex_vertices); } @@ -1084,13 +1081,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2. radius); - glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted, - cxy); + glamor_set_circle_centre(width, height, c1x, c1y, cxy); glUniform2fv(c1_uniform_location, 1, cxy); glUniform1f(r1_uniform_location, r1); - glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted, - cxy); + glamor_set_circle_centre(width, height, c2x, c2y, cxy); glUniform2fv(c2_uniform_location, 1, cxy); glUniform1f(r2_uniform_location, r2); @@ -1322,7 +1317,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, linear.p1.x), pixman_fixed_to_double(src_picture->pSourcePict-> linear.p1.y), - glamor_priv->yInverted, pt1); + pt1); DEBUGF("pt1:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x), pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y), @@ -1333,7 +1328,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, linear.p2.x), pixman_fixed_to_double(src_picture->pSourcePict-> linear.p2.y), - glamor_priv->yInverted, pt2); + pt2); DEBUGF("pt2:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x), pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y), diff --git a/xorg-server/glamor/glamor_largepixmap.c b/xorg-server/glamor/glamor_largepixmap.c index b3a8d5d20..5a4bec571 100644 --- a/xorg-server/glamor/glamor_largepixmap.c +++ b/xorg-server/glamor/glamor_largepixmap.c @@ -797,9 +797,9 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, copy_box.y2 = temp_extent->y2 - temp_extent->y1; dx = temp_extent->x1; dy = temp_extent->y1; - glamor_copy_n_to_n(&priv->base.pixmap->drawable, - &temp_pixmap->drawable, - NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); + glamor_copy(&priv->base.pixmap->drawable, + &temp_pixmap->drawable, + NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); // glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width, // temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00); } @@ -829,9 +829,10 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, copy_box.x1, copy_box.y1, copy_box.x2, copy_box.y2, dx, dy); - glamor_copy_n_to_n(&priv->base.pixmap->drawable, - &temp_pixmap->drawable, - NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); + glamor_copy(&priv->base.pixmap->drawable, + &temp_pixmap->drawable, + NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); + box++; } } diff --git a/xorg-server/glamor/glamor_lines.c b/xorg-server/glamor/glamor_lines.c new file mode 100644 index 000000000..e9a619505 --- /dev/null +++ b/xorg-server/glamor/glamor_lines.c @@ -0,0 +1,187 @@ +/* + * 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_program.h" +#include "glamor_transform.h" +#include "glamor_prepare.h" + +static const glamor_facet glamor_facet_poly_lines = { + .name = "poly_lines", + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = (" vec2 pos = vec2(0.0,0.0);\n" + GLAMOR_POS(gl_Position, primitive.xy)), +}; + +static Bool +glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv; + glamor_program *prog; + int off_x, off_y; + DDXPointPtr v; + char *vbo_offset; + int box_x, box_y; + int add_last; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + add_last = 0; + if (gc->capStyle != CapNotLast) + add_last = 1; + + if (n < 2) + return TRUE; + + glamor_make_current(glamor_priv); + + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_line_program, + &glamor_facet_poly_lines); + + if (!prog) + goto bail_ctx; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, + (n + add_last) * sizeof (DDXPointRec), + &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, + sizeof (DDXPointRec), vbo_offset); + + if (mode == CoordModePrevious) { + int i; + DDXPointRec here = { 0, 0 }; + + for (i = 0; i < n; i++) { + here.x += points[i].x; + here.y += points[i].y; + v[i] = here; + } + } else { + memcpy(v, points, n * sizeof (DDXPointRec)); + } + + if (add_last) { + v[n].x = v[n-1].x + 1; + v[n].y = v[n-1].y; + } + + 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_LINE_STRIP, 0, n + add_last); + } + } + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + return TRUE; +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); +bail: + return FALSE; +} + +static Bool +glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + if (gc->lineWidth != 0) + return FALSE; + + switch (gc->lineStyle) { + case LineSolid: + return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points); + case LineOnOffDash: + return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points); + case LineDoubleDash: + if (gc->fillStyle == FillTiled) + return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points); + else + return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points); + default: + return FALSE; + } +} + +static void +glamor_poly_lines_bail(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + glamor_fallback("to %p (%c)\n", drawable, + glamor_get_drawable_location(drawable)); + + miPolylines(drawable, gc, mode, n, points); +} + +void +glamor_poly_lines(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + if (glamor_poly_lines_gl(drawable, gc, mode, n, points)) + return; + glamor_poly_lines_bail(drawable, gc, mode, n, points); +} + +Bool +glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + if (glamor_poly_lines_gl(drawable, gc, mode, n, points)) + return TRUE; + + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_gc(gc)) + { + return FALSE; + } + + glamor_poly_lines_bail(drawable, gc, mode, n, points); + return TRUE; +} + diff --git a/xorg-server/glamor/glamor_picture.c b/xorg-server/glamor/glamor_picture.c index 5fdc5f9b0..cbbc19406 100644 --- a/xorg-server/glamor/glamor_picture.c +++ b/xorg-server/glamor/glamor_picture.c @@ -45,24 +45,6 @@ glamor_upload_picture_to_texture(PicturePtr picture) return glamor_upload_pixmap_to_texture(pixmap); } -Bool -glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access) -{ - if (!picture || !picture->pDrawable) - return TRUE; - - return glamor_prepare_access(picture->pDrawable, access); -} - -void -glamor_finish_access_picture(PicturePtr picture) -{ - if (!picture || !picture->pDrawable) - return; - - glamor_finish_access(picture->pDrawable); -} - /* * We should already have drawable attached to it, if it has one. * Then set the attached pixmap to is_picture format, and set diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c index 789d3772e..ccb49f3c6 100644 --- a/xorg-server/glamor/glamor_pixmap.c +++ b/xorg-server/glamor/glamor_pixmap.c @@ -747,11 +747,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, glamor_get_screen_private(pixmap->drawable.pScreen); static float vertices[8]; - static float texcoords[8] = { 0, 1, - 1, 1, - 1, 0, - 0, 0 - }; static float texcoords_inv[8] = { 0, 0, 1, 0, 1, 1, @@ -760,11 +755,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, float *ptexcoords; float dst_xscale, dst_yscale; GLuint tex = 0; - int need_flip; int need_free_bits = 0; - need_flip = !glamor_priv->yInverted; - if (bits == NULL) goto ready_to_upload; @@ -798,7 +790,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, /* Try fast path firstly, upload the pixmap to the texture attached * to the fbo directly. */ if (no_alpha == 0 - && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING && !need_flip + && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING #ifdef WALKAROUND_LARGE_TEXTURE_MAP && pixmap_priv->type != GLAMOR_TEXTURE_LARGE #endif @@ -818,17 +810,14 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, return TRUE; } - if (need_flip) - ptexcoords = texcoords; - else - ptexcoords = texcoords_inv; + ptexcoords = texcoords_inv; pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale); glamor_set_normalize_vcoords(pixmap_priv, dst_xscale, dst_yscale, x, y, x + w, y + h, - glamor_priv->yInverted, vertices); + vertices); /* Slow path, we need to flip y or wire alpha to 1. */ glamor_make_current(glamor_priv); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, @@ -865,10 +854,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, /* * Prepare to upload a pixmap to texture memory. * no_alpha equals 1 means the format needs to wire alpha to 1. - * Two condtion need to setup a fbo for a pixmap - * 1. !yInverted, we need to do flip if we are not yInverted. - * 2. no_alpha != 0, we need to wire the alpha. - * */ + */ static int glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int revert, int swap_rb) @@ -896,8 +882,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, return 0; if (!(no_alpha || (revert == REVERT_NORMAL) - || (swap_rb != SWAP_NONE_UPLOADING) - || !glamor_priv->yInverted)) { + || (swap_rb != SWAP_NONE_UPLOADING))) { /* We don't need a fbo, a simple texture uploading should work. */ flag = GLAMOR_CREATE_FBO_NO_FBO; @@ -939,26 +924,6 @@ glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits, } } -/* - * download sub region from a large region. - */ -static void -glamor_get_bits(char *dst_bits, int dst_stride, char *src_bits, - int src_stride, int bpp, int x, int y, int w, int h) -{ - int j; - int byte_per_pixel; - - byte_per_pixel = bpp / 8; - dst_bits += y * dst_stride + x * byte_per_pixel; - - for (j = y; j < y + h; j++) { - memcpy(dst_bits, src_bits, w * byte_per_pixel); - src_bits += src_stride; - dst_bits += dst_stride; - } -} - Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h, int stride, void *bits, int pbo) @@ -1100,13 +1065,6 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap) return ret; } -void -glamor_restore_pixmap_to_texture(PixmapPtr pixmap) -{ - if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE) - LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n"); -} - /* * as gles2 only support a very small set of color format and * type when do glReadPixel, @@ -1142,7 +1100,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL, temp_xscale, temp_yscale, 0, 0, w, h, - glamor_priv->yInverted, vertices); + vertices); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); @@ -1153,7 +1111,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, source_yscale, x, y, x + w, y + h, - glamor_priv->yInverted, texcoords); + texcoords); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), texcoords); @@ -1176,330 +1134,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, return temp_fbo; } -/* - * Download a sub region of pixmap to a specified memory region. - * The pixmap must have a valid FBO, otherwise return a NULL. - * */ - -static void * -_glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format, - GLenum type, int no_alpha, - int revert, int swap_rb, - int x, int y, int w, int h, - int stride, void *bits, int pbo, - glamor_access_t access) -{ - glamor_pixmap_private *pixmap_priv; - GLenum gl_access = 0, gl_usage = 0; - void *data, *read; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - glamor_pixmap_fbo *temp_fbo = NULL; - int need_post_conversion = 0; - int need_free_data = 0; - int fbo_x_off, fbo_y_off; - - data = bits; - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return NULL; - - switch (access) { - case GLAMOR_ACCESS_RO: - gl_access = GL_READ_ONLY; - gl_usage = GL_STREAM_READ; - break; - case GLAMOR_ACCESS_RW: - gl_access = GL_READ_WRITE; - gl_usage = GL_DYNAMIC_DRAW; - break; - default: - ErrorF("Glamor: Invalid access code. %d\n", access); - assert(0); - } - - glamor_make_current(glamor_priv); - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - - need_post_conversion = (revert > REVERT_NORMAL); - if (need_post_conversion) { - if (pixmap->drawable.depth == 1) { - int temp_stride; - - temp_stride = (((w * 8 + 7) / 8) + 3) & ~3; - data = malloc(temp_stride * h); - if (data == NULL) - return NULL; - need_free_data = 1; - } - } - - pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off); - - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - && !need_post_conversion - && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) { - if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h, - format, type, no_alpha, - revert, swap_rb))) { - free(data); - return NULL; - } - x = 0; - y = 0; - fbo_x_off = 0; - fbo_y_off = 0; - } - - glPixelStorei(GL_PACK_ALIGNMENT, 4); - - if (glamor_priv->has_pack_invert || glamor_priv->yInverted) { - - if (!glamor_priv->yInverted) { - assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - glPixelStorei(GL_PACK_INVERT_MESA, 1); - } - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) { - assert(pbo > 0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); - glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, gl_usage); - } - - glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data); - - if (!glamor_priv->yInverted) { - assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - glPixelStorei(GL_PACK_INVERT_MESA, 0); - } - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) { - bits = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - } - } - else { - unsigned int temp_pbo; - int yy; - - glamor_make_current(glamor_priv); - glGenBuffers(1, &temp_pbo); - glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo); - glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, GL_STREAM_READ); - glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, 0); - read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - for (yy = 0; yy < pixmap->drawable.height; yy++) - memcpy((char *) data + yy * stride, - (char *) read + (h - yy - 1) * stride, stride); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - glDeleteBuffers(1, &temp_pbo); - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - if (need_post_conversion) { - /* As OpenGL desktop version never enters here. - * Don't need to consider if the pbo is valid.*/ - bits = glamor_color_convert_to_bits(data, bits, - w, h, - stride, no_alpha, revert, swap_rb); - } - - if (temp_fbo != NULL) - glamor_destroy_fbo(temp_fbo); - if (need_free_data) - free(data); - - return bits; -} - -void * -glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h, - int stride, void *bits, int pbo, - glamor_access_t access) -{ - GLenum format, type; - int no_alpha, revert, swap_rb; - glamor_pixmap_private *pixmap_priv; - Bool force_clip; - - if (glamor_get_tex_format_type_from_pixmap(pixmap, - &format, - &type, - &no_alpha, - &revert, &swap_rb, 0)) { - glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); - return NULL; - } - - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return NULL; - - force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP - && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h); - - if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) { - - RegionRec region; - BoxRec box; - int n_region; - glamor_pixmap_clipped_regions *clipped_regions; - void *sub_bits; - int i, j; - - sub_bits = malloc(h * stride); - if (sub_bits == NULL) - return FALSE; - box.x1 = x; - box.y1 = y; - box.x2 = x + w; - box.y2 = y + h; - RegionInitBoxes(®ion, &box, 1); - - if (!force_clip) - clipped_regions = - glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, - 0, 0, 0); - else - clipped_regions = - glamor_compute_clipped_regions_ext(pixmap_priv, ®ion, - &n_region, - pixmap_priv->large.block_w, - pixmap_priv->large.block_h, - 0, - 0); - - DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h); - for (i = 0; i < n_region; i++) { - BoxPtr boxes; - int nbox; - int temp_stride; - void *temp_bits; - - assert(pbo == 0); - SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx); - - boxes = RegionRects(clipped_regions[i].region); - nbox = RegionNumRects(clipped_regions[i].region); - for (j = 0; j < nbox; j++) { - temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1, - pixmap->drawable.depth); - - if (boxes[j].x1 == x && temp_stride == stride) { - temp_bits = (char *) bits + (boxes[j].y1 - y) * stride; - } - else { - temp_bits = sub_bits; - } - DEBUGF("download x %d y %d w %d h %d temp stride %d \n", - boxes[j].x1, boxes[j].y1, - boxes[j].x2 - boxes[j].x1, - boxes[j].y2 - boxes[j].y1, temp_stride); - - /* For large pixmap, we don't support pbo currently. */ - assert(pbo == 0); - if (_glamor_download_sub_pixmap_to_cpu - (pixmap, format, type, no_alpha, revert, swap_rb, - boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1, - boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits, pbo, - access) == FALSE) { - RegionUninit(®ion); - free(sub_bits); - assert(0); - return NULL; - } - if (boxes[j].x1 != x || temp_stride != stride) - glamor_get_bits(bits, stride, temp_bits, temp_stride, - pixmap->drawable.bitsPerPixel, - boxes[j].x1 - x, boxes[j].y1 - y, - boxes[j].x2 - boxes[j].x1, - boxes[j].y2 - boxes[j].y1); - } - - RegionDestroy(clipped_regions[i].region); - } - free(sub_bits); - free(clipped_regions); - RegionUninit(®ion); - return bits; - } - else - return _glamor_download_sub_pixmap_to_cpu(pixmap, format, type, - no_alpha, revert, swap_rb, x, - y, w, h, stride, bits, pbo, - access); -} - -/** - * Move a pixmap to CPU memory. - * The input data is the pixmap's fbo. - * The output data is at pixmap->devPrivate.ptr. We always use pbo - * to read the fbo and then map it to va. If possible, we will use - * it directly as devPrivate.ptr. - * If successfully download a fbo to cpu then return TRUE. - * Otherwise return FALSE. - **/ -Bool -glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) -{ - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - unsigned int stride; - void *data = NULL, *dst; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - int pbo = 0; - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return TRUE; - - glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD, - "Downloading pixmap %p %dx%d depth%d\n", - pixmap, - pixmap->drawable.width, - pixmap->drawable.height, pixmap->drawable.depth); - - stride = pixmap->devKind; - - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted) - || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - data = malloc(stride * pixmap->drawable.height); - } - else { - glamor_make_current(glamor_priv); - if (pixmap_priv->base.fbo->pbo == 0) - glGenBuffers(1, &pixmap_priv->base.fbo->pbo); - pbo = pixmap_priv->base.fbo->pbo; - } - - if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) { - stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth); - pixmap_priv->base.drm_stride = pixmap->devKind; - pixmap->devKind = stride; - } - - dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->devKind, data, pbo, access); - - if (!dst) { - if (data) - free(data); - return FALSE; - } - - if (pbo != 0) - pixmap_priv->base.fbo->pbo_valid = 1; - - pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED; - - pixmap->devPrivate.ptr = dst; - - return TRUE; -} - /* fixup a fbo to the exact size as the pixmap. */ /* XXX LARGE pixmap? */ Bool @@ -1558,132 +1192,3 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv) return ret; } - -/* - * We may use this function to reduce a large pixmap to a small sub - * pixmap. Two scenarios currently: - * 1. When fallback a large textured pixmap to CPU but we do need to - * do rendering within a small sub region, then we can just get a - * sub region. - * - * 2. When uploading a large pixmap to texture but we only need to - * use part of the source/mask picture. As glTexImage2D will be more - * efficient to upload a contingent region rather than a sub block - * in a large buffer. We use this function to gather the sub region - * to a contingent sub pixmap. - * - * The sub-pixmap must have the same format as the source pixmap. - * - * */ -PixmapPtr -glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, - glamor_access_t access) -{ - glamor_screen_private *glamor_priv; - PixmapPtr sub_pixmap; - glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv; - void *data; - int pbo; - int flag; - - if (x < 0 || y < 0) - return NULL; - w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w; - h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h; - - glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return NULL; - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 || - pixmap_priv->type == GLAMOR_TEXTURE_LARGE) - flag = GLAMOR_CREATE_PIXMAP_CPU; - else - flag = GLAMOR_CREATE_PIXMAP_MAP; - - sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h, - pixmap->drawable.depth, flag); - - if (sub_pixmap == NULL) - return NULL; - - sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap); - pbo = - sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base. - fbo->pbo : 0) : 0; - - if (pixmap_priv->base.is_picture) { - sub_pixmap_priv->base.picture = pixmap_priv->base.picture; - sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture; - } - - if (pbo) - data = NULL; - else - data = sub_pixmap->devPrivate.ptr; - - data = - glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, - sub_pixmap->devKind, data, pbo, - access); - if (data == NULL) { - fbDestroyPixmap(sub_pixmap); - return NULL; - } - if (pbo) { - assert(sub_pixmap->devPrivate.ptr == NULL); - sub_pixmap->devPrivate.ptr = data; - sub_pixmap_priv->base.fbo->pbo_valid = 1; - } -#if 0 - struct pixman_box16 box; - PixmapPtr new_sub_pixmap; - int dx, dy; - - box.x1 = 0; - box.y1 = 0; - box.x2 = w; - box.y2 = h; - - dx = x; - dy = y; - - new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h, - pixmap->drawable.depth, - GLAMOR_CREATE_PIXMAP_CPU); - glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap->drawable, NULL, &box, - 1, dx, dy, 0, 0, 0, NULL); - glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1); -#endif - - return sub_pixmap; -} - -void -glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, - int w, int h, glamor_access_t access) -{ - void *bits; - int pbo; - glamor_pixmap_private *sub_pixmap_priv; - - if (access != GLAMOR_ACCESS_RO) { - sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap); - if (sub_pixmap_priv->base.fbo && sub_pixmap_priv->base.fbo->pbo_valid) { - bits = NULL; - pbo = sub_pixmap_priv->base.fbo->pbo; - } - else { - bits = sub_pixmap->devPrivate.ptr; - pbo = 0; - } - - assert(x >= 0 && y >= 0); - w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w; - h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h; - glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h, - sub_pixmap->devKind, bits, pbo); - } - glamor_destroy_pixmap(sub_pixmap); -} diff --git a/xorg-server/glamor/glamor_points.c b/xorg-server/glamor/glamor_points.c index d4525e294..84383d254 100644 --- a/xorg-server/glamor/glamor_points.c +++ b/xorg-server/glamor/glamor_points.c @@ -105,9 +105,6 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint glDisable(GL_COLOR_LOGIC_OP); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - return TRUE; bail_ctx: diff --git a/xorg-server/glamor/glamor_polylines.c b/xorg-server/glamor/glamor_polylines.c deleted file mode 100644 index 1adf45ddc..000000000 --- a/xorg-server/glamor/glamor_polylines.c +++ /dev/null @@ -1,136 +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: - * Eric Anholt - * - */ - -#include "glamor_priv.h" - -/** @file glamor_polylines.c - * - * GC PolyFillRect implementation, taken straight from fb_fill.c - */ - -/** - * glamor_poly_lines() checks if it can accelerate the lines as a group of - * horizontal or vertical lines (rectangles), and uses existing rectangle fill - * acceleration if so. - */ -static Bool -_glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points, Bool fallback) -{ - xRectangle *rects; - int x1, x2, y1, y2; - int i; - - /* Don't try to do wide lines or non-solid fill style. */ - if (gc->lineWidth != 0) { - /* This ends up in miSetSpans, which is accelerated as well as we - * can hope X wide lines will be. - */ - goto fail; - } - - if (gc->lineStyle != LineSolid) { - glamor_fallback("non-solid fill line style %d\n", gc->lineStyle); - goto fail; - } - rects = malloc(sizeof(xRectangle) * (n - 1)); - x1 = points[0].x; - y1 = points[0].y; - /* If we have any non-horizontal/vertical, fall back. */ - for (i = 0; i < n - 1; i++) { - if (mode == CoordModePrevious) { - x2 = x1 + points[i + 1].x; - y2 = y1 + points[i + 1].y; - } - else { - x2 = points[i + 1].x; - y2 = points[i + 1].y; - } - if (x1 != x2 && y1 != y2) { - free(rects); - glamor_fallback("stub diagonal poly_line\n"); - goto fail; - } - if (x1 < x2) { - rects[i].x = x1; - rects[i].width = x2 - x1 + 1; - } - else { - rects[i].x = x2; - rects[i].width = x1 - x2 + 1; - } - if (y1 < y2) { - rects[i].y = y1; - rects[i].height = y2 - y1 + 1; - } - else { - rects[i].y = y2; - rects[i].height = y1 - y2 + 1; - } - - x1 = x2; - y1 = y2; - } - gc->ops->PolyFillRect(drawable, gc, n - 1, rects); - free(rects); - return TRUE; - - fail: - if (!fallback && glamor_ddx_fallback_check_pixmap(drawable) - && glamor_ddx_fallback_check_gc(gc)) - return FALSE; - - switch (gc->lineStyle) { - case LineSolid: - if (gc->lineWidth == 0) - miZeroLine(drawable, gc, mode, n, points); - else - miWideLine(drawable, gc, mode, n, points); - break; - case LineOnOffDash: - case LineDoubleDash: - miWideDash(drawable, gc, mode, n, points); - break; - } - - return TRUE; -} - -void -glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points) -{ - _glamor_poly_lines(drawable, gc, mode, n, points, TRUE); -} - -Bool -glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points) -{ - return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE); -} diff --git a/xorg-server/glamor/glamor_prepare.c b/xorg-server/glamor/glamor_prepare.c new file mode 100644 index 000000000..561c55d19 --- /dev/null +++ b/xorg-server/glamor/glamor_prepare.c @@ -0,0 +1,274 @@ +/* + * 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_prepare.h" +#include "glamor_transfer.h" + +/* + * Make a pixmap ready to draw with fb by + * creating a PBO large enough for the whole object + * and downloading all of the FBOs into it. + */ + +static Bool +glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); + int gl_access, gl_usage; + RegionRec region; + + if (priv->type == GLAMOR_DRM_ONLY) + return FALSE; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) + return TRUE; + + RegionInit(®ion, box, 1); + + /* See if it's already mapped */ + if (pixmap->devPrivate.ptr) { + /* + * Someone else has mapped this pixmap; + * we'll assume that it's directly mapped + * by a lower level driver + */ + if (!priv->base.prepared) + return TRUE; + + /* In X, multiple Drawables can be stored in the same Pixmap (such as + * each individual window in a non-composited screen pixmap, or the + * reparented window contents inside the window-manager-decorated window + * pixmap on a composited screen). + * + * As a result, when doing a series of mappings for a fallback, we may + * need to add more boxes to the set of data we've downloaded, as we go. + */ + RegionSubtract(®ion, ®ion, &priv->base.prepare_region); + if (!RegionNotEmpty(®ion)) + return TRUE; + + if (access == GLAMOR_ACCESS_RW) + FatalError("attempt to remap buffer as writable"); + + if (priv->base.pbo) { + glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + pixmap->devPrivate.ptr = NULL; + } + } else { + RegionInit(&priv->base.prepare_region, box, 1); + + if (glamor_priv->has_rw_pbo) { + if (priv->base.pbo == 0) + glGenBuffers(1, &priv->base.pbo); + + if (access == GLAMOR_ACCESS_RW) + gl_usage = GL_DYNAMIC_DRAW; + else + gl_usage = GL_STREAM_READ; + + glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo); + glBufferData(GL_PIXEL_PACK_BUFFER, + pixmap->devKind * pixmap->drawable.height, NULL, + gl_usage); + } else { + pixmap->devPrivate.ptr = malloc(pixmap->devKind * + pixmap->drawable.height); + if (!pixmap->devPrivate.ptr) + return FALSE; + } + priv->base.map_access = access; + } + + glamor_download_boxes(pixmap, RegionRects(®ion), RegionNumRects(®ion), + 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind); + + RegionUninit(®ion); + + if (glamor_priv->has_rw_pbo) { + if (priv->base.map_access == GLAMOR_ACCESS_RW) + gl_access = GL_READ_WRITE; + else + gl_access = GL_READ_ONLY; + + pixmap->devPrivate.ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + } + + priv->base.prepared = TRUE; + return TRUE; +} + +/* + * When we're done with the drawable, unmap the PBO, reupload + * if we were writing to it and then unbind it to release the memory + */ + +static void +glamor_fini_pixmap(PixmapPtr pixmap) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) + return; + + if (!priv->base.prepared) + return; + + if (glamor_priv->has_rw_pbo) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->base.pbo); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + pixmap->devPrivate.ptr = NULL; + } + + if (priv->base.map_access == GLAMOR_ACCESS_RW) { + glamor_upload_boxes(pixmap, + RegionRects(&priv->base.prepare_region), + RegionNumRects(&priv->base.prepare_region), + 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind); + } + + RegionUninit(&priv->base.prepare_region); + + if (glamor_priv->has_rw_pbo) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glDeleteBuffers(1, &priv->base.pbo); + priv->base.pbo = 0; + } else { + free(pixmap->devPrivate.ptr); + pixmap->devPrivate.ptr = NULL; + } + + priv->base.prepared = FALSE; +} + +Bool +glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + BoxRec box; + int off_x, off_y; + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + + box.x1 = drawable->x + off_x; + box.x2 = box.x1 + drawable->width; + box.y1 = drawable->y + off_y; + box.y2 = box.y1 + drawable->height; + return glamor_prep_pixmap_box(pixmap, access, &box); +} + +Bool +glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access, + int x, int y, int w, int h) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + BoxRec box; + int off_x, off_y; + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + box.x1 = drawable->x + x + off_x; + box.x2 = box.x1 + w; + box.y1 = drawable->y + y + off_y; + box.y2 = box.y1 + h; + return glamor_prep_pixmap_box(pixmap, access, &box); +} + +void +glamor_finish_access(DrawablePtr drawable) +{ + glamor_fini_pixmap(glamor_get_drawable_pixmap(drawable)); +} + +/* + * Make a picture ready to use with fb. + */ + +Bool +glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access) +{ + if (!picture || !picture->pDrawable) + return TRUE; + + return glamor_prepare_access(picture->pDrawable, access); +} + +Bool +glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access, + int x, int y, int w, int h) +{ + if (!picture || !picture->pDrawable) + return TRUE; + return glamor_prepare_access_box(picture->pDrawable, access, + x, y, w, h); +} + +void +glamor_finish_access_picture(PicturePtr picture) +{ + if (!picture || !picture->pDrawable) + return; + + glamor_finish_access(picture->pDrawable); +} + +/* + * Make a GC ready to use with fb. This just + * means making sure the appropriate fill pixmap is + * in CPU memory again + */ + +Bool +glamor_prepare_access_gc(GCPtr gc) +{ + switch (gc->fillStyle) { + case FillTiled: + return glamor_prepare_access(&gc->tile.pixmap->drawable, + GLAMOR_ACCESS_RO); + case FillStippled: + case FillOpaqueStippled: + return glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO); + } + return TRUE; +} + +/* + * Free any temporary CPU pixmaps for the GC + */ +void +glamor_finish_access_gc(GCPtr gc) +{ + switch (gc->fillStyle) { + case FillTiled: + glamor_finish_access(&gc->tile.pixmap->drawable); + break; + case FillStippled: + case FillOpaqueStippled: + glamor_finish_access(&gc->stipple->drawable); + break; + } +} diff --git a/xorg-server/glamor/glamor_prepare.h b/xorg-server/glamor/glamor_prepare.h new file mode 100644 index 000000000..85fa79574 --- /dev/null +++ b/xorg-server/glamor/glamor_prepare.h @@ -0,0 +1,52 @@ +/* + * 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_PREPARE_H_ +#define _GLAMOR_PREPARE_H_ + +Bool +glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); + +Bool +glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access, + int x, int y, int w, int h); + +void +glamor_finish_access(DrawablePtr drawable); + +Bool +glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); + +Bool +glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access, + int x, int y, int w, int h); + +void +glamor_finish_access_picture(PicturePtr picture); + +Bool +glamor_prepare_access_gc(GCPtr gc); + +void +glamor_finish_access_gc(GCPtr gc); + +#endif /* _GLAMOR_PREPARE_H_ */ diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h index c56c55973..57a46873c 100644 --- a/xorg-server/glamor/glamor_priv.h +++ b/xorg-server/glamor/glamor_priv.h @@ -31,6 +31,12 @@ #include #include "glamor.h" +#include "xvdix.h" + +#if XSYNC +#include "misyncshm.h" +#include "misyncstr.h" +#endif #include #if GLAMOR_HAS_GBM @@ -183,6 +189,9 @@ struct glamor_saved_procs { DestroyPictureProcPtr destroy_picture; UnrealizeGlyphProcPtr unrealize_glyph; SetWindowPixmapProcPtr set_window_pixmap; +#if XSYNC + SyncScreenFuncsRec sync_screen_funcs; +#endif }; #define CACHE_FORMAT_COUNT 3 @@ -193,13 +202,7 @@ struct glamor_saved_procs { #define GLAMOR_TICK_AFTER(t0, t1) \ (((int)(t1) - (int)(t0)) < 0) -#define IDLE_STATE 0 -#define RENDER_STATE 1 -#define BLIT_STATE 2 -#define RENDER_IDEL_MAX 32 - typedef struct glamor_screen_private { - Bool yInverted; unsigned int tick; enum glamor_gl_flavor gl_flavor; int glsl_version; @@ -208,16 +211,14 @@ typedef struct glamor_screen_private { int has_map_buffer_range; int has_buffer_storage; int has_khr_debug; + int has_nv_texture_barrier; int max_fbo_size; + int has_rw_pbo; struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; unsigned long fbo_cache_watermark; - /* glamor_solid */ - GLint solid_prog; - GLint solid_color_uniform_location; - /* glamor point shader */ glamor_program point_prog; @@ -235,6 +236,20 @@ typedef struct glamor_screen_private { glamor_program te_text_prog; glamor_program image_text_prog; + /* glamor copy shaders */ + glamor_program copy_area_prog; + glamor_program copy_plane_prog; + + /* glamor line shader */ + glamor_program_fill poly_line_program; + + /* glamor segment shaders */ + glamor_program_fill poly_segment_program; + + /* glamor dash line shader */ + glamor_program_fill on_off_dash_line_progs; + glamor_program double_dash_line_prog; + /* vertext/elment_index buffer object for render */ GLuint vbo, ebo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ @@ -261,10 +276,6 @@ typedef struct glamor_screen_private { GLint finish_access_revert[2]; GLint finish_access_swap_rb[2]; - /* glamor_tile */ - GLint tile_prog; - GLint tile_wh; - /* glamor gradient, 0 for small nstops, 1 for large nstops and 2 for dynamic generate. */ GLint gradient_prog[SHADER_GRADIENT_COUNT][3]; @@ -280,8 +291,6 @@ typedef struct glamor_screen_private { char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; int delayed_fallback_pending; int flags; - int state; - unsigned int render_idle_cnt; ScreenPtr screen; int dri3_enabled; @@ -430,6 +439,9 @@ typedef struct glamor_pixmap_private_base { int drm_stride; glamor_screen_private *glamor_priv; PicturePtr picture; + GLuint pbo; + RegionRec prepare_region; + Bool prepared; #if GLAMOR_HAS_GBM EGLImageKHR image; #endif @@ -528,7 +540,7 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv) 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. * * GLAMOR_NONE: initial status, don't need to do anything. @@ -544,19 +556,29 @@ typedef enum glamor_pixmap_status { GLAMOR_UPLOAD_FAILED } glamor_pixmap_status_t; -extern DevPrivateKey glamor_screen_private_key; -extern DevPrivateKey glamor_pixmap_private_key; +/* GC private structure. Currently holds only any computed dash pixmap */ + +typedef struct { + PixmapPtr dash; + PixmapPtr stipple; + DamagePtr stipple_damage; +} glamor_gc_private; + +extern DevPrivateKeyRec glamor_gc_private_key; +extern DevPrivateKeyRec glamor_screen_private_key; +extern DevPrivateKeyRec glamor_pixmap_private_key; + static inline glamor_screen_private * glamor_get_screen_private(ScreenPtr screen) { return (glamor_screen_private *) - dixLookupPrivate(&screen->devPrivates, glamor_screen_private_key); + dixLookupPrivate(&screen->devPrivates, &glamor_screen_private_key); } static inline void glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv) { - dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, priv); + dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv); } static inline glamor_pixmap_private * @@ -564,17 +586,23 @@ glamor_get_pixmap_private(PixmapPtr pixmap) { glamor_pixmap_private *priv; - priv = dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); + priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key); if (!priv) { glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY); priv = dixLookupPrivate(&pixmap->devPrivates, - glamor_pixmap_private_key); + &glamor_pixmap_private_key); } return priv; } void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv); +static inline glamor_gc_private * +glamor_get_gc_private(GCPtr gc) +{ + return dixLookupPrivate(&gc->devPrivates, &glamor_gc_private_key); +} + /** * Returns TRUE if the given planemask covers all the significant bits in the * pixel values for pDrawable. @@ -614,32 +642,13 @@ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv, int flag, int block_w, int block_h, glamor_pixmap_private *); -/* glamor_copyarea.c */ -RegionPtr - -glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, - int srcx, int srcy, int width, int height, int dstx, int dsty); -void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc, - BoxPtr box, int nbox, int dx, int dy, Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure); - /* glamor_core.c */ -Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); -void glamor_finish_access(DrawablePtr drawable); -Bool glamor_prepare_access_window(WindowPtr window); -void glamor_finish_access_window(WindowPtr window); -Bool glamor_prepare_access_gc(GCPtr gc); -void glamor_finish_access_gc(GCPtr gc); void glamor_init_finish_access_shaders(ScreenPtr screen); void glamor_fini_finish_access_shaders(ScreenPtr screen); + const Bool glamor_get_drawable_location(const DrawablePtr drawable); void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int *x, int *y); -Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, - int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - unsigned long fg_pixel, unsigned long bg_pixel, - int stipple_x, int stipple_y); GLint glamor_compile_glsl_prog(GLenum type, const char *source); void glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4); @@ -651,7 +660,7 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv); void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int); /* nc means no check. caller must ensure this pixmap has valid fbo. - * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. + * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. * */ void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv); @@ -665,17 +674,8 @@ Bool glamor_set_alu(ScreenPtr screen, unsigned char alu); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); -/* glamor_fill.c */ -Bool glamor_fill(DrawablePtr drawable, - GCPtr gc, int x, int y, int width, int height, Bool fallback); -Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - unsigned long fg_pixel); -Bool glamor_solid_boxes(PixmapPtr pixmap, - BoxPtr box, int nbox, unsigned long fg_pixel); - -void glamor_init_solid_shader(ScreenPtr screen); -void glamor_fini_solid_shader(ScreenPtr screen); +void +glamor_track_stipple(GCPtr gc); /* glamor_glyphs.c */ Bool glamor_realize_glyph_caches(ScreenPtr screen); @@ -687,10 +687,6 @@ void glamor_glyphs(CARD8 op, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs); -/* glamor_polylines.c */ -void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points); - /* glamor_render.c */ Bool glamor_composite_clipped_region(CARD8 op, PicturePtr source, @@ -756,14 +752,6 @@ void glamor_trapezoids(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps); -/* glamor_tile.c */ -Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, - int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - int tile_x, int tile_y); -void glamor_init_tile_shader(ScreenPtr screen); -void glamor_fini_tile_shader(ScreenPtr screen); - /* glamor_gradient.c */ void glamor_init_gradient_shader(ScreenPtr screen); void glamor_fini_gradient_shader(ScreenPtr screen); @@ -801,31 +789,6 @@ 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 - * the pixmap->devPrivate.ptr. Will use pbo to map to - * the pointer if possible. - * The pixmap must be a gl texture pixmap. gl_fbo must be GLAMOR_FBO_NORMAL and - * gl_tex must be 1. Used by glamor_prepare_access. - * - */ -Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access); - -void *glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, - int h, int stride, void *bits, int pbo, - glamor_access_t access); - -/** - * Restore a pixmap's data which is downloaded by - * glamor_download_pixmap_to_cpu to its original - * gl texture. Used by glamor_finish_access. - * - * The pixmap must originally be a texture -- gl_fbo must be - * GLAMOR_FBO_NORMAL. - **/ -void glamor_restore_pixmap_to_texture(PixmapPtr pixmap); - /** * According to the flag, * if the flag is GLAMOR_CREATE_FBO_NO_FBO then just ensure @@ -846,11 +809,6 @@ Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h, int stride, void *bits, int pbo); -PixmapPtr glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, - int w, int h, glamor_access_t access); -void glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, - int w, int h, glamor_access_t access); - glamor_pixmap_clipped_regions * glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, int *clipped_nbox, @@ -909,20 +867,10 @@ Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type, int no_alpha, int revert, int swap_rb, void *bits); -/** - * Destroy all the resources allocated on the uploading - * phase, includs the tex and fbo. - **/ -void glamor_destroy_upload_pixmap(PixmapPtr pixmap); - int glamor_create_picture(PicturePtr picture); void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap); -Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); - -void glamor_finish_access_picture(PicturePtr picture); - void glamor_destroy_picture(PicturePtr picture); /* fixup a fbo to the exact size as the pixmap. */ @@ -935,11 +883,6 @@ void glamor_picture_format_fixup(PicturePtr picture, void glamor_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap *traps); -RegionPtr glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, - int dstx, int dsty, - unsigned long bitPlane); - /* glamor_text.c */ int glamor_poly_text8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars); @@ -981,6 +924,48 @@ void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); +/* glamor_dash.c */ +Bool +glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points); + +Bool +glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs); + +/* glamor_lines.c */ +void +glamor_poly_lines(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points); + +/* glamor_segs.c */ +void +glamor_poly_segment(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs); + +/* glamor_copy.c */ +void +glamor_copy(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +RegionPtr +glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty); + +RegionPtr +glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty, + unsigned long bitplane); + /* glamor_glyphblt.c */ void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, @@ -996,17 +981,28 @@ void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt); -void glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg); - -void glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt); - void glamor_composite_rectangles(CARD8 op, PicturePtr dst, xRenderColor *color, int num_rects, xRectangle *rects); +/* glamor_sync.c */ +Bool +glamor_sync_init(ScreenPtr screen); + +void +glamor_sync_close(ScreenPtr screen); + +/* glamor_util.c */ +void +glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, + unsigned long fg_pixel); + +void +glamor_solid_boxes(PixmapPtr pixmap, + BoxPtr box, int nbox, unsigned long fg_pixel); + + /* glamor_xv */ typedef struct { uint32_t transform_index; @@ -1028,15 +1024,41 @@ typedef struct { int src_pix_w, src_pix_h; } glamor_port_private; -void glamor_init_xv_shader(ScreenPtr screen); -void glamor_fini_xv_shader(ScreenPtr screen); +extern XvAttributeRec glamor_xv_attributes[]; +extern int glamor_xv_num_attributes; +extern XvImageRec glamor_xv_images[]; +extern int glamor_xv_num_images; + +void glamor_xv_init_port(glamor_port_private *port_priv); +void glamor_xv_stop_video(glamor_port_private *port_priv); +int glamor_xv_set_port_attribute(glamor_port_private *port_priv, + Atom attribute, INT32 value); +int glamor_xv_get_port_attribute(glamor_port_private *port_priv, + Atom attribute, INT32 *value); +int glamor_xv_query_image_attributes(int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets); +int glamor_xv_put_image(glamor_port_private *port_priv, + DrawablePtr pDrawable, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes); +void glamor_xv_core_init(ScreenPtr screen); +void glamor_xv_render(glamor_port_private *port_priv); #include"glamor_utils.h" -/* Dynamic pixmap upload to texture if needed. +/* Dynamic pixmap upload to texture if needed. * Sometimes, the target is a gl texture pixmap/picture, * but the source or mask is in cpu memory. In that case, - * upload the source/mask to gl texture and then avoid + * upload the source/mask to gl texture and then avoid * fallback the whole process to cpu. Most of the time, * this will increase performance obviously. */ diff --git a/xorg-server/glamor/glamor_program.c b/xorg-server/glamor/glamor_program.c index 0f4d0f06a..1d0328f2b 100644 --- a/xorg-server/glamor/glamor_program.c +++ b/xorg-server/glamor/glamor_program.c @@ -51,42 +51,51 @@ static const glamor_facet glamor_fill_tile = { .use = use_tile, }; -#if 0 static Bool -use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog) +use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { - return glamor_set_stippled(pixmap, gc, prog->fg_uniform, prog->fill_offset_uniform, prog->fill_size_uniform); + 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" + .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n", + .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n" + " if (a == 0.0)\n" " discard;\n" - " gl_FragColor = fg;\n") - .locations = glamor_program_location_fg | glamor_program_location_fill + " gl_FragColor = fg;\n"), + .locations = glamor_program_location_fg | glamor_program_location_fill, .use = use_stipple, }; +static Bool +use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) +{ + if (!use_stipple(pixmap, gc, prog, arg)) + return FALSE; + glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform); + return TRUE; +} + 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" + .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n", + .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n" + " if (a == 0.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 + .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, + &glamor_fill_stipple, + &glamor_fill_opaque_stipple, }; typedef struct { @@ -117,6 +126,16 @@ static glamor_location_var location_vars[] = { .location = glamor_program_location_font, .fs_vars = "uniform usampler2D font;\n", }, + { + .location = glamor_program_location_bitplane, + .fs_vars = ("uniform uvec4 bitplane;\n" + "uniform vec4 bitmul;\n"), + }, + { + .location = glamor_program_location_dash, + .vs_vars = "uniform float dash_length;\n", + .fs_vars = "uniform sampler2D dash;\n", + }, }; #define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0]) @@ -196,6 +215,8 @@ static const glamor_facet facet_null_fill = { .name = "" }; +#define DBG 0 + static GLint glamor_get_uniform(glamor_program *prog, glamor_program_location location, @@ -281,7 +302,6 @@ glamor_build_program(ScreenPtr screen, 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); @@ -318,6 +338,10 @@ glamor_build_program(ScreenPtr screen, 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"); + prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane"); + prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul"); + prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash"); + prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length"); if (glGetError() != GL_NO_ERROR) goto fail; diff --git a/xorg-server/glamor/glamor_program.h b/xorg-server/glamor/glamor_program.h index 88efc3593..56ba03aa8 100644 --- a/xorg-server/glamor/glamor_program.h +++ b/xorg-server/glamor/glamor_program.h @@ -29,6 +29,8 @@ typedef enum { glamor_program_location_bg = 2, glamor_program_location_fill = 4, glamor_program_location_font = 8, + glamor_program_location_bitplane = 16, + glamor_program_location_dash = 32, } glamor_program_location; typedef enum { @@ -61,6 +63,10 @@ struct _glamor_program { GLint fill_size_uniform; GLint fill_offset_uniform; GLint font_uniform; + GLint bitplane_uniform; + GLint bitmul_uniform; + GLint dash_uniform; + GLint dash_length_uniform; glamor_program_location locations; glamor_program_flag flags; glamor_use prim_use; diff --git a/xorg-server/glamor/glamor_render.c b/xorg-server/glamor/glamor_render.c index 14ab738eb..2386f2e2e 100644 --- a/xorg-server/glamor/glamor_render.c +++ b/xorg-server/glamor/glamor_render.c @@ -651,11 +651,12 @@ glamor_composite_with_copy(CARD8 op, if (region->extents.y2 + y_source - y_dest > source->pDrawable->height) goto cleanup_region; } - ret = glamor_copy_n_to_n_nf(source->pDrawable, - dest->pDrawable, NULL, - RegionRects(region), RegionNumRects(region), - x_source - x_dest, y_source - y_dest, - FALSE, FALSE, 0, NULL); + glamor_copy(source->pDrawable, + dest->pDrawable, NULL, + RegionRects(region), RegionNumRects(region), + x_source - x_dest, y_source - y_dest, + FALSE, FALSE, 0, NULL); + ret = TRUE; cleanup_region: return ret; } @@ -792,30 +793,29 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv, float *matrix, float xscale, float yscale, int x1, int y1, int x2, int y2, - int yInverted, float *texcoords, + float *texcoords, int stride) { if (!matrix && repeat_type == RepeatNone) glamor_set_normalize_tcoords_ext(priv, xscale, yscale, x1, y1, - x2, y2, yInverted, texcoords, stride); + x2, y2, texcoords, stride); else if (matrix && repeat_type == RepeatNone) glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, yscale, x1, y1, x2, y2, - yInverted, texcoords, stride); else if (!matrix && repeat_type != RepeatNone) glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, xscale, yscale, x1, y1, x2, y2, - yInverted, texcoords, stride); + texcoords, stride); else if (matrix && repeat_type != RepeatNone) glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type, matrix, xscale, yscale, x1, y1, x2, - y2, yInverted, + y2, texcoords, stride); } @@ -1265,7 +1265,7 @@ glamor_composite_with_shader(CARD8 op, glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale, dst_yscale, x_dest, y_dest, x_dest + width, y_dest + height, - glamor_priv->yInverted, vertices, + vertices, vb_stride); vertices += 2; if (key.source != SHADER_SOURCE_SOLID) { @@ -1275,7 +1275,6 @@ glamor_composite_with_shader(CARD8 op, src_yscale, x_source, y_source, x_source + width, y_source + height, - glamor_priv->yInverted, vertices, vb_stride); vertices += 2; } @@ -1287,7 +1286,6 @@ glamor_composite_with_shader(CARD8 op, mask_yscale, x_mask, y_mask, x_mask + width, y_mask + height, - glamor_priv->yInverted, vertices, vb_stride); vertices += 2; } @@ -1315,8 +1313,6 @@ glamor_composite_with_shader(CARD8 op, glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); glDisable(GL_BLEND); DEBUGF("finish rendering.\n"); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; if (saved_source_format) source->format = saved_source_format; @@ -1450,8 +1446,8 @@ glamor_composite_clipped_region(CARD8 op, || source_pixmap->drawable.height != height)))) { temp_src = glamor_convert_gradient_picture(screen, source, - extent->x1 + x_source - x_dest, - extent->y1 + y_source - y_dest, + extent->x1 + x_source - x_dest - dest->pDrawable->x, + extent->y1 + y_source - y_dest - dest->pDrawable->y, width, height); if (!temp_src) { temp_src = source; @@ -1459,8 +1455,8 @@ glamor_composite_clipped_region(CARD8 op, } temp_src_priv = glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable)); - x_temp_src = -extent->x1 + x_dest; - y_temp_src = -extent->y1 + y_dest; + x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x; + y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y; } if (mask @@ -1474,8 +1470,8 @@ glamor_composite_clipped_region(CARD8 op, * to do reduce one convertion. */ temp_mask = glamor_convert_gradient_picture(screen, mask, - extent->x1 + x_mask - x_dest, - extent->y1 + y_mask - y_dest, + extent->x1 + x_mask - x_dest - dest->pDrawable->x, + extent->y1 + y_mask - y_dest - dest->pDrawable->y, width, height); if (!temp_mask) { temp_mask = mask; @@ -1483,8 +1479,8 @@ glamor_composite_clipped_region(CARD8 op, } temp_mask_priv = glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable)); - x_temp_mask = -extent->x1 + x_dest; - y_temp_mask = -extent->y1 + y_dest; + x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x; + y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y; } /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. @@ -1586,15 +1582,6 @@ _glamor_composite(CARD8 op, RegionRec region; BoxPtr extent; int nbox, ok = FALSE; - PixmapPtr sub_dest_pixmap = NULL; - PixmapPtr sub_source_pixmap = NULL; - PixmapPtr sub_mask_pixmap = NULL; - int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y; - int source_x_off, source_y_off, saved_source_x, saved_source_y; - int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y; - DrawablePtr saved_dest_drawable; - DrawablePtr saved_source_drawable; - DrawablePtr saved_mask_drawable; int force_clip = 0; dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); @@ -1737,34 +1724,13 @@ _glamor_composite(CARD8 op, dest->pDrawable->width, dest->pDrawable->height, glamor_get_picture_location(dest)); -#define GET_SUB_PICTURE(p, access) do { \ - glamor_get_drawable_deltas(p->pDrawable, p ##_pixmap, \ - & p ##_x_off, & p ##_y_off); \ - sub_ ##p ##_pixmap = glamor_get_sub_pixmap(p ##_pixmap, \ - x_ ##p + p ##_x_off + p->pDrawable->x, \ - y_ ##p + p ##_y_off + p->pDrawable->y, \ - width, height, access); \ - if (sub_ ##p ##_pixmap != NULL) { \ - saved_ ##p ##_drawable = p->pDrawable; \ - saved_ ##p ##_x = x_ ##p; \ - saved_ ##p ##_y = y_ ##p; \ - if (p->pCompositeClip) \ - pixman_region_translate (p->pCompositeClip, \ - -p->pDrawable->x - x_ ##p, \ - -p->pDrawable->y - y_ ##p); \ - p->pDrawable = &sub_ ##p ##_pixmap->drawable; \ - x_ ##p = 0; \ - y_ ##p = 0; \ - } } while(0) - GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW); - if (source->pDrawable && !source->transform) - GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO); - if (mask && mask->pDrawable && !mask->transform) - GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO); - - if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW) && - glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO) && - glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) { + if (glamor_prepare_access_picture_box(dest, GLAMOR_ACCESS_RW, + x_dest, y_dest, width, height) && + glamor_prepare_access_picture_box(source, GLAMOR_ACCESS_RO, + x_source, y_source, width, height) && + glamor_prepare_access_picture_box(mask, GLAMOR_ACCESS_RO, + x_mask, y_mask, width, height)) + { fbComposite(op, source, mask, dest, x_source, y_source, @@ -1774,25 +1740,6 @@ _glamor_composite(CARD8 op, glamor_finish_access_picture(source); glamor_finish_access_picture(dest); -#define PUT_SUB_PICTURE(p, access) do { \ - if (sub_ ##p ##_pixmap != NULL) { \ - x_ ##p = saved_ ##p ##_x; \ - y_ ##p = saved_ ##p ##_y; \ - p->pDrawable = saved_ ##p ##_drawable; \ - if (p->pCompositeClip) \ - pixman_region_translate (p->pCompositeClip, \ - p->pDrawable->x + x_ ##p, \ - p->pDrawable->y + y_ ##p); \ - glamor_put_sub_pixmap(sub_ ##p ##_pixmap, p ##_pixmap, \ - x_ ##p + p ##_x_off + p->pDrawable->x, \ - y_ ##p + p ##_y_off + p->pDrawable->y, \ - width, height, access); \ - }} while(0) - if (mask && mask->pDrawable) - PUT_SUB_PICTURE(mask, GLAMOR_ACCESS_RO); - if (source->pDrawable) - PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO); - PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW); done: return ret; } diff --git a/xorg-server/glamor/glamor_segment.c b/xorg-server/glamor/glamor_segment.c deleted file mode 100644 index 53f7da0cb..000000000 --- a/xorg-server/glamor/glamor_segment.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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) -{ - if (glamor_ddx_fallback_check_pixmap(drawable) && - glamor_ddx_fallback_check_gc(gc)) { - return FALSE; - } - - miPolySegment(drawable, gc, nseg, seg); - - return TRUE; -} - -void -glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg, - xSegment *seg) -{ - miPolySegment(drawable, gc, nseg, seg); -} diff --git a/xorg-server/glamor/glamor_segs.c b/xorg-server/glamor/glamor_segs.c new file mode 100644 index 000000000..ff0daef10 --- /dev/null +++ b/xorg-server/glamor/glamor_segs.c @@ -0,0 +1,188 @@ +/* + * 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_program.h" +#include "glamor_transform.h" +#include "glamor_prepare.h" + +static const glamor_facet glamor_facet_poly_segment = { + .name = "poly_segment", + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = (" vec2 pos = vec2(0.0,0.0);\n" + GLAMOR_POS(gl_Position, primitive.xy)), +}; + +static Bool +glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv; + glamor_program *prog; + int off_x, off_y; + xSegment *v; + char *vbo_offset; + int box_x, box_y; + int add_last; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + add_last = 0; + if (gc->capStyle != CapNotLast) + add_last = 1; + + glamor_make_current(glamor_priv); + + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_segment_program, + &glamor_facet_poly_segment); + + if (!prog) + goto bail_ctx; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, + (nseg << add_last) * sizeof (xSegment), + &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, + sizeof(DDXPointRec), vbo_offset); + + if (add_last) { + int i, j; + for (i = 0, j=0; i < nseg; i++) { + v[j++] = segs[i]; + v[j].x1 = segs[i].x2; + v[j].y1 = segs[i].y2; + v[j].x2 = segs[i].x2+1; + v[j].y2 = segs[i].y2; + j++; + } + } else + memcpy(v, segs, nseg * sizeof (xSegment)); + + 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_LINES, 0, nseg << (1 + add_last)); + } + } + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + return TRUE; +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); +bail: + return FALSE; +} + +static Bool +glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + if (gc->lineWidth != 0) + return FALSE; + + switch (gc->lineStyle) { + case LineSolid: + return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs); + case LineOnOffDash: + return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs); + case LineDoubleDash: + if (gc->fillStyle == FillTiled) + return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs); + else + return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs); + default: + return FALSE; + } +} + +static void +glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + glamor_fallback("to %p (%c)\n", drawable, + glamor_get_drawable_location(drawable)); + + if (gc->lineWidth == 0) { + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) { + fbPolySegment(drawable, gc, nseg, segs); + } + glamor_finish_access_gc(gc); + glamor_finish_access(drawable); + } else + miPolySegment(drawable, gc, nseg, segs); +} + +void +glamor_poly_segment(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + if (glamor_poly_segment_gl(drawable, gc, nseg, segs)) + return; + + glamor_poly_segment_bail(drawable, gc, nseg, segs); +} + +Bool +glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + if (glamor_poly_segment_gl(drawable, gc, nseg, segs)) + return TRUE; + + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_gc(gc)) + { + return FALSE; + } + + glamor_poly_segment_bail(drawable, gc, nseg, segs); + return TRUE; +} + diff --git a/xorg-server/glamor/glamor_spans.c b/xorg-server/glamor/glamor_spans.c index 46ba6c38f..582d11df3 100644 --- a/xorg-server/glamor/glamor_spans.c +++ b/xorg-server/glamor/glamor_spans.c @@ -326,9 +326,6 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src, glamor_make_current(glamor_priv); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glamor_pixmap_loop(pixmap_priv, box_x, box_y) { diff --git a/xorg-server/glamor/glamor_sync.c b/xorg-server/glamor/glamor_sync.c new file mode 100644 index 000000000..d3d64a925 --- /dev/null +++ b/xorg-server/glamor/glamor_sync.c @@ -0,0 +1,117 @@ +/* + * 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 "misyncshm.h" +#include "misyncstr.h" + +#if XSYNC +/* + * This whole file exists to wrap a sync fence trigger operation so + * that we can flush GL to provide serialization between the server + * and the shm fence client + */ + +static DevPrivateKeyRec glamor_sync_fence_key; + +struct glamor_sync_fence { + SyncFenceSetTriggeredFunc set_triggered; +}; + +static inline struct glamor_sync_fence * +glamor_get_sync_fence(SyncFence *fence) +{ + return (struct glamor_sync_fence *) dixLookupPrivate(&fence->devPrivates, &glamor_sync_fence_key); +} + +static void +glamor_sync_fence_set_triggered (SyncFence *fence) +{ + ScreenPtr screen = fence->pScreen; + glamor_screen_private *glamor = glamor_get_screen_private(screen); + struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence); + + /* Flush pending rendering operations */ + glamor_make_current(glamor); + glFinish(); + + fence->funcs.SetTriggered = glamor_fence->set_triggered; + fence->funcs.SetTriggered(fence); + glamor_fence->set_triggered = fence->funcs.SetTriggered; + fence->funcs.SetTriggered = glamor_sync_fence_set_triggered; +} + +static void +glamor_sync_create_fence(ScreenPtr screen, + SyncFence *fence, + Bool initially_triggered) +{ + glamor_screen_private *glamor = glamor_get_screen_private(screen); + SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); + struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence); + + screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence; + screen_funcs->CreateFence(screen, fence, initially_triggered); + glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence; + screen_funcs->CreateFence = glamor_sync_create_fence; + + glamor_fence->set_triggered = fence->funcs.SetTriggered; + fence->funcs.SetTriggered = glamor_sync_fence_set_triggered; +} +#endif + +Bool +glamor_sync_init(ScreenPtr screen) +{ +#if XSYNC + glamor_screen_private *glamor = glamor_get_screen_private(screen); + SyncScreenFuncsPtr screen_funcs; + + if (!dixPrivateKeyRegistered(&glamor_sync_fence_key)) { + if (!dixRegisterPrivateKey(&glamor_sync_fence_key, + PRIVATE_SYNC_FENCE, + sizeof (struct glamor_sync_fence))) + return FALSE; + } + + if (!miSyncShmScreenInit(screen)) + return FALSE; + + screen_funcs = miSyncGetScreenFuncs(screen); + glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence; + screen_funcs->CreateFence = glamor_sync_create_fence; +#endif + return TRUE; +} + +void +glamor_sync_close(ScreenPtr screen) +{ +#if XSYNC + glamor_screen_private *glamor = glamor_get_screen_private(screen); + SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); + + if (screen_funcs) + screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence; +#endif +} diff --git a/xorg-server/glamor/glamor_text.c b/xorg-server/glamor/glamor_text.c index 6e02b9aa8..59cd0fdc8 100644 --- a/xorg-server/glamor/glamor_text.c +++ b/xorg-server/glamor/glamor_text.c @@ -293,9 +293,6 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc, glDisable(GL_COLOR_LOGIC_OP); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - *final_pos = x; return TRUE; @@ -493,9 +490,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc, (void) glamor_text(drawable, gc, glamor_font, prog, x, y, count, chars, charinfo, sixteen); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - return TRUE; bail: diff --git a/xorg-server/glamor/glamor_tile.c b/xorg-server/glamor/glamor_tile.c deleted file mode 100644 index 4e479763e..000000000 --- a/xorg-server/glamor/glamor_tile.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright © 2009 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. - * - * Authors: - * Eric Anholt - * Zhigang Gong - * - */ - -#include "glamor_priv.h" - -/** @file glamor_tile.c - * - * Implements the basic fill-with-a-tile support used by multiple GC ops. - */ - -void -glamor_init_tile_shader(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv; - const char *tile_vs = - "attribute vec4 v_position;\n" - "attribute vec4 v_texcoord0;\n" - "varying vec2 tile_texture;\n" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - " tile_texture = v_texcoord0.xy;\n" - "}\n"; - const char *tile_fs = - GLAMOR_DEFAULT_PRECISION - "varying vec2 tile_texture;\n" - "uniform sampler2D sampler;\n" - "uniform vec2 wh;" - "void main()\n" - "{\n" - " vec2 rel_tex;" - " rel_tex = tile_texture * wh; \n" - " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n" - " gl_FragColor = texture2D(sampler, rel_tex);\n" - "}\n"; - GLint fs_prog, vs_prog; - GLint sampler_uniform_location; - - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - glamor_priv->tile_prog = glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs); - glAttachShader(glamor_priv->tile_prog, vs_prog); - glAttachShader(glamor_priv->tile_prog, fs_prog); - - glBindAttribLocation(glamor_priv->tile_prog, - GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(glamor_priv->tile_prog, - GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(screen, glamor_priv->tile_prog, "tile"); - - sampler_uniform_location = - glGetUniformLocation(glamor_priv->tile_prog, "sampler"); - glUseProgram(glamor_priv->tile_prog); - glUniform1i(sampler_uniform_location, 0); - - glamor_priv->tile_wh = - glGetUniformLocation(glamor_priv->tile_prog, "wh"); -} - -void -glamor_fini_tile_shader(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv; - - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - glDeleteProgram(glamor_priv->tile_prog); -} - -static void -_glamor_tile(PixmapPtr pixmap, PixmapPtr tile, - int x, int y, int width, int height, int tile_x, int tile_y) -{ - ScreenPtr screen = pixmap->drawable.pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - int tile_x1 = tile_x; - int tile_x2 = tile_x + width; - int tile_y1 = tile_y; - int tile_y2 = tile_y + height; - float vertices[8]; - float source_texcoords[8]; - GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; - glamor_pixmap_private *src_pixmap_priv; - glamor_pixmap_private *dst_pixmap_priv; - float wh[4]; - - src_pixmap_priv = glamor_get_pixmap_private(tile); - dst_pixmap_priv = glamor_get_pixmap_private(pixmap); - - glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); - pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); - pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); - glamor_make_current(glamor_priv); - glUseProgram(glamor_priv->tile_prog); - - glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv); - glUniform2fv(glamor_priv->tile_wh, 1, wh); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glamor_set_repeat_normalize_tcoords - (src_pixmap_priv, RepeatNormal, - src_xscale, src_yscale, - tile_x1, tile_y1, - tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords); - - glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, - 2 * sizeof(float), source_texcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - - glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale, - x1, y1, - x2, y2, glamor_priv->yInverted, vertices); - - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, - 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; -} - -Bool -glamor_tile(PixmapPtr pixmap, PixmapPtr tile, - int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, int tile_x, int tile_y) -{ - ScreenPtr screen = pixmap->drawable.pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_pixmap_private *dst_pixmap_priv; - glamor_pixmap_private *src_pixmap_priv; - - dst_pixmap_priv = glamor_get_pixmap_private(pixmap); - src_pixmap_priv = glamor_get_pixmap_private(tile); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) - return FALSE; - - if (glamor_priv->tile_prog == 0) { - glamor_fallback("Tiling unsupported\n"); - goto fail; - } - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { - /* XXX dynamic uploading candidate. */ - glamor_fallback("Non-texture tile pixmap\n"); - goto fail; - } - - if (!glamor_set_planemask(pixmap, planemask)) { - glamor_fallback("unsupported planemask %lx\n", planemask); - goto fail; - } - - glamor_make_current(glamor_priv); - if (!glamor_set_alu(screen, alu)) { - glamor_fallback("unsupported alu %x\n", alu); - goto fail; - } - - if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE - || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - glamor_pixmap_clipped_regions *clipped_dst_regions; - int n_dst_region, i, j, k; - BoxRec box; - RegionRec region; - - box.x1 = x; - box.y1 = y; - box.x2 = x + width; - box.y2 = y + height; - RegionInitBoxes(®ion, &box, 1); - clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv, - ®ion, - &n_dst_region, 0, - 0, 0); - for (i = 0; i < n_dst_region; i++) { - int n_src_region; - glamor_pixmap_clipped_regions *clipped_src_regions; - BoxPtr current_boxes; - int n_current_boxes; - - SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, - clipped_dst_regions[i].block_idx); - - if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - RegionTranslate(clipped_dst_regions[i].region, - tile_x - x, tile_y - y); - DEBUGF("tiled a large src pixmap. %dx%d \n", - tile->drawable.width, tile->drawable.height); - clipped_src_regions = - glamor_compute_clipped_regions(src_pixmap_priv, - clipped_dst_regions[i]. - region, &n_src_region, 1, 0, - 0); - DEBUGF("got %d src regions %d \n", n_src_region); - for (j = 0; j < n_src_region; j++) { - - SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, - clipped_src_regions[j].block_idx); - - RegionTranslate(clipped_src_regions[j].region, - x - tile_x, y - tile_y); - current_boxes = RegionRects(clipped_src_regions[j].region); - n_current_boxes = - RegionNumRects(clipped_src_regions[j].region); - for (k = 0; k < n_current_boxes; k++) { - DEBUGF - ("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n", - current_boxes[k].x1, current_boxes[k].y1, - current_boxes[k].x2 - current_boxes[k].x1, - current_boxes[k].y2 - current_boxes[k].y1, - clipped_dst_regions[i].block_idx, - clipped_src_regions[j].block_idx, - (tile_x + (current_boxes[k].x1 - x)), - tile_y + (current_boxes[k].y1 - y)); - - _glamor_tile(pixmap, tile, - current_boxes[k].x1, current_boxes[k].y1, - current_boxes[k].x2 - current_boxes[k].x1, - current_boxes[k].y2 - current_boxes[k].y1, - (tile_x + (current_boxes[k].x1 - x)), - (tile_y + (current_boxes[k].y1 - y))); - } - - RegionDestroy(clipped_src_regions[j].region); - } - free(clipped_src_regions); - } - else { - current_boxes = RegionRects(clipped_dst_regions[i].region); - n_current_boxes = RegionNumRects(clipped_dst_regions[i].region); - for (k = 0; k < n_current_boxes; k++) { - _glamor_tile(pixmap, tile, - current_boxes[k].x1, current_boxes[k].y1, - current_boxes[k].x2 - current_boxes[k].x1, - current_boxes[k].y2 - current_boxes[k].y1, - (tile_x + (current_boxes[k].x1 - x)), - (tile_y + (current_boxes[k].y1 - y))); - } - } - RegionDestroy(clipped_dst_regions[i].region); - } - free(clipped_dst_regions); - RegionUninit(®ion); - } - else - _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y); - - glamor_set_alu(screen, GXcopy); - return TRUE; - fail: - return FALSE; - -} diff --git a/xorg-server/glamor/glamor_transfer.c b/xorg-server/glamor/glamor_transfer.c index ad875c962..891415565 100644 --- a/xorg-server/glamor/glamor_transfer.c +++ b/xorg-server/glamor/glamor_transfer.c @@ -72,9 +72,6 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, glamor_make_current(glamor_priv); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel); @@ -90,27 +87,14 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, while (nbox--) { /* compute drawable coordinates */ - int x1 = boxes->x1 + dx_dst; - int x2 = boxes->x2 + dx_dst; - int y1 = boxes->y1 + dy_dst; - int y2 = boxes->y2 + dy_dst; + int x1 = MAX(boxes->x1 + dx_dst, box->x1); + int x2 = MIN(boxes->x2 + dx_dst, box->x2); + int y1 = MAX(boxes->y1 + dy_dst, box->y1); + int y2 = MIN(boxes->y2 + dy_dst, box->y2); boxes++; - if (x1 < box->x1) - x1 = box->x1; - if (box->x2 < x2) - x2 = box->x2; - - if (x2 <= x1) - continue; - - if (y1 < box->y1) - y1 = box->y1; - if (box->y2 < y2) - y2 = box->y2; - - if (y2 <= y1) + if (x2 <= x1 || y2 <= y1) continue; glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src); @@ -195,26 +179,14 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, while (nbox--) { /* compute drawable coordinates */ - int x1 = boxes->x1 + dx_src; - int x2 = boxes->x2 + dx_src; - int y1 = boxes->y1 + dy_src; - int y2 = boxes->y2 + dy_src; + int x1 = MAX(boxes->x1 + dx_src, box->x1); + int x2 = MIN(boxes->x2 + dx_src, box->x2); + int y1 = MAX(boxes->y1 + dy_src, box->y1); + int y2 = MIN(boxes->y2 + dy_src, box->y2); boxes++; - if (x1 < box->x1) - x1 = box->x1; - if (box->x2 < x2) - x2 = box->x2; - - if (y1 < box->y1) - y1 = box->y1; - if (box->y2 < y2) - y2 = box->y2; - - if (x2 <= x1) - continue; - if (y2 <= y1) + if (x2 <= x1 || y2 <= y1) continue; glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst); diff --git a/xorg-server/glamor/glamor_transform.c b/xorg-server/glamor/glamor_transform.c index d6ba56421..c1df56018 100644 --- a/xorg-server/glamor/glamor_transform.c +++ b/xorg-server/glamor/glamor_transform.c @@ -198,6 +198,64 @@ glamor_set_tiled(PixmapPtr pixmap, size_uniform); } +static PixmapPtr +glamor_get_stipple_pixmap(GCPtr gc) +{ + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + ScreenPtr screen = gc->pScreen; + PixmapPtr bitmap; + PixmapPtr pixmap; + GCPtr scratch_gc; + ChangeGCVal changes[2]; + + if (gc_priv->stipple) + return gc_priv->stipple; + + bitmap = gc->stipple; + if (!bitmap) + goto bail; + + pixmap = glamor_create_pixmap(screen, + bitmap->drawable.width, + bitmap->drawable.height, + 8, GLAMOR_CREATE_NO_LARGE); + if (!pixmap) + goto bail; + + scratch_gc = GetScratchGC(8, screen); + if (!scratch_gc) + goto bail_pixmap; + + changes[0].val = 0xff; + changes[1].val = 0x00; + if (ChangeGC(NullClient, scratch_gc, + GCForeground|GCBackground, changes) != Success) + goto bail_gc; + ValidateGC(&pixmap->drawable, scratch_gc); + + (*scratch_gc->ops->CopyPlane)(&bitmap->drawable, + &pixmap->drawable, + scratch_gc, + 0, 0, + bitmap->drawable.width, + bitmap->drawable.height, + 0, 0, 0x1); + + FreeScratchGC(scratch_gc); + gc_priv->stipple = pixmap; + + glamor_track_stipple(gc); + + return pixmap; + +bail_gc: + FreeScratchGC(scratch_gc); +bail_pixmap: + glamor_destroy_pixmap(pixmap); +bail: + return NULL; +} + Bool glamor_set_stippled(PixmapPtr pixmap, GCPtr gc, @@ -205,11 +263,19 @@ glamor_set_stippled(PixmapPtr pixmap, GLint offset_uniform, GLint size_uniform) { - if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform)) + PixmapPtr stipple; + + stipple = glamor_get_stipple_pixmap(gc); + if (!stipple) return FALSE; - if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform)) + if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform)) return FALSE; - return TRUE; + return glamor_set_texture(pixmap, + stipple, + -gc->patOrg.x, + -gc->patOrg.y, + offset_uniform, + size_uniform); } diff --git a/xorg-server/glamor/glamor_trapezoid.c b/xorg-server/glamor/glamor_trapezoid.c index 4aba469af..d61d11f79 100644 --- a/xorg-server/glamor/glamor_trapezoid.c +++ b/xorg-server/glamor/glamor_trapezoid.c @@ -908,7 +908,6 @@ _glamor_trapezoids_with_shader(CARD8 op, clipped_vtx_tmp[5] = clipped_vtx[(i + 2) * 2 + 1]; glamor_set_normalize_tri_vcoords(dst_xscale, dst_yscale, clipped_vtx_tmp, - glamor_priv->yInverted, vertices); DEBUGF("vertices of triangle: (%f X %f), (%f X %f), " "(%f X %f)\n", vertices[0], vertices[1], @@ -920,14 +919,12 @@ _glamor_trapezoids_with_shader(CARD8 op, glamor_set_transformed_normalize_tri_tcoords (source_pixmap_priv, src_matrix, src_xscale, src_yscale, clipped_vtx_tmp, - glamor_priv->yInverted, source_texcoords); + source_texcoords); } else { glamor_set_normalize_tri_tcoords(src_xscale, src_yscale, clipped_vtx_tmp, - glamor_priv-> - yInverted, source_texcoords); } @@ -1392,12 +1389,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, } /* First, clear all to zero */ - if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width, - pixmap_priv->base.pixmap->drawable.height, - GXclear, 0xFFFFFFFF, 0)) { - DEBUGF("glamor_solid failed, fallback\n"); - return FALSE; - } + glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width, + pixmap_priv->base.pixmap->drawable.height, 0); glamor_make_current(glamor_priv); @@ -1443,11 +1436,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, miTrapezoidBounds(1, ptrap, &one_trap_bound); 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), + glamor_set_tcoords_ext((one_trap_bound.x1), (one_trap_bound.y1), (one_trap_bound.x2), (one_trap_bound.y2), - glamor_priv->yInverted, vertices, stride); + vertices, stride); DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0], vertices[1], vertices[1 * stride], vertices[1 * stride + 1], @@ -1467,8 +1458,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, one_trap_bound.y1, one_trap_bound.x2, one_trap_bound.y2, - glamor_priv->yInverted, vertices, - stride); + vertices, stride); DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0], vertices[1], vertices[1 * stride], vertices[1 * stride + 1], diff --git a/xorg-server/glamor/glamor_utils.c b/xorg-server/glamor/glamor_utils.c new file mode 100644 index 000000000..f06896096 --- /dev/null +++ b/xorg-server/glamor/glamor_utils.c @@ -0,0 +1,79 @@ +/* + * 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" + +void +glamor_solid_boxes(PixmapPtr pixmap, + BoxPtr box, int nbox, unsigned long fg_pixel) +{ + DrawablePtr drawable = &pixmap->drawable; + GCPtr gc; + xRectangle *rect; + int n; + + rect = malloc(nbox * sizeof (xRectangle)); + if (!rect) + return; + for (n = 0; n < nbox; n++) { + rect[n].x = box[n].x1; + rect[n].y = box[n].y1; + rect[n].width = box[n].x2 - box[n].x1; + rect[n].height = box[n].y2 - box[n].y1; + } + + gc = GetScratchGC(drawable->depth, drawable->pScreen); + if (gc) { + ChangeGCVal vals[1]; + + vals[0].val = fg_pixel; + ChangeGC(NullClient, gc, GCForeground, vals); + ValidateGC(drawable, gc); + gc->ops->PolyFillRect(drawable, gc, nbox, rect); + FreeScratchGC(gc); + } + free(rect); +} + +void +glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, + unsigned long fg_pixel) +{ + DrawablePtr drawable = &pixmap->drawable; + GCPtr gc; + ChangeGCVal vals[1]; + xRectangle rect; + + vals[0].val = fg_pixel; + gc = GetScratchGC(drawable->depth, drawable->pScreen); + if (!gc) + return; + ChangeGC(NullClient, gc, GCForeground, vals); + ValidateGC(drawable, gc); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + gc->ops->PolyFillRect(drawable, gc, 1, &rect); + FreeScratchGC(gc); +} + diff --git a/xorg-server/glamor/glamor_utils.h b/xorg-server/glamor/glamor_utils.h index 4c1581ef5..c15d17ca3 100644 --- a/xorg-server/glamor/glamor_utils.h +++ b/xorg-server/glamor/glamor_utils.h @@ -32,6 +32,8 @@ #ifndef __GLAMOR_UTILS_H__ #define __GLAMOR_UTILS_H__ +#include "glamor_prepare.h" + #define v_from_x_coord_x(_xscale_, _x_) ( 2 * (_x_) * (_xscale_) - 1.0) #define v_from_x_coord_y(_yscale_, _y_) (-2 * (_y_) * (_yscale_) + 1.0) #define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0) @@ -311,21 +313,17 @@ } while(0) #define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \ - texcoord, yInverted) \ + texcoord) \ do { \ (texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \ - if (_X_LIKELY(yInverted)) \ - (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\ - else \ - (texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \ + (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_); \ DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \ (texcoord)[1]); \ } while(0) #define glamor_set_transformed_point(priv, matrix, xscale, \ yscale, texcoord, \ - x, y, \ - yInverted) \ + x, y) \ do { \ float tx, ty; \ int fbo_x_off, fbo_y_off; \ @@ -337,10 +335,7 @@ tx += fbo_x_off; \ ty += fbo_y_off; \ (texcoord)[0] = t_from_x_coord_x(xscale, tx); \ - if (_X_LIKELY(yInverted)) \ - (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \ - else \ - (texcoord)[1] = t_from_x_coord_y(yscale, ty); \ + (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \ DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \ } while(0) @@ -349,18 +344,14 @@ xscale, \ yscale, \ vtx, \ - yInverted, \ texcoords) \ do { \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords, (vtx)[0], (vtx)[1], \ - yInverted); \ + texcoords, (vtx)[0], (vtx)[1]); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords+2, (vtx)[2], (vtx)[3], \ - yInverted); \ + texcoords+2, (vtx)[2], (vtx)[3]); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords+4, (vtx)[4], (vtx)[5], \ - yInverted); \ + texcoords+4, (vtx)[4], (vtx)[5]); \ } while (0) #define glamor_set_transformed_normalize_tcoords_ext( priv, \ @@ -368,21 +359,17 @@ xscale, \ yscale, \ tx1, ty1, tx2, ty2, \ - yInverted, texcoords, \ + texcoords, \ stride) \ do { \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords, tx1, ty1, \ - yInverted); \ + texcoords, tx1, ty1); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords + 1 * stride, tx2, ty1, \ - yInverted); \ + texcoords + 1 * stride, tx2, ty1); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords + 2 * stride, tx2, ty2, \ - yInverted); \ + texcoords + 2 * stride, tx2, ty2); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords + 3 * stride, tx1, ty2, \ - yInverted); \ + texcoords + 3 * stride, tx1, ty2); \ } while (0) #define glamor_set_transformed_normalize_tcoords( priv, \ @@ -390,35 +377,31 @@ xscale, \ yscale, \ tx1, ty1, tx2, ty2, \ - yInverted, texcoords) \ + texcoords) \ do { \ glamor_set_transformed_normalize_tcoords_ext( priv, \ matrix, \ xscale, \ yscale, \ tx1, ty1, tx2, ty2, \ - yInverted, texcoords, \ + texcoords, \ 2); \ } while (0) #define glamor_set_normalize_tri_tcoords(xscale, \ yscale, \ vtx, \ - yInverted, \ texcoords) \ do { \ _glamor_set_normalize_tpoint(xscale, yscale, \ (vtx)[0], (vtx)[1], \ - texcoords, \ - yInverted); \ + texcoords); \ _glamor_set_normalize_tpoint(xscale, yscale, \ (vtx)[2], (vtx)[3], \ - texcoords+2, \ - yInverted); \ + texcoords+2); \ _glamor_set_normalize_tpoint(xscale, yscale, \ (vtx)[4], (vtx)[5], \ - texcoords+4, \ - yInverted); \ + texcoords+4); \ } while (0) #define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \ @@ -428,14 +411,13 @@ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ - yInverted, \ texcoords, \ stride) \ do { \ if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) { \ glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \ yscale, _x1_, _y1_, \ - _x2_, _y2_, yInverted, \ + _x2_, _y2_, \ texcoords, stride); \ } else { \ float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \ @@ -462,13 +444,13 @@ DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \ ttx2, tty2, ttx3, tty3, ttx4, tty4); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \ - texcoords, yInverted); \ + texcoords); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \ - texcoords + 1 * stride, yInverted); \ + texcoords + 1 * stride); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \ - texcoords + 2 * stride, yInverted); \ + texcoords + 2 * stride); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \ - texcoords + 3 * stride, yInverted); \ + texcoords + 3 * stride); \ } \ } while (0) @@ -479,7 +461,6 @@ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ - yInverted, \ texcoords) \ do { \ glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \ @@ -489,14 +470,13 @@ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ - yInverted, \ texcoords, \ 2); \ } while (0) #define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \ ty1, tx2, ty2, \ - yInverted, vertices, stride) \ + vertices, stride) \ do { \ /* vertices may be write-only, so we use following \ * temporary variable. */ \ @@ -505,21 +485,15 @@ (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \ (vertices)[2 * stride] = _t2_; \ (vertices)[3 * stride] = _t0_; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \ - (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2);\ - } \ - else { \ - (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1); \ - (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);\ - } \ + (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \ + (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2); \ (vertices)[1 * stride + 1] = _t1_; \ (vertices)[3 * stride + 1] = _t5_; \ } while(0) #define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices, stride) \ + vertices, stride) \ do { \ if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \ float tx1, tx2, ty1, ty2; \ @@ -530,26 +504,26 @@ ty1 = y1 + fbo_y_off; \ ty2 = y2 + fbo_y_off; \ _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ - tx2, ty2, yInverted, vertices, \ + tx2, ty2, vertices, \ stride); \ } else \ _glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \ - x2, y2, yInverted, vertices, stride);\ + x2, y2, vertices, stride); \ } while(0) #define glamor_set_normalize_tcoords(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices) \ + vertices) \ do { \ glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices, 2); \ + vertices, 2); \ } while(0) #define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ - yInverted, vertices, stride)\ + vertices, stride) \ do { \ if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \ float tx1, tx2, ty1, ty2; \ @@ -564,130 +538,99 @@ _x1_, _y1_, _x2_, _y2_); \ } \ _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ - tx2, ty2, yInverted, vertices, \ + tx2, ty2, vertices, \ stride); \ } else \ _glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \ - _x2_, _y2_, yInverted, vertices, \ + _x2_, _y2_, vertices, \ stride); \ } while(0) #define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ - yInverted, vertices) \ + vertices) \ do { \ glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ - yInverted, vertices, 2); \ + vertices, 2); \ } while(0) #define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices) \ + vertices) \ do { \ (vertices)[0] = t_from_x_coord_x(xscale, x1); \ (vertices)[2] = t_from_x_coord_x(xscale, x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \ - (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \ - } \ - else { \ - (vertices)[1] = t_from_x_coord_y(yscale, y1); \ - (vertices)[7] = t_from_x_coord_y(yscale, y2); \ - } \ + (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) -#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \ - yInverted, vertices) \ +#define glamor_set_tcoords(x1, y1, x2, y2, vertices) \ do { \ (vertices)[0] = (x1); \ (vertices)[2] = (x2); \ (vertices)[4] = (vertices)[2]; \ (vertices)[6] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = (y1); \ - (vertices)[5] = (y2); \ - } \ - else { \ - (vertices)[1] = height - (y2); \ - (vertices)[5] = height - (y1); \ - } \ + (vertices)[1] = (y1); \ + (vertices)[5] = (y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[7] = (vertices)[5]; \ } while(0) -#define glamor_set_tcoords_ext(width, height, x1, y1, x2, y2, \ - yInverted, vertices, stride) \ +#define glamor_set_tcoords_ext(x1, y1, x2, y2, vertices, stride) \ do { \ (vertices)[0] = (x1); \ (vertices)[1*stride] = (x2); \ (vertices)[2*stride] = (vertices)[1*stride]; \ (vertices)[3*stride] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = (y1); \ - (vertices)[2*stride + 1] = (y2); \ - } \ - else { \ - (vertices)[1] = height - (y2); \ - (vertices)[2*stride + 1] = height - (y1); \ - } \ + (vertices)[1] = (y1); \ + (vertices)[2*stride + 1] = (y2); \ (vertices)[1*stride + 1] = (vertices)[1]; \ (vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \ } while(0) #define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \ - yInverted, vertices) \ + vertices) \ do { \ (vertices)[0] = v_from_x_coord_x(xscale, x); \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \ - } else { \ - (vertices)[1] = v_from_x_coord_y(yscale, y); \ - } \ + (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \ } while(0) #define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \ - yInverted, vertices) \ + vertices) \ do { \ glamor_set_normalize_one_vcoord(xscale, yscale, \ (vtx)[0], (vtx)[1], \ - yInverted, vertices); \ + vertices); \ glamor_set_normalize_one_vcoord(xscale, yscale, \ (vtx)[2], (vtx)[3], \ - yInverted, vertices+2); \ + vertices+2); \ glamor_set_normalize_one_vcoord(xscale, yscale, \ (vtx)[4], (vtx)[5], \ - yInverted, vertices+4); \ + vertices+4); \ } while(0) -#define glamor_set_tcoords_tri_strip(width, height, x1, y1, x2, y2, \ - yInverted, vertices) \ +#define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices) \ do { \ (vertices)[0] = (x1); \ (vertices)[2] = (x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = (y1); \ - (vertices)[7] = (y2); \ - } \ - else { \ - (vertices)[1] = height - (y2); \ - (vertices)[7] = height - (y1); \ - } \ + (vertices)[1] = (y1); \ + (vertices)[7] = (y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) #define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices, stride) \ + vertices, stride) \ do { \ int fbo_x_off, fbo_y_off; \ /* vertices may be write-only, so we use following \ @@ -699,29 +642,22 @@ x2 + fbo_x_off); \ (vertices)[2 * stride] = _t2_; \ (vertices)[3 * stride] = _t0_; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \ - y1 + fbo_y_off); \ - (vertices)[2 * stride + 1] = _t5_ = \ - v_from_x_coord_y_inverted(yscale, \ - y2 + fbo_y_off); \ - } \ - else { \ - (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \ - (vertices)[2 * stride + 1] = _t5_ = v_from_x_coord_y(yscale, \ - y2 + fbo_y_off); \ - } \ + (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \ + y1 + fbo_y_off); \ + (vertices)[2 * stride + 1] = _t5_ = \ + v_from_x_coord_y_inverted(yscale, \ + y2 + fbo_y_off); \ (vertices)[1 * stride + 1] = _t1_; \ (vertices)[3 * stride + 1] = _t5_; \ } while(0) #define glamor_set_normalize_vcoords(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices) \ + vertices) \ do { \ glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices, 2); \ + vertices, 2); \ } while(0) #define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \ @@ -736,44 +672,30 @@ #define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices) \ + vertices) \ do { \ (vertices)[0] = v_from_x_coord_x(xscale, x1); \ (vertices)[2] = v_from_x_coord_x(xscale, x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \ - (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \ - } \ - else { \ - (vertices)[1] = v_from_x_coord_y(yscale, y1); \ - (vertices)[7] = v_from_x_coord_y(yscale, y2); \ - } \ + (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) #define glamor_set_normalize_pt(xscale, yscale, x, y, \ - yInverted, pt) \ + pt) \ do { \ (pt)[0] = t_from_x_coord_x(xscale, x); \ - if (_X_LIKELY(yInverted)) { \ - (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \ - } else { \ - (pt)[1] = t_from_x_coord_y(yscale, y); \ - } \ + (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \ } while(0) #define glamor_set_circle_centre(width, height, x, y, \ - yInverted, c) \ + c) \ do { \ (c)[0] = (float)x; \ - if (_X_LIKELY(yInverted)) { \ - (c)[1] = (float)y; \ - } else { \ - (c)[1] = (float)height - (float)y; \ - } \ + (c)[1] = (float)y; \ } while(0) inline static void diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c index 369b02b61..68a06a413 100644 --- a/xorg-server/glamor/glamor_xv.c +++ b/xorg-server/glamor/glamor_xv.c @@ -36,12 +36,10 @@ #include #endif -#include "xf86xv.h" -#define GLAMOR_FOR_XORG #include "glamor_priv.h" #include -#include "fourcc.h" +#include "../hw/xfree86/common/fourcc.h" /* Reference color space transform data */ typedef struct tagREF_TRANSFORM { float RefLuma; @@ -90,7 +88,28 @@ static const char *xv_ps = GLAMOR_DEFAULT_PRECISION "gl_FragColor = temp1;\n" "}\n"; -void +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +XvAttributeRec glamor_xv_attributes[] = { + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_BRIGHTNESS"}, + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_CONTRAST"}, + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_SATURATION"}, + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_HUE"}, + {XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE"}, + {0, 0, 0, NULL} +}; +int glamor_xv_num_attributes = ARRAY_SIZE(glamor_xv_attributes) - 1; + +Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue, + glamorColorspace, glamorGamma; + +XvImageRec glamor_xv_images[] = { + XVIMAGE_YV12, + XVIMAGE_I420, +}; +int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images); + +static void glamor_init_xv_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv; @@ -113,43 +132,12 @@ glamor_init_xv_shader(ScreenPtr screen) } #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) -#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) - -static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace, - xvGamma; - -#define NUM_ATTRIBUTES 5 -static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES + 1] = { - {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, - {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"}, - {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}, - {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}, - {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"}, - {0, 0, 0, NULL} -}; - -#define NUM_FORMATS 3 - -static XF86VideoFormatRec Formats[NUM_FORMATS] = { - {15, TrueColor}, {16, TrueColor}, {24, TrueColor} -}; - -#define NUM_IMAGES 2 - -static XF86ImageRec Images[NUM_IMAGES] = { - XVIMAGE_YV12, - XVIMAGE_I420, -}; -static void -glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup) +void +glamor_xv_stop_video(glamor_port_private *port_priv) { - glamor_port_private *port_priv = (glamor_port_private *) data; int i; - if (!cleanup) - return; - for (i = 0; i < 3; i++) { if (port_priv->src_pix[i]) { glamor_destroy_pixmap(port_priv->src_pix[i]); @@ -158,46 +146,42 @@ glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup) } } -static int -glamor_xv_set_port_attribute(ScrnInfoPtr pScrn, - Atom attribute, INT32 value, void *data) +int +glamor_xv_set_port_attribute(glamor_port_private *port_priv, + Atom attribute, INT32 value) { - glamor_port_private *port_priv = (glamor_port_private *) data; - - if (attribute == xvBrightness) + if (attribute == glamorBrightness) port_priv->brightness = ClipValue(value, -1000, 1000); - else if (attribute == xvHue) + else if (attribute == glamorHue) port_priv->hue = ClipValue(value, -1000, 1000); - else if (attribute == xvContrast) + else if (attribute == glamorContrast) port_priv->contrast = ClipValue(value, -1000, 1000); - else if (attribute == xvSaturation) + else if (attribute == glamorSaturation) port_priv->saturation = ClipValue(value, -1000, 1000); - else if (attribute == xvGamma) + else if (attribute == glamorGamma) port_priv->gamma = ClipValue(value, 100, 10000); - else if (attribute == xvColorspace) + else if (attribute == glamorColorspace) port_priv->transform_index = ClipValue(value, 0, 1); else return BadMatch; return Success; } -static int -glamor_xv_get_port_attribute(ScrnInfoPtr pScrn, - Atom attribute, INT32 *value, void *data) +int +glamor_xv_get_port_attribute(glamor_port_private *port_priv, + Atom attribute, INT32 *value) { - glamor_port_private *port_priv = (glamor_port_private *) data; - - if (attribute == xvBrightness) + if (attribute == glamorBrightness) *value = port_priv->brightness; - else if (attribute == xvHue) + else if (attribute == glamorHue) *value = port_priv->hue; - else if (attribute == xvContrast) + else if (attribute == glamorContrast) *value = port_priv->contrast; - else if (attribute == xvSaturation) + else if (attribute == glamorSaturation) *value = port_priv->saturation; - else if (attribute == xvGamma) + else if (attribute == glamorGamma) *value = port_priv->gamma; - else if (attribute == xvColorspace) + else if (attribute == glamorColorspace) *value = port_priv->transform_index; else return BadMatch; @@ -205,20 +189,8 @@ glamor_xv_get_port_attribute(ScrnInfoPtr pScrn, return Success; } -static void -glamor_xv_query_best_size(ScrnInfoPtr pScrn, - Bool motion, - short vid_w, short vid_h, - short drw_w, short drw_h, - unsigned int *p_w, unsigned int *p_h, void *data) -{ - *p_w = drw_w; - *p_h = drw_h; -} - -static int -glamor_xv_query_image_attributes(ScrnInfoPtr pScrn, - int id, +int +glamor_xv_query_image_attributes(int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets) { @@ -258,8 +230,8 @@ static REF_TRANSFORM trans[2] = { {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */ }; -static void -glamor_display_textured_video(glamor_port_private *port_priv) +void +glamor_xv_render(glamor_port_private *port_priv) { ScreenPtr screen = port_priv->pPixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -282,6 +254,9 @@ glamor_display_textured_video(glamor_port_private *port_priv) int ref = port_priv->transform_index; GLint uloc, sampler_loc; + if (!glamor_priv->xv_prog) + glamor_init_xv_shader(screen); + cont = RTFContrast(port_priv->contrast); bright = RTFBrightness(port_priv->brightness); gamma = (float) port_priv->gamma / 1000.0; @@ -385,7 +360,7 @@ glamor_display_textured_video(glamor_port_private *port_priv) dsty, dstx + dstw, dsty + dsth, - glamor_priv->yInverted, vertices); + vertices); glamor_set_normalize_tcoords(src_pixmap_priv[0], src_xscale[0], @@ -394,7 +369,7 @@ glamor_display_textured_video(glamor_port_private *port_priv) srcy, srcx + srcw, srcy + srch, - glamor_priv->yInverted, texcoords); + texcoords); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -405,8 +380,9 @@ glamor_display_textured_video(glamor_port_private *port_priv) DamageDamageRegion(port_priv->pDraw, &port_priv->clip); } -static int -glamor_xv_put_image(ScrnInfoPtr pScrn, +int +glamor_xv_put_image(glamor_port_private *port_priv, + DrawablePtr pDrawable, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, @@ -416,35 +392,15 @@ glamor_xv_put_image(ScrnInfoPtr pScrn, short width, short height, Bool sync, - RegionPtr clipBoxes, void *data, DrawablePtr pDrawable) + RegionPtr clipBoxes) { - ScreenPtr screen = pDrawable->pScreen; - glamor_port_private *port_priv = (glamor_port_private *) data; - INT32 x1, x2, y1, y2; + ScreenPtr pScreen = pDrawable->pScreen; int srcPitch, srcPitch2; - BoxRec dstBox; int top, nlines; int s2offset, s3offset, tmp; s2offset = s3offset = srcPitch2 = 0; - /* Clip */ - x1 = src_x; - x2 = src_x + src_w; - y1 = src_y; - y2 = src_y + src_h; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - if (!xf86XVClipVideoHelper - (&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height)) - return Success; - - if ((x1 >= x2) || (y1 >= y2)) - return Success; - srcPitch = width; srcPitch2 = width >> 1; @@ -457,11 +413,11 @@ glamor_xv_put_image(ScrnInfoPtr pScrn, glamor_destroy_pixmap(port_priv->src_pix[i]); port_priv->src_pix[0] = - glamor_create_pixmap(screen, width, height, 8, 0); + glamor_create_pixmap(pScreen, width, height, 8, 0); port_priv->src_pix[1] = - glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0); + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); port_priv->src_pix[2] = - glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0); + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); port_priv->src_pix_w = width; port_priv->src_pix_h = height; @@ -470,8 +426,8 @@ glamor_xv_put_image(ScrnInfoPtr pScrn, return BadAlloc; } - top = (y1 >> 16) & ~1; - nlines = ((y2 + 0xffff) >> 16) - top; + top = (src_y) & ~1; + nlines = (src_y + height) - top; switch (id) { case FOURCC_YV12: @@ -505,7 +461,7 @@ glamor_xv_put_image(ScrnInfoPtr pScrn, } if (pDrawable->type == DRAWABLE_WINDOW) - port_priv->pPixmap = (*screen->GetWindowPixmap) ((WindowPtr) pDrawable); + port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable); else port_priv->pPixmap = (PixmapPtr) pDrawable; @@ -524,83 +480,30 @@ glamor_xv_put_image(ScrnInfoPtr pScrn, port_priv->w = width; port_priv->h = height; port_priv->pDraw = pDrawable; - glamor_display_textured_video(port_priv); + glamor_xv_render(port_priv); return Success; } -static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = { - { - 0, - "XV_IMAGE", - 8192, 8192, - {1, 1} - } -}; - -XF86VideoAdaptorPtr -glamor_xv_init(ScreenPtr screen, int num_texture_ports) +void +glamor_xv_init_port(glamor_port_private *port_priv) { - glamor_port_private *port_priv; - XF86VideoAdaptorPtr adapt; - int i; + port_priv->brightness = 0; + port_priv->contrast = 0; + port_priv->saturation = 0; + port_priv->hue = 0; + port_priv->gamma = 1000; + port_priv->transform_index = 0; + + REGION_NULL(pScreen, &port_priv->clip); +} - glamor_init_xv_shader(screen); - - adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports * - (sizeof(glamor_port_private) + sizeof(DevUnion))); - if (adapt == NULL) - return NULL; - - xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); - xvContrast = MAKE_ATOM("XV_CONTRAST"); - xvSaturation = MAKE_ATOM("XV_SATURATION"); - xvHue = MAKE_ATOM("XV_HUE"); - xvGamma = MAKE_ATOM("XV_GAMMA"); - xvColorspace = MAKE_ATOM("XV_COLORSPACE"); - - adapt->type = XvWindowMask | XvInputMask | XvImageMask; - adapt->flags = 0; - adapt->name = "GLAMOR Textured Video"; - adapt->nEncodings = 1; - adapt->pEncodings = DummyEncodingGLAMOR; - - adapt->nFormats = NUM_FORMATS; - adapt->pFormats = Formats; - adapt->nPorts = num_texture_ports; - adapt->pPortPrivates = (DevUnion *) (&adapt[1]); - - adapt->pAttributes = Attributes_glamor; - adapt->nAttributes = NUM_ATTRIBUTES; - - port_priv = - (glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]); - adapt->pImages = Images; - adapt->nImages = NUM_IMAGES; - adapt->PutVideo = NULL; - adapt->PutStill = NULL; - adapt->GetVideo = NULL; - adapt->GetStill = NULL; - adapt->StopVideo = glamor_xv_stop_video; - adapt->SetPortAttribute = glamor_xv_set_port_attribute; - adapt->GetPortAttribute = glamor_xv_get_port_attribute; - adapt->QueryBestSize = glamor_xv_query_best_size; - adapt->PutImage = glamor_xv_put_image; - adapt->ReputImage = NULL; - adapt->QueryImageAttributes = glamor_xv_query_image_attributes; - - for (i = 0; i < num_texture_ports; i++) { - glamor_port_private *pPriv = &port_priv[i]; - - pPriv->brightness = 0; - pPriv->contrast = 0; - pPriv->saturation = 0; - pPriv->hue = 0; - pPriv->gamma = 1000; - pPriv->transform_index = 0; - - REGION_NULL(pScreen, &pPriv->clip); - - adapt->pPortPrivates[i].ptr = (void *) (pPriv); - } - return adapt; +void +glamor_xv_core_init(ScreenPtr screen) +{ + glamorBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + glamorContrast = MAKE_ATOM("XV_CONTRAST"); + glamorSaturation = MAKE_ATOM("XV_SATURATION"); + glamorHue = MAKE_ATOM("XV_HUE"); + glamorGamma = MAKE_ATOM("XV_GAMMA"); + glamorColorspace = MAKE_ATOM("XV_COLORSPACE"); } -- cgit v1.2.3