summaryrefslogtreecommitdiff
path: root/glamor
diff options
context:
space:
mode:
authorKonstantin <ria.freelander@gmail.com>2023-10-20 22:45:11 +0300
committerKonstantin <ria.freelander@gmail.com>2023-11-29 21:18:29 +0000
commit81ef43dd4ab22185ba63aaa271fdbb36dd39f0c9 (patch)
tree4fb3dcc40aa150785c4e5b5f6ad5271145591802 /glamor
parenta8270fc5f0d5e934c266a8b243a35ebd83e2f08f (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.h3
-rw-r--r--glamor/glamor_xv.c54
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++)