Exemple #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;
}
Exemple #2
0
static Bool 
_glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
		 int w, int h, int left_pad, int image_format, char *bits, Bool fallback)
{
	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
	glamor_pixmap_private *pixmap_priv =
	    glamor_get_pixmap_private(pixmap);
	RegionPtr clip;
	int x_off, y_off;
	Bool ret = FALSE;
	PixmapPtr temp_pixmap, sub_pixmap;
	glamor_pixmap_private *temp_pixmap_priv;
	BoxRec box;
	int stride;

	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
	clip = fbGetCompositeClip(gc);
	if (image_format == XYBitmap) {
		assert(depth == 1);
		goto fail;
	}

	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
		glamor_fallback("has no fbo.\n");
		goto fail;
	}

	if (image_format != ZPixmap) {
		glamor_fallback("non-ZPixmap\n");
		goto fail;
	}

	if (!glamor_set_planemask(pixmap, gc->planemask)) {
		goto fail;
	}
	/* create a temporary pixmap and upload the bits to that
	 * pixmap, then apply clip copy it to the destination pixmap.*/
	stride = PixmapBytePad(w, depth);
	box.x1 = x + drawable->x;
	box.y1 = y + drawable->y;
	box.x2 = x + w + drawable->x;
	box.y2 = y + h + drawable->y;

	if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN)
	     || gc->alu != GXcopy) {
		temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
		if (temp_pixmap == NULL)
			goto fail;

		temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);

		if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
			temp_pixmap_priv->base.picture = pixmap_priv->base.picture;
			temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
		}

		glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
		                                    stride, bits, 0);
		glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y);
		glamor_destroy_pixmap(temp_pixmap);
	} else {
		glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off,
		                                    w, h, stride, bits, 0);
	}
	ret = TRUE;
	goto done;

fail:
	glamor_set_planemask(pixmap, ~0);

	if (!fallback
	    && glamor_ddx_fallback_check_pixmap(&pixmap->drawable))
		goto done;

	glamor_fallback("to %p (%c)\n",
			drawable, glamor_get_drawable_location(drawable));

	sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
					   y + y_off + drawable->y, w, h,
					   GLAMOR_ACCESS_RW);
	if (sub_pixmap) {
		if (clip != NULL)
			pixman_region_translate (clip, -x - drawable->x, -y - drawable->y);

		fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h,
			   left_pad, image_format, bits);

		glamor_put_sub_pixmap(sub_pixmap, pixmap,
				      x + x_off + drawable->x,
				      y + y_off + drawable->y,
				      w, h, GLAMOR_ACCESS_RW);
		if (clip != NULL)
			pixman_region_translate (clip, x + drawable->x, y + drawable->y);
	} else
		fbPutImage(drawable, gc, depth, x, y, w, h,
			   left_pad, image_format, bits);
	ret = TRUE;

done:
	return ret;
}