glamor: Add acceleration for copyarea not from the screen.
This commit is contained in:
		
							parent
							
								
									647b9fb49a
								
							
						
					
					
						commit
						35847c578e
					
				|  | @ -32,6 +32,30 @@ | |||
|  * GC CopyArea implementation | ||||
|  */ | ||||
| 
 | ||||
| static float | ||||
| v_from_x_coord_x(PixmapPtr pixmap, int x) | ||||
| { | ||||
|     return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0; | ||||
| } | ||||
| 
 | ||||
| static float | ||||
| v_from_x_coord_y(PixmapPtr pixmap, int y) | ||||
| { | ||||
|     return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0; | ||||
| } | ||||
| 
 | ||||
| static float | ||||
| t_from_x_coord_x(PixmapPtr pixmap, int x) | ||||
| { | ||||
|     return (float)(x - pixmap->screen_x) / pixmap->drawable.width; | ||||
| } | ||||
| 
 | ||||
| static float | ||||
| t_from_x_coord_y(PixmapPtr pixmap, int y) | ||||
| { | ||||
|     return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| glamor_copy_n_to_n(DrawablePtr src, | ||||
| 		 DrawablePtr dst, | ||||
|  | @ -45,16 +69,78 @@ glamor_copy_n_to_n(DrawablePtr src, | |||
| 		 Pixel		bitplane, | ||||
| 		 void		*closure) | ||||
| { | ||||
|     glamor_screen_private *glamor_priv = | ||||
| 	glamor_get_screen_private(dst->pScreen); | ||||
|     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); | ||||
|     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); | ||||
|     int i; | ||||
|     float vertices[4][2], texcoords[4][2]; | ||||
|     glamor_pixmap_private *src_pixmap_priv; | ||||
| 
 | ||||
|     goto fail; | ||||
|     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); | ||||
| 
 | ||||
|     glamor_set_alu(gc->alu); | ||||
|     if (!glamor_set_planemask(dst_pixmap, gc->planemask)) | ||||
|     if (src == dst) { | ||||
| 	glamor_fallback("glamor_copy_n_to_n with same src/dst\n"); | ||||
| 	goto fail; | ||||
|     } | ||||
| 
 | ||||
|     if (!src_pixmap_priv || !src_pixmap_priv->tex) { | ||||
| 	glamor_fallback("glamor_copy_n_to_n with non-texture src\n"); | ||||
| 	goto fail; | ||||
|     } | ||||
| 
 | ||||
|     if (!glamor_set_destination_pixmap(dst_pixmap)) | ||||
| 	goto fail; | ||||
| 
 | ||||
|     if (gc) { | ||||
| 	glamor_set_alu(gc->alu); | ||||
| 	if (!glamor_set_planemask(dst_pixmap, gc->planemask)) | ||||
| 	    goto fail; | ||||
|     } | ||||
| 
 | ||||
|     glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); | ||||
|     glEnable(GL_TEXTURE_2D); | ||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
| 
 | ||||
|     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); | ||||
|     glEnableClientState(GL_VERTEX_ARRAY); | ||||
| 
 | ||||
|     glClientActiveTexture(GL_TEXTURE0); | ||||
|     glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); | ||||
|     glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||||
| 
 | ||||
|     assert(GLEW_ARB_fragment_shader); | ||||
|     glUseProgramObjectARB(glamor_priv->finish_access_prog); | ||||
| 
 | ||||
|     for (i = 0; i < nbox; i++) { | ||||
| 	vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1); | ||||
| 	vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1); | ||||
| 	vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2); | ||||
| 	vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1); | ||||
| 	vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2); | ||||
| 	vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2); | ||||
| 	vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1); | ||||
| 	vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2); | ||||
| 
 | ||||
| 	texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); | ||||
| 	texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); | ||||
| 	texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); | ||||
| 	texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); | ||||
| 	texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); | ||||
| 	texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); | ||||
| 	texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); | ||||
| 	texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); | ||||
| 	glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | ||||
|     } | ||||
| 
 | ||||
|     glUseProgramObjectARB(0); | ||||
| 
 | ||||
|     glDisableClientState(GL_VERTEX_ARRAY); | ||||
|     glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||||
|     glDisable(GL_TEXTURE_2D); | ||||
| 
 | ||||
| #if 0 | ||||
|     for (i = 0; i < nbox; i++) { | ||||
| 	glRasterPos2i(box[i].x1 - dst_pixmap->screen_x, | ||||
| 		      box[i].y1 - dst_pixmap->screen_y); | ||||
|  | @ -64,9 +150,12 @@ glamor_copy_n_to_n(DrawablePtr src, | |||
| 		     box[i].y2 - box[i].y1, | ||||
| 		     GL_COLOR); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     return; | ||||
| 
 | ||||
| fail: | ||||
|     glamor_fallback("from %p to %p (%c,%c)\n", src, dst, | ||||
|     glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst, | ||||
| 		    glamor_get_drawable_location(src), | ||||
| 		    glamor_get_drawable_location(dst)); | ||||
|     if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { | ||||
|  | @ -89,31 +178,9 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, | |||
|     ScreenPtr screen = dst->pScreen; | ||||
|     PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); | ||||
|     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); | ||||
|     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); | ||||
|     glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); | ||||
|     RegionPtr region; | ||||
| 
 | ||||
|     if (!GLEW_EXT_framebuffer_blit) { | ||||
| 	glamor_fallback("glamor_copy_area(): " | ||||
| 			"EXT_framebuffer_blit unsupported\n"); | ||||
| 	goto fail; | ||||
|     } | ||||
| 
 | ||||
|     if (!glamor_set_destination_pixmap(dst_pixmap)) | ||||
| 	goto fail; | ||||
| 
 | ||||
|     if (src_priv == NULL) { | ||||
| 	glamor_fallback("glamor_copy_area(): no src pixmap priv"); | ||||
| 	goto fail; | ||||
|     } | ||||
| 
 | ||||
|     if (src_priv->fb == 0 && src_pixmap != screen_pixmap) { | ||||
| 	glamor_fallback("glamor_copy_area(): no src fbo"); | ||||
| 	goto fail; | ||||
|     } | ||||
| 
 | ||||
|     glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src_priv->fb); | ||||
| 
 | ||||
|     region = miDoCopy(src, dst, gc, | ||||
| 		      srcx, srcy, width, height, | ||||
| 		      dstx, dsty, glamor_copy_n_to_n, 0, NULL); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue