Ejemplo n.º 1
0
glamor_pixmap_fbo *
glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
                               GLenum format, GLenum type, int no_alpha,
                               int revert, int swap_rb)
{
    glamor_pixmap_private *source_priv;
    glamor_screen_private *glamor_priv;
    ScreenPtr screen;
    glamor_pixmap_fbo *temp_fbo;
    float temp_xscale, temp_yscale, source_xscale, source_yscale;
    static float vertices[8];
    static float texcoords[8];

    screen = source->drawable.pScreen;

    glamor_priv = glamor_get_screen_private(screen);
    source_priv = glamor_get_pixmap_private(source);
    temp_fbo = glamor_create_fbo(glamor_priv, w, h, format, 0);
    if (temp_fbo == NULL)
        return NULL;

    glamor_make_current(glamor_priv);
    temp_xscale = 1.0 / w;
    temp_yscale = 1.0 / h;

    glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
                                 temp_xscale, temp_yscale, 0, 0, w, h,
                                 vertices);

    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                          2 * sizeof(float), vertices);
    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);

    pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
    glamor_set_normalize_tcoords(source_priv, source_xscale,
                                 source_yscale,
                                 x, y,
                                 x + w, y + h,
                                 texcoords);

    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
                          2 * sizeof(float), texcoords);
    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
    glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
    glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
    glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
    return temp_fbo;
}
Ejemplo n.º 2
0
PixmapPtr
glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                     unsigned int usage)
{
    PixmapPtr pixmap;
    glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
    glamor_pixmap_private *pixmap_priv;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    glamor_pixmap_fbo *fbo = NULL;
    int pitch;
    GLenum format;

    if (w > 32767 || h > 32767)
        return NullPixmap;

    if ((usage == GLAMOR_CREATE_PIXMAP_CPU
         || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64)
         || (w == 0 && h == 0)
         || !glamor_check_pixmap_fbo_depth(depth))
        || (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
            !glamor_check_fbo_size(glamor_priv, w, h)))
        return fbCreatePixmap(screen, w, h, depth, usage);
    else
        pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);

    pixmap_priv = calloc(1, sizeof(*pixmap_priv));

    if (!pixmap_priv) {
        fbDestroyPixmap(pixmap);
        return fbCreatePixmap(screen, w, h, depth, usage);
    }
    glamor_set_pixmap_private(pixmap, pixmap_priv);

    if (usage == GLAMOR_CREATE_PIXMAP_MAP)
        type = GLAMOR_MEMORY_MAP;

    pixmap_priv->base.pixmap = pixmap;
    pixmap_priv->base.glamor_priv = glamor_priv;

    format = gl_iformat_for_pixmap(pixmap);

    pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
    screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);

    if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
        pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
        pixmap_priv->base.box.x1 = 0;
        pixmap_priv->base.box.y1 = 0;
        pixmap_priv->base.box.x2 = w;
        pixmap_priv->base.box.y2 = h;
        return pixmap;
    }
    else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE ||
        glamor_check_fbo_size(glamor_priv, w, h))
    {
        pixmap_priv->type = type;
        pixmap_priv->base.box.x1 = 0;
        pixmap_priv->base.box.y1 = 0;
        pixmap_priv->base.box.x2 = w;
        pixmap_priv->base.box.y2 = h;
        fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
    } else {
        int tile_size = glamor_priv->max_fbo_size;
        DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size);
        pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
        fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
                                      tile_size, tile_size, pixmap_priv);
    }

    if (fbo == NULL) {
        fbDestroyPixmap(pixmap);
        free(pixmap_priv);
        return fbCreatePixmap(screen, w, h, depth, usage);
    }

    glamor_pixmap_attach_fbo(pixmap, fbo);

    return pixmap;
}