예제 #1
0
/* XXX LARGE pixmap? */
Bool
glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
{
    glamor_pixmap_fbo *old_fbo;
    glamor_pixmap_fbo *new_fbo = NULL;
    PixmapPtr scratch = NULL;
    glamor_pixmap_private *scratch_priv;
    DrawablePtr drawable;
    GCPtr gc = NULL;
    int ret = FALSE;

    drawable = &pixmap_priv->base.pixmap->drawable;

    if (!GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv))
        return TRUE;

    old_fbo = pixmap_priv->base.fbo;

    if (!old_fbo)
        return FALSE;

    gc = GetScratchGC(drawable->depth, screen);
    if (!gc)
        goto fail;

    scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
                                   drawable->depth, GLAMOR_CREATE_PIXMAP_FIXUP);

    scratch_priv = glamor_get_pixmap_private(scratch);

    if (!scratch_priv->base.fbo)
        goto fail;

    ValidateGC(&scratch->drawable, gc);
    glamor_copy_area(drawable,
                     &scratch->drawable,
                     gc, 0, 0, drawable->width, drawable->height, 0, 0);
    old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
    new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
    glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
    glamor_pixmap_attach_fbo(scratch, old_fbo);

    DEBUGF("old %dx%d type %d\n",
           drawable->width, drawable->height, pixmap_priv->type);
    DEBUGF("copy tex %d  %dx%d to tex %d %dx%d \n",
           old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex,
           new_fbo->width, new_fbo->height);
    ret = TRUE;
 fail:
    if (gc)
        FreeScratchGC(gc);
    if (scratch)
        glamor_destroy_pixmap(scratch);

    return ret;
}
예제 #2
0
_X_EXPORT void
glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
{
    ScreenPtr screen = pixmap->drawable.pScreen;
    glamor_pixmap_private *pixmap_priv;
    glamor_screen_private *glamor_priv;
    glamor_pixmap_fbo *fbo;
    GLenum format;

    glamor_priv = glamor_get_screen_private(screen);
    pixmap_priv = glamor_get_pixmap_private(pixmap);

    if (pixmap_priv->base.fbo) {
        fbo = glamor_pixmap_detach_fbo(pixmap_priv);
        glamor_destroy_fbo(fbo);
    }

    format = gl_iformat_for_pixmap(pixmap);
    fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
                                     pixmap->drawable.height, format, tex, 0);

    if (fbo == NULL) {
        ErrorF("XXX fail to create fbo.\n");
        return;
    }

    glamor_pixmap_attach_fbo(pixmap, fbo);
}
예제 #3
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;
}