diff options
author | Konstantin <ria.freelander@gmail.com> | 2023-10-20 22:45:11 +0300 |
---|---|---|
committer | Konstantin <ria.freelander@gmail.com> | 2023-11-29 21:18:29 +0000 |
commit | 81ef43dd4ab22185ba63aaa271fdbb36dd39f0c9 (patch) | |
tree | 4fb3dcc40aa150785c4e5b5f6ad5271145591802 /glamor | |
parent | a8270fc5f0d5e934c266a8b243a35ebd83e2f08f (diff) |
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>
Diffstat (limited to 'glamor')
-rw-r--r-- | glamor/glamor_priv.h | 3 | ||||
-rw-r--r-- | glamor/glamor_xv.c | 54 |
2 files changed, 37 insertions, 20 deletions
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 610af5315..76570febd 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -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[]; diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index f68053e8c..eba756555 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -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); +} + +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; - glamor_xv_free_port_data(port_priv); + 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++) |