Ejemplo n.º 1
0
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_index;
    int off_x, off_y;

    glEnable(GL_SCISSOR_TEST);

    glamor_pixmap_loop(pixmap_priv, box_index) {
        int nbox = RegionNumRects(gc->pCompositeClip);
        BoxPtr box = RegionRects(gc->pCompositeClip);

        glamor_set_destination_drawable(drawable, box_index, 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);
        }
    }
Ejemplo n.º 2
0
static void
glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
                   glamor_program *prog,
                   struct glamor_glyph_atlas *atlas, int nglyph)
{
    DrawablePtr drawable = dst->pDrawable;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
    PixmapPtr atlas_pixmap = atlas->atlas;
    glamor_pixmap_private *atlas_priv = glamor_get_pixmap_private(atlas_pixmap);
    glamor_pixmap_fbo *atlas_fbo = glamor_pixmap_fbo_at(atlas_priv, 0, 0);
    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;

    glamor_put_vbo_space(drawable->pScreen);

    glEnable(GL_SCISSOR_TEST);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, atlas_fbo->tex);

    for (;;) {
        if (!glamor_use_program_render(prog, op, src, dst))
            break;

        glUniform1i(prog->atlas_uniform, 1);

        glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
            BoxPtr box = RegionRects(dst->pCompositeClip);
            int nbox = RegionNumRects(dst->pCompositeClip);

            glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);

            /* Run over the clip list, drawing the glyphs
             * in each box
             */

            while (nbox--) {
                glScissor(box->x1 + off_x,
                          box->y1 + off_y,
                          box->x2 - box->x1,
                          box->y2 - box->y1);
                box++;

                if (glamor_glyph_use_130(glamor_priv))
                    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph);
                else
                    glamor_glDrawArrays_GL_QUADS(glamor_priv, nglyph);
            }
        }
        if (prog->alpha != glamor_program_alpha_ca_first)
            break;
        prog++;
    }
Ejemplo n.º 3
0
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_index, dst_box_index;
    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;
    int n;

    glamor_make_current(glamor_priv);

    if (gc && !glamor_set_planemask(gc->depth, 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, NULL, 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);

    glEnable(GL_SCISSOR_TEST);

    glamor_pixmap_loop(src_priv, src_box_index) {
        BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_index);

        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_index);

        if (!glamor_use_program(dst_pixmap, gc, prog, &args))
            goto bail_ctx;

        glamor_pixmap_loop(dst_priv, dst_box_index) {
            glamor_set_destination_drawable(dst, dst_box_index, FALSE, FALSE,
                                            prog->matrix_uniform,
                                            &dst_off_x, &dst_off_y);

            glScissor(dst_off_x - args.dx,
                      dst_off_y - args.dy,
                      src_box->x2 - src_box->x1,
                      src_box->y2 - src_box->y1);

            glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
        }
Ejemplo n.º 4
0
static int
glamor_text(DrawablePtr drawable, GCPtr gc,
            glamor_font_t *glamor_font,
            glamor_program *prog,
            int x, int y,
            int count, char *s_chars, CharInfoPtr *charinfo,
            Bool sixteen)
{
    unsigned char *chars = (unsigned char *) s_chars;
    FontPtr font = gc->font;
    int off_x, off_y;
    int c;
    int nglyph;
    GLshort *v;
    char *vbo_offset;
    CharInfoPtr ci;
    int firstRow = font->info.firstRow;
    int firstCol = font->info.firstCol;
    int glyph_spacing_x = glamor_font->glyph_width_bytes * 8;
    int glyph_spacing_y = glamor_font->glyph_height;
    int box_x, box_y;
    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);

    /* Set the font as texture 1 */

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id);
    glUniform1i(prog->font_uniform, 1);

    /* Set up the vertex buffers for the font and destination */

    v = glamor_get_vbo_space(drawable->pScreen, count * (6 * sizeof (GLshort)), &vbo_offset);

    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
    glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
    glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE,
                          6 * sizeof (GLshort), vbo_offset);

    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
    glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1);
    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE,
                          6 * sizeof (GLshort), vbo_offset + 4 * sizeof (GLshort));

    /* Set the vertex coordinates */
    nglyph = 0;

    for (c = 0; c < count; c++) {
        if ((ci = *charinfo++)) {
            int     x1 = x + ci->metrics.leftSideBearing;
            int     y1 = y - ci->metrics.ascent;
            int     width = GLYPHWIDTHPIXELS(ci);
            int     height = GLYPHHEIGHTPIXELS(ci);
            int     tx, ty = 0;
            int     row = 0, col;

            x += ci->metrics.characterWidth;

            if (sixteen) {
                if (ci == glamor_font->default_char) {
                    row = glamor_font->default_row;
                    col = glamor_font->default_col;
                } else {
                    row = chars[0];
                    col = chars[1];
                }
                if (FONTLASTROW(font) != 0)
                    ty = (row - firstRow) * glyph_spacing_y;
                else
                    col += row << 8;
            } else {
                if (ci == glamor_font->default_char)
                    col = glamor_font->default_col;
                else
                    col = chars[0];
            }

            tx = (col - firstCol) * glyph_spacing_x;

            v[ 0] = x1;
            v[ 1] = y1;
            v[ 2] = width;
            v[ 3] = height;
            v[ 4] = tx;
            v[ 5] = ty;

            v += 6;
            nglyph++;
        }
        chars += 1 + sixteen;
    }
    glamor_put_vbo_space(drawable->pScreen);

    if (nglyph != 0) {

        glEnable(GL_SCISSOR_TEST);

        glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
            BoxPtr box = RegionRects(gc->pCompositeClip);
            int nbox = RegionNumRects(gc->pCompositeClip);

            glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);

            /* Run over the clip list, drawing the glyphs
             * in each box
             */

            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, nglyph);
            }
        }
Ejemplo n.º 5
0
static Bool
glamor_fill_spans_gl(DrawablePtr drawable,
                     GCPtr gc,
                     int n, DDXPointPtr points, int *widths, int sorted)
{
    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;
    GLshort *v;
    char *vbo_offset;
    int c;
    int box_x, box_y;

    pixmap_priv = glamor_get_pixmap_private(pixmap);
    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
        goto bail;

    glamor_make_current(glamor_priv);

    if (glamor_priv->glsl_version >= 130) {
        prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program,
                                       &glamor_facet_fillspans_130);

        if (!prog)
            goto bail;

        /* Set up the vertex buffers for the points */

        v = glamor_get_vbo_space(drawable->pScreen, n * (4 * sizeof (GLshort)), &vbo_offset);

        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
        glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
        glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE,
                              4 * sizeof (GLshort), vbo_offset);

        for (c = 0; c < n; c++) {
            v[0] = points->x;
            v[1] = points->y;
            v[2] = *widths++;
            points++;
            v += 4;
        }

        glamor_put_vbo_space(screen);
    } else {
        prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program,
                                       &glamor_facet_fillspans_120);

        if (!prog)
            goto bail;

        /* Set up the vertex buffers for the points */

        v = glamor_get_vbo_space(drawable->pScreen, n * 8 * sizeof (short), &vbo_offset);

        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
        glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
                              2 * sizeof (short), vbo_offset);

        for (c = 0; c < n; c++) {
            v[0] = points->x;           v[1] = points->y;
            v[2] = points->x;           v[3] = points->y + 1;
            v[4] = points->x + *widths; v[5] = points->y + 1;
            v[6] = points->x + *widths; v[7] = points->y;

            widths++;
            points++;
            v += 8;
        }

        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, FALSE, FALSE, 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++;
            if (glamor_priv->glsl_version >= 130)
                glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, n);
            else {
                glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
            }
        }
    }
Ejemplo n.º 6
0
static Bool
glamor_poly_fill_rect_gl(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 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);

    if (glamor_priv->glsl_version >= 130) {
        prog = glamor_use_program_fill(pixmap, gc,
                                       &glamor_priv->poly_fill_rect_program,
                                       &glamor_facet_polyfillrect_130);

        if (!prog)
            goto bail_ctx;

        /* Set up the vertex buffers for the points */

        v = glamor_get_vbo_space(drawable->pScreen, nrect * sizeof (xRectangle), &vbo_offset);

        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
        glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
        glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE,
                              4 * sizeof (short), vbo_offset);

        memcpy(v, prect, nrect * sizeof (xRectangle));

        glamor_put_vbo_space(screen);
    } else {
        int n;

        prog = glamor_use_program_fill(pixmap, gc,
                                       &glamor_priv->poly_fill_rect_program,
                                       &glamor_facet_polyfillrect_120);

        if (!prog)
            goto bail_ctx;

        /* Set up the vertex buffers for the points */

        v = glamor_get_vbo_space(drawable->pScreen, nrect * 8 * sizeof (short), &vbo_offset);

        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
        glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
                              2 * sizeof (short), vbo_offset);

        for (n = 0; n < nrect; n++) {
            v[0] = prect->x;                v[1] = prect->y;
            v[2] = prect->x;                v[3] = prect->y + prect->height;
            v[4] = prect->x + prect->width; v[5] = prect->y + prect->height;
            v[6] = prect->x + prect->width; v[7] = prect->y;
            prect++;
            v += 8;
        }

        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, FALSE, 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++;
            if (glamor_priv->glsl_version >= 130)
                glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect);
            else {
                if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
                    glDrawArrays(GL_QUADS, 0, nrect * 4);
                } else {
                    int i;
                    for (i = 0; i < nrect; i++) {
                        glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
                    }
                }
            }
        }
    }
static Bool
glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
                         int start_x, int y, unsigned int nglyph,
                         CharInfoPtr *ppci, void *pglyph_base)
{
    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;
    RegionPtr clip = gc->pCompositeClip;
    int box_index;

    pixmap_priv = glamor_get_pixmap_private(pixmap);
    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
        goto bail;

    glamor_make_current(glamor_priv);

    prog = glamor_use_program_fill(pixmap, gc,
                                   &glamor_priv->poly_glyph_blt_progs,
                                   &glamor_facet_poly_glyph_blt);
    if (!prog)
        goto bail;

    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);

    start_x += drawable->x;
    y += drawable->y;

    glamor_pixmap_loop(pixmap_priv, box_index) {
        int x;
        int n;
        int num_points, max_points;
        INT16 *points = NULL;
        int off_x, off_y;
        char *vbo_offset;

        glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE,
                                        prog->matrix_uniform, &off_x, &off_y);

        max_points = 500;
        num_points = 0;
        x = start_x;
        for (n = 0; n < nglyph; n++) {
            CharInfoPtr charinfo = ppci[n];
            int w = GLYPHWIDTHPIXELS(charinfo);
            int h = GLYPHHEIGHTPIXELS(charinfo);
            uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo);

            if (w && h) {
                int glyph_x = x + charinfo->metrics.leftSideBearing;
                int glyph_y = y - charinfo->metrics.ascent;
                int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo);
                int xx, yy;

                for (yy = 0; yy < h; yy++) {
                    uint8_t *glyph = glyphbits;
                    for (xx = 0; xx < w; glyph += ((xx&7) == 7), xx++) {
                        int pt_x_i = glyph_x + xx;
                        int pt_y_i = glyph_y + yy;

                        if (!(*glyph & (1 << (xx & 7))))
                            continue;

                        if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, NULL))
                            continue;

                        if (!num_points) {
                            points = glamor_get_vbo_space(screen,
                                                          max_points *
                                                          (2 * sizeof (INT16)),
                                                          &vbo_offset);

                            glVertexAttribPointer(GLAMOR_VERTEX_POS,
                                                  2, GL_SHORT,
                                                  GL_FALSE, 0, vbo_offset);
                        }

                        *points++ = pt_x_i;
                        *points++ = pt_y_i;
                        num_points++;

                        if (num_points == max_points) {
                            glamor_put_vbo_space(screen);
                            glDrawArrays(GL_POINTS, 0, num_points);
                            num_points = 0;
                        }
                    }
                    glyphbits += glyph_stride;
                }
            }
            x += charinfo->metrics.characterWidth;
        }

        if (num_points) {
            glamor_put_vbo_space(screen);
            glDrawArrays(GL_POINTS, 0, num_points);
        }
    }