glamor: xv: reuse ports and shaders when possible
Xv currently calls glamor_xv_free_port_data at the end of every putImage. This leads to shader recompilation for every frame, which is a huge performance loss. This commit changes behaviour of glamor_xv_free_port_data, and its now is called only if width, height or format is changed for xv port. Shader management also done in a port now, because if shaders will be stored in core glamor and try to be reused, this can lead to a bug if we try to play 2 videos with different formats simultaneously. Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Konstantin <ria.freelander@gmail.com>
This commit is contained in:
		
							parent
							
								
									a8270fc5f0
								
							
						
					
					
						commit
						81ef43dd4a
					
				|  | @ -945,6 +945,9 @@ typedef struct { | |||
|     RegionRec clip; | ||||
|     PixmapPtr src_pix[3];       /* y, u, v for planar */ | ||||
|     int src_pix_w, src_pix_h; | ||||
|     /* Port optimization */ | ||||
|     int prev_fmt; | ||||
|     glamor_program xv_prog; | ||||
| } glamor_port_private; | ||||
| 
 | ||||
| extern XvAttributeRec glamor_xv_attributes[]; | ||||
|  |  | |||
|  | @ -143,9 +143,8 @@ XvImageRec glamor_xv_images[] = { | |||
| int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images); | ||||
| 
 | ||||
| static void | ||||
| glamor_init_xv_shader(ScreenPtr screen, int id) | ||||
| glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id) | ||||
| { | ||||
|     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); | ||||
|     GLint sampler_loc; | ||||
|     const glamor_facet *glamor_facet_xv_planar = NULL; | ||||
| 
 | ||||
|  | @ -162,10 +161,10 @@ glamor_init_xv_shader(ScreenPtr screen, int id) | |||
|     } | ||||
| 
 | ||||
|     glamor_build_program(screen, | ||||
|                          &glamor_priv->xv_prog, | ||||
|                          &port_priv->xv_prog, | ||||
|                          glamor_facet_xv_planar, NULL, NULL, NULL); | ||||
| 
 | ||||
|     glUseProgram(glamor_priv->xv_prog.prog); | ||||
|     glUseProgram(port_priv->xv_prog.prog); | ||||
|     sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler"); | ||||
|     glUniform1i(sampler_loc, 0); | ||||
|     sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler"); | ||||
|  | @ -330,8 +329,8 @@ glamor_xv_render(glamor_port_private *port_priv, int id) | |||
|     char *vbo_offset; | ||||
|     int dst_box_index; | ||||
| 
 | ||||
|     if (!glamor_priv->xv_prog.prog) | ||||
|         glamor_init_xv_shader(screen, id); | ||||
|     if (!port_priv->xv_prog.prog) | ||||
|         glamor_init_xv_shader(screen, port_priv, id); | ||||
| 
 | ||||
|     cont = RTFContrast(port_priv->contrast); | ||||
|     bright = RTFBrightness(port_priv->brightness); | ||||
|  | @ -365,13 +364,13 @@ glamor_xv_render(glamor_port_private *port_priv, int id) | |||
|         } | ||||
|     } | ||||
|     glamor_make_current(glamor_priv); | ||||
|     glUseProgram(glamor_priv->xv_prog.prog); | ||||
|     glUseProgram(port_priv->xv_prog.prog); | ||||
| 
 | ||||
|     uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "offsetyco"); | ||||
|     uloc = glGetUniformLocation(port_priv->xv_prog.prog, "offsetyco"); | ||||
|     glUniform4f(uloc, off[0], off[1], off[2], yco); | ||||
|     uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "ucogamma"); | ||||
|     uloc = glGetUniformLocation(port_priv->xv_prog.prog, "ucogamma"); | ||||
|     glUniform4f(uloc, uco[0], uco[1], uco[2], gamma); | ||||
|     uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "vco"); | ||||
|     uloc = glGetUniformLocation(port_priv->xv_prog.prog, "vco"); | ||||
|     glUniform4f(uloc, vco[0], vco[1], vco[2], 0); | ||||
| 
 | ||||
|     glActiveTexture(GL_TEXTURE0); | ||||
|  | @ -455,7 +454,7 @@ glamor_xv_render(glamor_port_private *port_priv, int id) | |||
|         glamor_set_destination_drawable(port_priv->pDraw, | ||||
|                                         dst_box_index, | ||||
|                                         FALSE, FALSE, | ||||
|                                         glamor_priv->xv_prog.matrix_uniform, | ||||
|                                         port_priv->xv_prog.matrix_uniform, | ||||
|                                         &dst_off_x, &dst_off_y); | ||||
| 
 | ||||
|         for (i = 0; i < nBox; i++) { | ||||
|  | @ -476,8 +475,25 @@ glamor_xv_render(glamor_port_private *port_priv, int id) | |||
|     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); | ||||
| 
 | ||||
|     DamageDamageRegion(port_priv->pDraw, &port_priv->clip); | ||||
| } | ||||
| 
 | ||||
|     glamor_xv_free_port_data(port_priv); | ||||
| static Bool | ||||
| glamor_xv_can_reuse_port(glamor_port_private *port_priv, int id, short w, short h) | ||||
| { | ||||
|     int ret = TRUE; | ||||
| 
 | ||||
|     if (port_priv->prev_fmt != id) | ||||
|         ret = FALSE; | ||||
| 
 | ||||
|     if (w != port_priv->src_pix_w || h != port_priv->src_pix_h) | ||||
|         ret = FALSE; | ||||
| 
 | ||||
|     if (!port_priv->src_pix[0]) | ||||
|         ret = FALSE; | ||||
| 
 | ||||
|     port_priv->prev_fmt = id; | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  | @ -495,7 +511,6 @@ glamor_xv_put_image(glamor_port_private *port_priv, | |||
|                     RegionPtr clipBoxes) | ||||
| { | ||||
|     ScreenPtr pScreen = pDrawable->pScreen; | ||||
|     glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); | ||||
|     int srcPitch, srcPitch2; | ||||
|     int top, nlines; | ||||
|     int s2offset, s3offset, tmp; | ||||
|  | @ -503,15 +518,14 @@ glamor_xv_put_image(glamor_port_private *port_priv, | |||
| 
 | ||||
|     s2offset = s3offset = srcPitch2 = 0; | ||||
| 
 | ||||
|     if (!port_priv->src_pix[0] || | ||||
|         (width != port_priv->src_pix_w || height != port_priv->src_pix_h) || | ||||
|         (port_priv->src_pix[2] && id == FOURCC_NV12) || | ||||
|         (!port_priv->src_pix[2] && id != FOURCC_NV12)) { | ||||
|     if (!glamor_xv_can_reuse_port(port_priv, id, width, height)) { | ||||
|         int i; | ||||
| 
 | ||||
|         if (glamor_priv->xv_prog.prog) { | ||||
|             glDeleteProgram(glamor_priv->xv_prog.prog); | ||||
|             glamor_priv->xv_prog.prog = 0; | ||||
|         glamor_xv_free_port_data(port_priv); | ||||
| 
 | ||||
|         if (port_priv->xv_prog.prog) { | ||||
|             glDeleteProgram(port_priv->xv_prog.prog); | ||||
|             port_priv->xv_prog.prog = 0; | ||||
|         } | ||||
| 
 | ||||
|         for (i = 0; i < 3; i++) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue