This accelerates poly_fill_rect using GPU-based geometry computation Signed-off-by: Keith Packard <kei...@keithp.com> --- glamor/Makefile.am | 1 + glamor/glamor.c | 1 + glamor/glamor_core.c | 2 +- glamor/glamor_priv.h | 11 +++++ glamor/glamor_rects.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 glamor/glamor_rects.c
diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 746ed40..19c8ddd 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -23,6 +23,7 @@ libglamor_la_SOURCES = \ glamor_render.c \ glamor_gradient.c \ glamor_program.c \ + glamor_rects.c \ glamor_spans.c \ glamor_transform.c \ glamor_trapezoid.c \ diff --git a/glamor/glamor.c b/glamor/glamor.c index b0f1e01..7acc212 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -552,6 +552,7 @@ glamor_release_screen_priv(ScreenPtr screen) glamor_fini_solid_shader(screen); glamor_fini_point_shader(screen); glamor_fini_fillspans_shader(screen); + glamor_fini_polyfillrect_shader(screen); glamor_fini_tile_shader(screen); #ifdef GLAMOR_TRAPEZOID_SHADER glamor_fini_trapezoid_shader(screen); diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 8c10c92..0144890 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -421,7 +421,7 @@ GCOps glamor_gc_ops = { .PolyRectangle = miPolyRectangle, .PolyArc = miPolyArc, .FillPolygon = miFillPolygon, - .PolyFillRect = glamor_poly_fill_rect, + .PolyFillRect = glamor_polyfillrect, .PolyFillArc = miPolyFillArc, .PolyText8 = miPolyText8, .PolyText16 = miPolyText16, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 77a0f24..cb07048 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -232,6 +232,9 @@ typedef struct glamor_screen_private { /* glamor spans shaders */ glamor_program_fill fill_spans_program; + /* glamor rect shaders */ + glamor_program_fill poly_fill_rect_program; + /* vertext/elment_index buffer object for render */ GLuint vbo, ebo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ @@ -993,6 +996,14 @@ glamor_fillspans(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr points, int *widths, int sorted); +/* glamor_rects.c */ +void +glamor_fini_polyfillrect_shader(ScreenPtr screen); + +void +glamor_polyfillrect(DrawablePtr drawable, + GCPtr gc, int nrect, xRectangle *prect); + /* glamor_glyphblt.c */ void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c new file mode 100644 index 0000000..a8cf0ec --- /dev/null +++ b/glamor/glamor_rects.c @@ -0,0 +1,121 @@ +/* + * 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" + +glamor_program fill_rects_progs[4]; + +static const glamor_facet glamor_facet_polyfillrect = { + .name = "poly_fill_rect", + .version = 130, + .vs_vars = "attribute vec4 primitive;\n", + .vs_exec = (" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n" + GLAMOR_POS(gl_Position, (primitive.xy + pos))), +}; + +void +glamor_polyfillrect(DrawablePtr drawable, + GCPtr gc, int nrect, xRectangle *prect) +{ + 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 nbox = RegionNumRects(gc->pCompositeClip); + BoxPtr box = RegionRects(gc->pCompositeClip); + int off_x, off_y; + GLshort *v; + char *vbo_offset; + int box_x, box_y; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + glamor_get_context(glamor_priv); + + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_fill_rect_program, + &glamor_facet_polyfillrect); + + if (!prog) + goto bail; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, nrect * (4 * sizeof (GLshort)), &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE, + 4 * sizeof (GLshort), vbo_offset); + + memcpy(v, prect, nrect * sizeof (xRectangle)); + + glamor_put_vbo_space(screen); + + glEnable(GL_SCISSOR_TEST); + + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, prog->matrix_uniform, &off_x, &off_y); + + nbox = RegionNumRects(gc->pCompositeClip); + box = RegionRects(gc->pCompositeClip); + + while (nbox--) { + glScissor(box->x1 + off_x, + box->y1 + off_y, + box->x2 - box->x1, + box->y2 - box->y1); + box++; + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect); + } + } + + glDisable(GL_SCISSOR_TEST); + glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + glamor_put_context(glamor_priv); + return; +bail: + glamor_fallback("to %p (%c)\n", drawable, + glamor_get_drawable_location(drawable)); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) { + fbPolyFillRect(drawable, gc, nrect, prect); + } + glamor_finish_access_gc(gc); + glamor_finish_access(drawable); +} + +void +glamor_fini_polyfillrect_shader(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + glamor_delete_program_fill(screen, &glamor_priv->poly_fill_rect_program); +} + -- 1.9.0 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel