This accelerates poly point when possible by off-loading all geometry computation to the GPU.
Signed-off-by: Keith Packard <kei...@keithp.com> --- glamor/glamor.c | 1 + glamor/glamor_polyops.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++--- glamor/glamor_priv.h | 5 +++ 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index c5b6e8c..86b0ba5 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -550,6 +550,7 @@ glamor_release_screen_priv(ScreenPtr screen) glamor_fini_vbo(screen); glamor_fini_pixmap_fbo(screen); glamor_fini_solid_shader(screen); + glamor_fini_point_shader(screen); glamor_fini_tile_shader(screen); #ifdef GLAMOR_TRAPEZOID_SHADER glamor_fini_trapezoid_shader(screen); diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c index 1484d80..eac1688 100644 --- a/glamor/glamor_polyops.c +++ b/glamor/glamor_polyops.c @@ -27,17 +27,93 @@ */ #include "glamor_priv.h" +#include "glamor_transform.h" + +static const glamor_facet glamor_facet_point = { + .name = "poly_point", + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = GLAMOR_POS(gl_Position, primitive), +}; static Bool -_glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, +_glamor_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPointPtr ppt, Bool fallback) { - if (!fallback && glamor_ddx_fallback_check_gc(pGC) - && glamor_ddx_fallback_check_pixmap(pDrawable)) + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_program *prog = &glamor_priv->point_prog; + glamor_pixmap_private *pixmap_priv; + int nbox = RegionNumRects(gc->pCompositeClip); + BoxPtr box = RegionRects(gc->pCompositeClip); + int off_x, off_y; + GLshort *vbo_ppt; + char *vbo_offset; + int box_x, box_y; + + if (!fallback && glamor_ddx_fallback_check_gc(gc) + && glamor_ddx_fallback_check_pixmap(drawable)) return FALSE; - miPolyPoint(pDrawable, pGC, mode, npt, ppt); + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + glamor_get_context(glamor_priv); + + if (prog->failed) { + glamor_put_context(glamor_priv); + goto bail; + } + + if (!prog->prog) { + if (!glamor_build_program(screen, prog, + &glamor_facet_point, + &glamor_fill_solid)) + { + glamor_put_context(glamor_priv); + goto bail; + } + } + + if (!glamor_use_program(pixmap, gc, prog)) { + glamor_put_context(glamor_priv); + goto bail; + } + + vbo_ppt = glamor_get_vbo_space(screen, npt * (2 * sizeof (INT16)), &vbo_offset); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 0, vbo_offset); + memcpy(vbo_ppt, ppt, npt * (2 * sizeof (INT16))); + glamor_put_vbo_space(screen); + + glEnable(GL_SCISSOR_TEST); + + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, prog->matrix_uniform, &off_x, &off_y); + + while (nbox--) { + glScissor(box->x1 + off_x, + box->y1 + off_y, + box->x2 - box->x1, + box->y2 - box->y1); + box++; + glDrawArrays(GL_POINTS, 0, npt); + } + } + glDisable(GL_SCISSOR_TEST); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + glamor_put_context(glamor_priv); + + glamor_priv->state = RENDER_STATE; + glamor_priv->render_idle_cnt = 0; + + return TRUE; + +bail: + miPolyPoint(drawable, gc, mode, npt, ppt); return TRUE; } @@ -55,6 +131,14 @@ glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, return _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, FALSE); } +void +glamor_fini_point_shader(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + glamor_delete_program(screen, &glamor_priv->point_prog); +} + static Bool _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg, Bool fallback) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 766c7d9..b0ab4e1 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -226,6 +226,9 @@ typedef struct glamor_screen_private { GLint solid_prog; GLint solid_color_uniform_location; + /* glamor point shader */ + glamor_program point_prog; + /* vertext/elment_index buffer object for render */ GLuint vbo, ebo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ @@ -992,6 +995,8 @@ void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt); +void glamor_fini_point_shader(ScreenPtr screen); + void glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg); -- 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