Example #1
0
enum glamor_pixmap_status
glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
{
    glamor_pixmap_private *pixmap_priv;
    void *data;
    int pbo;
    int ret;

    pixmap_priv = glamor_get_pixmap_private(pixmap);

    if ((pixmap_priv->base.fbo)
        && (pixmap_priv->base.fbo->pbo_valid)) {
        data = NULL;
        pbo = pixmap_priv->base.fbo->pbo;
    }
    else {
        data = pixmap->devPrivate.ptr;
        pbo = 0;
    }

    if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
                                            pixmap->drawable.width,
                                            pixmap->drawable.height,
                                            pixmap->devKind, data, pbo))
        ret = GLAMOR_UPLOAD_DONE;
    else
        ret = GLAMOR_UPLOAD_FAILED;

    return ret;
}
Example #2
0
/* Upload picture to texture.  We may need to flip the y axis or
 * wire alpha to 1. So we may conditional create fbo for the picture.
 * */
enum glamor_pixmap_status
glamor_upload_picture_to_texture(PicturePtr picture)
{
    PixmapPtr pixmap;

    assert(picture->pDrawable);
    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);

    if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
                                            pixmap->drawable.width,
                                            pixmap->drawable.height,
                                            pixmap->devKind,
                                            pixmap->devPrivate.ptr, 0,
                                            picture->format))
        return GLAMOR_UPLOAD_DONE;
    else
        return GLAMOR_UPLOAD_FAILED;
}
Example #3
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;
}
Example #4
0
static Bool
glamor_copy_n_to_n_textured(DrawablePtr src,
			    DrawablePtr dst,
			    GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
{
	glamor_screen_private *glamor_priv =
	    glamor_get_screen_private(dst->pScreen);
	glamor_gl_dispatch *dispatch;
	PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
	int i;
	float vertices[8], texcoords[8];
	glamor_pixmap_private *src_pixmap_priv;
	glamor_pixmap_private *dst_pixmap_priv;
	int src_x_off, src_y_off, dst_x_off, dst_y_off;
	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;

	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);

	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
					   &src_y_off);
	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
				   &dst_y_off);

	if (!src_pixmap_priv->base.gl_fbo) {
		/* Optimize when the source doesn't have an FBO, just upload
		   the data directly to the dest FBO */
		int src_stride = src_pixmap->devKind;
		int bpp = src_pixmap->drawable.bitsPerPixel;
		void *src_data = NULL;
		if (src->bitsPerPixel != dst->bitsPerPixel) {
			DEBUGF("Non-matching bpp\n");
			return FALSE;
		}
		if (src->bitsPerPixel < 8) {
			DEBUGF("bpp < 8\n");
			return FALSE;
		}
		if (gc && !(gc->alu == GXcopy && glamor_pm_is_solid(src, gc->planemask))) {
			DEBUGF("non gxcopy and solid\n");
			return FALSE;
		}
		for (i = 0; i < nbox; i++) {
			int x = box[i].x1 + dst_x_off;
			int y = box[i].y1 + dst_y_off;
			int w = box[i].x2 - box[i].x1;
			int h = box[i].y2 - box[i].y1;
			src_data = (char *)src_pixmap->devPrivate.ptr + (box[i].y1 + dy +
								src_y_off) * src_stride +
								(box[i].x1 + dx + src_x_off) * (bpp / 8);
			if (!glamor_upload_sub_pixmap_to_texture(dst_pixmap,
					x, y, w, h,
					src_stride, src_data, 0)) {
				ErrorF("Failed to upload the sub pixmap to dst\n");
				return FALSE;
			}
		}
		return TRUE;
	}


	pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);


	dispatch = glamor_get_dispatch(glamor_priv);


	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
					GL_FALSE, 2 * sizeof(float),
					vertices);
	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);


	dx += src_x_off;
	dy += src_y_off;


	dispatch->glActiveTexture(GL_TEXTURE0);
	dispatch->glBindTexture(GL_TEXTURE_2D,
				src_pixmap_priv->base.fbo->tex);
#ifndef GLAMOR_GLES2
	dispatch->glTexParameteri(GL_TEXTURE_2D,
				  GL_TEXTURE_WRAP_S,
				  GL_CLAMP_TO_BORDER);
	dispatch->glTexParameteri(GL_TEXTURE_2D,
				  GL_TEXTURE_WRAP_T,
				  GL_CLAMP_TO_BORDER);
#endif
	dispatch->glTexParameteri(GL_TEXTURE_2D,
				  GL_TEXTURE_MIN_FILTER,
				  GL_NEAREST);
	dispatch->glTexParameteri(GL_TEXTURE_2D,
				  GL_TEXTURE_MAG_FILTER,
				  GL_NEAREST);

	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
					GL_FLOAT, GL_FALSE,
					2 * sizeof(float),
					texcoords);
	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
	dispatch->glUniform1i(glamor_priv->finish_access_revert[0],
			      REVERT_NONE);
	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
			      SWAP_NONE_UPLOADING);

	for (i = 0; i < nbox; i++) {

		glamor_set_normalize_vcoords(dst_pixmap_priv,
					     dst_xscale, dst_yscale,
					     box[i].x1 + dst_x_off,
					     box[i].y1 + dst_y_off,
					     box[i].x2 + dst_x_off,
					     box[i].y2 + dst_y_off,
					     glamor_priv->yInverted,
					     vertices);

		glamor_set_normalize_tcoords(src_pixmap_priv,
					     src_xscale,
					     src_yscale,
					     box[i].x1 + dx,
					     box[i].y1 + dy,
					     box[i].x2 + dx,
					     box[i].y2 + dy,
					     glamor_priv->yInverted,
					     texcoords);
		dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
	}

	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
	/* The source texture is bound to a fbo, we have to flush it here. */
	glamor_put_dispatch(glamor_priv);
	glamor_priv->state = RENDER_STATE;
	glamor_priv->render_idle_cnt = 0;
	return TRUE;
}
Example #5
0
static Bool
_glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
                  DDXPointPtr points, int *widths, int numPoints, int sorted,
                  Bool fallback)
{
    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
    glamor_pixmap_private *dest_pixmap_priv;
    int i;
    uint8_t *drawpixels_src = (uint8_t *) src;
    RegionPtr clip = fbGetCompositeClip(gc);
    BoxRec *pbox;
    int x_off, y_off;
    Bool ret = FALSE;

    dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
        glamor_fallback("pixmap has no fbo.\n");
        goto fail;
    }

    /* XXX Shall we set alu here? */
    if (!glamor_set_planemask(dest_pixmap, gc->planemask))
        goto fail;

    glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
    for (i = 0; i < numPoints; i++) {

        int n = REGION_NUM_RECTS(clip);

        pbox = REGION_RECTS(clip);
        while (n--) {
            int x1 = points[i].x;
            int x2 = x1 + widths[i];
            int y1 = points[i].y;

            if (pbox->y1 > points[i].y || pbox->y2 < points[i].y)
                break;
            x1 = x1 > pbox->x1 ? x1 : pbox->x1;
            x2 = x2 < pbox->x2 ? x2 : pbox->x2;
            if (x1 >= x2)
                continue;
            glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off,
                                                y1 + y_off, x2 - x1, 1,
                                                PixmapBytePad(widths[i],
                                                              drawable->depth),
                                                drawpixels_src, 0);
        }
        drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
    }
    ret = TRUE;
    goto done;

 fail:
    if (!fallback && glamor_ddx_fallback_check_pixmap(drawable))
        goto done;

    glamor_fallback("to %p (%c)\n",
                    drawable, glamor_get_drawable_location(drawable));
    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
        fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted);
        glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
    }
    ret = TRUE;

 done:
    return ret;
}