Esempio 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;
}
Esempio n. 2
0
static void
glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
			  int x, int y, int w, int h, int left_pad,
			  int image_format, char *bits)
{
	ScreenPtr screen = drawable->pScreen;
	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
	glamor_screen_private *glamor_priv =
	    glamor_get_screen_private(screen);
	float fg[4], bg[4];
	GLuint tex;
	unsigned int stride = PixmapBytePad(1, w + left_pad);
	RegionPtr clip;
	BoxPtr box;
	int nbox;
	float dest_coords[8];
	const float bitmap_coords[8] = {
		0.0, 0.0,
		1.0, 0.0,
		1.0, 1.0,
		0.0, 1.0,
	};
	GLfloat xscale, yscale;
	glamor_pixmap_private *pixmap_priv;

	pixmap_priv = glamor_get_pixmap_private(pixmap);

	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);

	glamor_set_normalize_vcoords(xscale, yscale,
				     x, y,
				     x + w, y + h,
				     glamor_priv->yInverted, dest_coords);

	glamor_fallback("glamor_put_image_xybitmap: disabled\n");
	goto fail;

	if (glamor_priv->put_image_xybitmap_prog == 0) {
		ErrorF("no program for xybitmap putimage\n");
		goto fail;
	}

	glamor_set_alu(gc->alu);
	if (!glamor_set_planemask(pixmap, gc->planemask))
		goto fail;

	dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);

	glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
	dispatch->glUniform4fv
	    (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
	glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
	dispatch->glUniform4fv
	    (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);

	dispatch->glGenTextures(1, &tex);
	dispatch->glActiveTexture(GL_TEXTURE0);
	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
				  GL_NEAREST);
	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
				  GL_NEAREST);
	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
			       w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);

	/* Now that we've set up our bitmap texture and the shader, shove
	 * the destination rectangle through the cliprects and run the
	 * shader on the resulting fragments.
	 */
	dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
	dispatch->glEnableClientState(GL_VERTEX_ARRAY);
	dispatch->glClientActiveTexture(GL_TEXTURE0);
	dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
	dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	dispatch->glEnable(GL_SCISSOR_TEST);
	clip = fbGetCompositeClip(gc);
	for (nbox = REGION_NUM_RECTS(clip),
	     box = REGION_RECTS(clip); nbox--; box++) {
		int x1 = x;
		int y1 = y;
		int x2 = x + w;
		int y2 = y + h;

		if (x1 < box->x1)
			x1 = box->x1;
		if (y1 < box->y1)
			y1 = box->y1;
		if (x2 > box->x2)
			x2 = box->x2;
		if (y2 > box->y2)
			y2 = box->y2;
		if (x1 >= x2 || y1 >= y2)
			continue;

		dispatch->glScissor(box->x1,
				    y_flip(pixmap, box->y1),
				    box->x2 - box->x1, box->y2 - box->y1);
		dispatch->glDrawArrays(GL_QUADS, 0, 4);
	}

	dispatch->glDisable(GL_SCISSOR_TEST);
	glamor_set_alu(GXcopy);
	glamor_set_planemask(pixmap, ~0);
	dispatch->glDeleteTextures(1, &tex);
	dispatch->glDisableClientState(GL_VERTEX_ARRAY);
	dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	return;
	glamor_set_alu(GXcopy);
	glamor_set_planemask(pixmap, ~0);
	glamor_fallback(": to %p (%c)\n",
			drawable, glamor_get_drawable_location(drawable));
fail:
	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
	    glamor_prepare_access_gc(gc)) {
		fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap,
			   bits);
	}
	glamor_finish_access_gc(gc);
	glamor_finish_access(drawable);
}
Esempio n. 3
0
static void
_glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
             int x, int y, int width, int height, int tile_x, int tile_y)
{
    ScreenPtr screen = pixmap->drawable.pScreen;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    int x1 = x;
    int x2 = x + width;
    int y1 = y;
    int y2 = y + height;
    int tile_x1 = tile_x;
    int tile_x2 = tile_x + width;
    int tile_y1 = tile_y;
    int tile_y2 = tile_y + height;
    float vertices[8];
    float source_texcoords[8];
    GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
    glamor_pixmap_private *src_pixmap_priv;
    glamor_pixmap_private *dst_pixmap_priv;
    float wh[4];

    src_pixmap_priv = glamor_get_pixmap_private(tile);
    dst_pixmap_priv = glamor_get_pixmap_private(pixmap);

    glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
    pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
    pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
    glamor_make_current(glamor_priv);
    glUseProgram(glamor_priv->tile_prog);

    glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
    glUniform2fv(glamor_priv->tile_wh, 1, wh);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glamor_set_repeat_normalize_tcoords
        (src_pixmap_priv, RepeatNormal,
         src_xscale, src_yscale,
         tile_x1, tile_y1,
         tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords);

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

    glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale,
                                 x1, y1,
                                 x2, y2, glamor_priv->yInverted, vertices);

    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                          2 * sizeof(float), vertices);
    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);

    glamor_priv->state = RENDER_STATE;
    glamor_priv->render_idle_cnt = 0;
}
Esempio n. 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;
}