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;
 | 
					    RegionRec clip;
 | 
				
			||||||
    PixmapPtr src_pix[3];       /* y, u, v for planar */
 | 
					    PixmapPtr src_pix[3];       /* y, u, v for planar */
 | 
				
			||||||
    int src_pix_w, src_pix_h;
 | 
					    int src_pix_w, src_pix_h;
 | 
				
			||||||
 | 
					    /* Port optimization */
 | 
				
			||||||
 | 
					    int prev_fmt;
 | 
				
			||||||
 | 
					    glamor_program xv_prog;
 | 
				
			||||||
} glamor_port_private;
 | 
					} glamor_port_private;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern XvAttributeRec glamor_xv_attributes[];
 | 
					extern XvAttributeRec glamor_xv_attributes[];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,9 +143,8 @@ XvImageRec glamor_xv_images[] = {
 | 
				
			||||||
int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
 | 
					int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					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;
 | 
					    GLint sampler_loc;
 | 
				
			||||||
    const glamor_facet *glamor_facet_xv_planar = NULL;
 | 
					    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_build_program(screen,
 | 
				
			||||||
                         &glamor_priv->xv_prog,
 | 
					                         &port_priv->xv_prog,
 | 
				
			||||||
                         glamor_facet_xv_planar, NULL, NULL, NULL);
 | 
					                         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");
 | 
					    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler");
 | 
				
			||||||
    glUniform1i(sampler_loc, 0);
 | 
					    glUniform1i(sampler_loc, 0);
 | 
				
			||||||
    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler");
 | 
					    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;
 | 
					    char *vbo_offset;
 | 
				
			||||||
    int dst_box_index;
 | 
					    int dst_box_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!glamor_priv->xv_prog.prog)
 | 
					    if (!port_priv->xv_prog.prog)
 | 
				
			||||||
        glamor_init_xv_shader(screen, id);
 | 
					        glamor_init_xv_shader(screen, port_priv, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cont = RTFContrast(port_priv->contrast);
 | 
					    cont = RTFContrast(port_priv->contrast);
 | 
				
			||||||
    bright = RTFBrightness(port_priv->brightness);
 | 
					    bright = RTFBrightness(port_priv->brightness);
 | 
				
			||||||
| 
						 | 
					@ -365,13 +364,13 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    glamor_make_current(glamor_priv);
 | 
					    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);
 | 
					    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);
 | 
					    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);
 | 
					    glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    glActiveTexture(GL_TEXTURE0);
 | 
					    glActiveTexture(GL_TEXTURE0);
 | 
				
			||||||
| 
						 | 
					@ -455,7 +454,7 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
 | 
				
			||||||
        glamor_set_destination_drawable(port_priv->pDraw,
 | 
					        glamor_set_destination_drawable(port_priv->pDraw,
 | 
				
			||||||
                                        dst_box_index,
 | 
					                                        dst_box_index,
 | 
				
			||||||
                                        FALSE, FALSE,
 | 
					                                        FALSE, FALSE,
 | 
				
			||||||
                                        glamor_priv->xv_prog.matrix_uniform,
 | 
					                                        port_priv->xv_prog.matrix_uniform,
 | 
				
			||||||
                                        &dst_off_x, &dst_off_y);
 | 
					                                        &dst_off_x, &dst_off_y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = 0; i < nBox; i++) {
 | 
					        for (i = 0; i < nBox; i++) {
 | 
				
			||||||
| 
						 | 
					@ -476,8 +475,25 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
 | 
				
			||||||
    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 | 
					    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
 | 
					    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
 | 
					int
 | 
				
			||||||
| 
						 | 
					@ -495,7 +511,6 @@ glamor_xv_put_image(glamor_port_private *port_priv,
 | 
				
			||||||
                    RegionPtr clipBoxes)
 | 
					                    RegionPtr clipBoxes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ScreenPtr pScreen = pDrawable->pScreen;
 | 
					    ScreenPtr pScreen = pDrawable->pScreen;
 | 
				
			||||||
    glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
 | 
					 | 
				
			||||||
    int srcPitch, srcPitch2;
 | 
					    int srcPitch, srcPitch2;
 | 
				
			||||||
    int top, nlines;
 | 
					    int top, nlines;
 | 
				
			||||||
    int s2offset, s3offset, tmp;
 | 
					    int s2offset, s3offset, tmp;
 | 
				
			||||||
| 
						 | 
					@ -503,15 +518,14 @@ glamor_xv_put_image(glamor_port_private *port_priv,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s2offset = s3offset = srcPitch2 = 0;
 | 
					    s2offset = s3offset = srcPitch2 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!port_priv->src_pix[0] ||
 | 
					    if (!glamor_xv_can_reuse_port(port_priv, id, width, height)) {
 | 
				
			||||||
        (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)) {
 | 
					 | 
				
			||||||
        int i;
 | 
					        int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (glamor_priv->xv_prog.prog) {
 | 
					        glamor_xv_free_port_data(port_priv);
 | 
				
			||||||
            glDeleteProgram(glamor_priv->xv_prog.prog);
 | 
					
 | 
				
			||||||
            glamor_priv->xv_prog.prog = 0;
 | 
					        if (port_priv->xv_prog.prog) {
 | 
				
			||||||
 | 
					            glDeleteProgram(port_priv->xv_prog.prog);
 | 
				
			||||||
 | 
					            port_priv->xv_prog.prog = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = 0; i < 3; i++)
 | 
					        for (i = 0; i < 3; i++)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue