xserver: Branch 'master' - 6 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Dec 1 08:59:49 UTC 2023


 glamor/glamor_priv.h |    3 
 glamor/glamor_xv.c   |  288 ++++++++++++++++++++++++++++++++++++++++++---------
 include/fourcc.h     |   39 ++++++
 3 files changed, 280 insertions(+), 50 deletions(-)

New commits:
commit c170056111fe0b3c4956a34276b5683e24b8c63c
Author: Yuriy Vasilev <uuvasiliev at yandex.ru>
Date:   Fri Sep 10 16:20:06 2021 +0300

    glamor: xv: add rgb565
    
    This commit adds RGB565 format to XVideo with reuse of RGBA32 shader
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Yuriy Vasilev <uuvasiliev at yandex.ru>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index f368c0a9b..d897e9901 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -199,6 +199,7 @@ XvImageRec glamor_xv_images[] = {
     XVIMAGE_NV12,
     XVIMAGE_UYVY,
     XVIMAGE_RGB32,
+    XVIMAGE_RGB565,
 };
 int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
 
@@ -220,6 +221,7 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
         glamor_facet_xv_planar = &glamor_facet_xv_uyvy;
         break;
     case FOURCC_RGBA32:
+    case FOURCC_RGB565:
         glamor_facet_xv_planar = &glamor_facet_xv_rgb_raw;
         break;
     default:
@@ -250,6 +252,7 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
         break;
     case FOURCC_UYVY:
     case FOURCC_RGBA32:
+    case FOURCC_RGB565:
         sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "sampler");
         glUniform1i(sampler_loc, 0);
         break;
@@ -376,6 +379,7 @@ glamor_xv_query_image_attributes(int id,
             offsets[0] = 0;
         size *= *h;
         break;
+    case FOURCC_RGB565:
     case FOURCC_UYVY:
         /* UYVU is single-plane really, all tranformation is processed inside a shader */
         size = *w * 2;
@@ -516,6 +520,7 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         break;
     case FOURCC_RGBA32:
+    case FOURCC_RGB565:
         glActiveTexture(GL_TEXTURE0);
         glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -692,6 +697,13 @@ glamor_xv_put_image(glamor_port_private *port_priv,
             port_priv->src_pix[1] = NULL;
             port_priv->src_pix[2] = NULL;
             break;
+        case FOURCC_RGB565:
+            port_priv->src_pix[0] =
+            glamor_create_pixmap(pScreen, width, height, 16,
+                                     GLAMOR_CREATE_FBO_NO_FBO);
+            port_priv->src_pix[1] = NULL;
+            port_priv->src_pix[2] = NULL;
+            break;
         case FOURCC_UYVY:
             port_priv->src_pix[0] =
                 glamor_create_pixmap(pScreen, width, height, 32,
@@ -775,6 +787,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
                             buf + s2offset, srcPitch);
         break;
     case FOURCC_UYVY:
+    case FOURCC_RGB565:
         srcPitch = width * 2;
         full_box.x1 = 0;
         full_box.y1 = 0;
diff --git a/include/fourcc.h b/include/fourcc.h
index 582a95afe..83e51a888 100644
--- a/include/fourcc.h
+++ b/include/fourcc.h
@@ -195,4 +195,24 @@
 		 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
 		0 \
    }
+
+#define FOURCC_RGB565 0x36314752
+#define XVIMAGE_RGB565 \
+   { \
+        FOURCC_RGB565, \
+        XvRGB, \
+		LSBFirst, \
+		{'R','G','1','6', \
+		 0x00, 0x00, 0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+		16, \
+		XvPacked, \
+		1, \
+		16, 0xf800, 0x7e0, 0x1f, \
+		0, 0, 0, \
+		0, 0, 0, \
+		0, 0, 0, \
+		{0,0,0,0, \
+		 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+		0 \
+   }
 #endif                          /* _XF86_FOURCC_H_ */
commit 15412e78c83bf3d15bcd343ccc40afda072d3f9e
Author: Yuriy Vasilev <uuvasiliev at yandex.ru>
Date:   Thu Sep 9 18:14:02 2021 +0300

    glamor: xv: add rgba32 format
    
    This commit adds RGBA32 format to XVideo along with shader for handling it.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Yuriy Vasilev <uuvasiliev at yandex.ru>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 6a6e41ce1..f368c0a9b 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -161,6 +161,23 @@ static const glamor_facet glamor_facet_xv_uyvy = {
         ),
 };
 
+static const glamor_facet glamor_facet_xv_rgb_raw = {
+    .name = "xv_rgb",
+
+    .source_name = "v_texcoord0",
+    .vs_vars = ("in vec2 position;\n"
+                "in vec2 v_texcoord0;\n"
+                "out vec2 tcs;\n"),
+    .vs_exec = (GLAMOR_POS(gl_Position, position)
+                "        tcs = v_texcoord0;\n"),
+
+    .fs_vars = ("uniform sampler2D sampler;\n"
+                "in vec2 tcs;\n"),
+    .fs_exec = (
+                "        frag_color = texture2D(sampler, tcs);\n"
+                ),
+};
+
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
 XvAttributeRec glamor_xv_attributes[] = {
@@ -181,6 +198,7 @@ XvImageRec glamor_xv_images[] = {
     XVIMAGE_I420,
     XVIMAGE_NV12,
     XVIMAGE_UYVY,
+    XVIMAGE_RGB32,
 };
 int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
 
@@ -201,6 +219,9 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
     case FOURCC_UYVY:
         glamor_facet_xv_planar = &glamor_facet_xv_uyvy;
         break;
+    case FOURCC_RGBA32:
+        glamor_facet_xv_planar = &glamor_facet_xv_rgb_raw;
+        break;
     default:
         break;
     }
@@ -228,6 +249,7 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
         glUniform1i(sampler_loc, 1);
         break;
     case FOURCC_UYVY:
+    case FOURCC_RGBA32:
         sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "sampler");
         glUniform1i(sampler_loc, 0);
         break;
@@ -346,6 +368,14 @@ glamor_xv_query_image_attributes(int id,
         tmp *= (*h >> 1);
         size += tmp;
         break;
+    case FOURCC_RGBA32:
+        size = *w * 4;
+        if(pitches)
+            pitches[0] = size;
+        if(offsets)
+            offsets[0] = 0;
+        size *= *h;
+        break;
     case FOURCC_UYVY:
         /* UYVU is single-plane really, all tranformation is processed inside a shader */
         size = *w * 2;
@@ -485,6 +515,14 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         break;
+    case FOURCC_RGBA32:
+        glActiveTexture(GL_TEXTURE0);
+        glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        break;
     default:
         break;
     }
@@ -647,6 +685,13 @@ glamor_xv_put_image(glamor_port_private *port_priv,
             if (!port_priv->src_pix[1])
                 return BadAlloc;
             break;
+        case FOURCC_RGBA32:
+            port_priv->src_pix[0] =
+            glamor_create_pixmap(pScreen, width, height, 32,
+                                     GLAMOR_CREATE_FBO_NO_FBO);
+            port_priv->src_pix[1] = NULL;
+            port_priv->src_pix[2] = NULL;
+            break;
         case FOURCC_UYVY:
             port_priv->src_pix[0] =
                 glamor_create_pixmap(pScreen, width, height, 32,
@@ -739,6 +784,16 @@ glamor_xv_put_image(glamor_port_private *port_priv,
                             0, 0, 0, 0,
                             buf, srcPitch);
         break;
+    case FOURCC_RGBA32:
+        srcPitch = width * 4;
+        full_box.x1 = 0;
+        full_box.y1 = 0;
+        full_box.x2 = width;
+        full_box.y2 = height;
+        glamor_upload_boxes(&port_priv->src_pix[0]->drawable, &full_box, 1,
+                            0, 0, 0, 0,
+                            buf, srcPitch);
+        break;
     default:
         return BadMatch;
     }
diff --git a/include/fourcc.h b/include/fourcc.h
index a19e6869e..582a95afe 100644
--- a/include/fourcc.h
+++ b/include/fourcc.h
@@ -176,4 +176,23 @@
         XvTopToBottom \
    }
 
+#define FOURCC_RGBA32 0x34325241
+#define XVIMAGE_RGB32 \
+   { \
+        FOURCC_RGBA32, \
+        XvRGB, \
+		LSBFirst, \
+		{'R','A','2','4', \
+		 0x00, 0x00, 0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+		32, \
+		XvPacked, \
+		1, \
+		32, 0xff0000, 0xff00, 0xff, \
+		0, 0, 0, \
+		0, 0, 0, \
+		0, 0, 0, \
+		{0,0,0,0, \
+		 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+		0 \
+   }
 #endif                          /* _XF86_FOURCC_H_ */
commit 832b392f70450f164800d65546ec9adf15d642a2
Author: Konstantin <ria.freelander at gmail.com>
Date:   Tue Oct 19 15:03:35 2021 +0300

    glamor: xv: enable UYVY acceleration
    
    This commit adds UYVY format in XVideo for Glamor
    along with shader support.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Konstantin <ria.freelander at gmail.com>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index bbee58fb8..6a6e41ce1 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -120,6 +120,47 @@ static const glamor_facet glamor_facet_xv_planar_3 = {
                 ),
 };
 
+static const glamor_facet glamor_facet_xv_uyvy = {
+    .name = "xv_uyvy",
+
+    .source_name = "v_texcoord0",
+    .vs_vars = ("in vec2 position;\n"
+                "in vec2 v_texcoord0;\n"
+                "out vec2 tcs;\n"),
+    .vs_exec = (GLAMOR_POS(gl_Position, position)
+                "        tcs = v_texcoord0;\n"),
+
+    .fs_vars = ("#ifdef GL_ES\n"
+                "precision highp float;\n"
+                "#endif\n"
+                "uniform sampler2D sampler;\n"
+                "uniform vec2 texelSize;\n"
+                "uniform vec4 offsetyco;\n"
+                "uniform vec4 ucogamma;\n"
+                "uniform vec4 vco;\n"
+                "in vec2 tcs;\n"
+                ),
+    .fs_exec = (
+        "    vec3 uyv;\n"
+        "    vec4 frameOut = texture2D(sampler, tcs.st);\n"
+        "\n"
+        "    vec4 prevPixel = texture2D(sampler, vec2(tcs.s - texelSize.x, tcs.t));\n"
+        "    vec4 nextPixel = texture2D(sampler, vec2(tcs.s + texelSize.x, tcs.t));\n"
+        "\n"
+        "    float delta = 0.50;\n"
+        "\n"
+        "    int even = int(mod(tcs.x / texelSize.x, 2.0));\n"
+        "\n"
+        "    uyv.rgb = float(even)*vec3(frameOut.rg, nextPixel.r) + (1.0-float(even))*vec3(prevPixel.r, frameOut.gr);\n"
+        "\n"
+        "    frameOut.r = uyv.g + 1.403*(uyv.r - delta);\n"
+        "    frameOut.g = uyv.g - 0.714*(uyv.r - delta) - 0.344*(uyv.b - delta);\n"
+        "    frameOut.b = uyv.g + 1.773*(uyv.b - delta);\n"
+        "    frameOut.a = 1.0;\n"
+        "    frag_color = frameOut;\n"
+        ),
+};
+
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
 XvAttributeRec glamor_xv_attributes[] = {
@@ -138,7 +179,8 @@ Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue,
 XvImageRec glamor_xv_images[] = {
     XVIMAGE_YV12,
     XVIMAGE_I420,
-    XVIMAGE_NV12
+    XVIMAGE_NV12,
+    XVIMAGE_UYVY,
 };
 int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
 
@@ -156,6 +198,9 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
     case FOURCC_NV12:
         glamor_facet_xv_planar = &glamor_facet_xv_planar_2;
         break;
+    case FOURCC_UYVY:
+        glamor_facet_xv_planar = &glamor_facet_xv_uyvy;
+        break;
     default:
         break;
     }
@@ -182,6 +227,10 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
         sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "u_sampler");
         glUniform1i(sampler_loc, 1);
         break;
+    case FOURCC_UYVY:
+        sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "sampler");
+        glUniform1i(sampler_loc, 0);
+        break;
     default:
         break;
     }
@@ -297,6 +346,15 @@ glamor_xv_query_image_attributes(int id,
         tmp *= (*h >> 1);
         size += tmp;
         break;
+    case FOURCC_UYVY:
+        /* UYVU is single-plane really, all tranformation is processed inside a shader */
+        size = *w * 2;
+        if (pitches)
+            pitches[0] = size;
+        if (offsets)
+            offsets[0] = 0;
+        size *= *h;
+        break;
     }
     return size;
 }
@@ -377,16 +435,16 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
     uloc = glGetUniformLocation(port_priv->xv_prog.prog, "vco");
     glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
 
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
+        glActiveTexture(GL_TEXTURE0);
+        glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
         glActiveTexture(GL_TEXTURE1);
         glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -402,6 +460,13 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         break;
     case FOURCC_NV12:
+        glActiveTexture(GL_TEXTURE0);
+        glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
         glActiveTexture(GL_TEXTURE1);
         glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -409,6 +474,17 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         break;
+    case FOURCC_UYVY:
+        uloc = glGetUniformLocation(port_priv->xv_prog.prog, "texelSize");
+        glUniform2f(uloc, 1.0 / port_priv->w, 1.0 / port_priv->h);
+
+        glActiveTexture(GL_TEXTURE0);
+        glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        break;
     default:
         break;
     }
@@ -571,6 +647,14 @@ glamor_xv_put_image(glamor_port_private *port_priv,
             if (!port_priv->src_pix[1])
                 return BadAlloc;
             break;
+        case FOURCC_UYVY:
+            port_priv->src_pix[0] =
+                glamor_create_pixmap(pScreen, width, height, 32,
+                                     GLAMOR_CREATE_FBO_NO_FBO |
+                                     GLAMOR_CREATE_FORMAT_CBCR);
+            port_priv->src_pix[1] = NULL;
+            port_priv->src_pix[2] = NULL;
+            break;
         default:
             return BadMatch;
         }
@@ -645,6 +729,16 @@ glamor_xv_put_image(glamor_port_private *port_priv,
                             0, 0, 0, 0,
                             buf + s2offset, srcPitch);
         break;
+    case FOURCC_UYVY:
+        srcPitch = width * 2;
+        full_box.x1 = 0;
+        full_box.y1 = 0;
+        full_box.x2 = width;
+        full_box.y2 = height;
+        glamor_upload_boxes(&port_priv->src_pix[0]->drawable, &full_box, 1,
+                            0, 0, 0, 0,
+                            buf, srcPitch);
+        break;
     default:
         return BadMatch;
     }
commit ffd7151b109b8c598cd346d34b5233558409a03a
Author: Konstantin <ria.freelander at gmail.com>
Date:   Fri Oct 20 22:51:55 2023 +0300

    glamor: xv: prepare to one-plane formats
    
    As a preparation to one-plane formats (for example, UYVY), second
    texture definition is moved inside a format switch, and all allocations
    now also done inside a texture switch.
    No functional change.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Konstantin <ria.freelander at gmail.com>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index eba756555..bbee58fb8 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -165,18 +165,22 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
                          glamor_facet_xv_planar, NULL, NULL, NULL);
 
     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");
-    glUniform1i(sampler_loc, 1);
 
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
-        sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler");
+        sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "y_sampler");
+        glUniform1i(sampler_loc, 0);
+        sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "u_sampler");
+        glUniform1i(sampler_loc, 1);
+        sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "v_sampler");
         glUniform1i(sampler_loc, 2);
         break;
     case FOURCC_NV12:
+        sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "y_sampler");
+        glUniform1i(sampler_loc, 0);
+        sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "u_sampler");
+        glUniform1i(sampler_loc, 1);
         break;
     default:
         break;
@@ -380,16 +384,16 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-    glActiveTexture(GL_TEXTURE1);
-    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
+        glActiveTexture(GL_TEXTURE1);
+        glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
         glActiveTexture(GL_TEXTURE2);
         glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -398,6 +402,12 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         break;
     case FOURCC_NV12:
+        glActiveTexture(GL_TEXTURE1);
+        glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         break;
     default:
         break;
@@ -532,28 +542,34 @@ glamor_xv_put_image(glamor_port_private *port_priv,
             if (port_priv->src_pix[i])
                 glamor_destroy_pixmap(port_priv->src_pix[i]);
 
-        port_priv->src_pix[0] =
-            glamor_create_pixmap(pScreen, width, height, 8,
-                                 GLAMOR_CREATE_FBO_NO_FBO);
-
         switch (id) {
         case FOURCC_YV12:
         case FOURCC_I420:
+            port_priv->src_pix[0] =
+                glamor_create_pixmap(pScreen, width, height, 8,
+                                     GLAMOR_CREATE_FBO_NO_FBO);
+
             port_priv->src_pix[1] =
                 glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8,
                                      GLAMOR_CREATE_FBO_NO_FBO);
             port_priv->src_pix[2] =
                 glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8,
                                      GLAMOR_CREATE_FBO_NO_FBO);
-            if (!port_priv->src_pix[2])
+            if (!port_priv->src_pix[1] || !port_priv->src_pix[2])
                 return BadAlloc;
             break;
         case FOURCC_NV12:
+            port_priv->src_pix[0] =
+                glamor_create_pixmap(pScreen, width, height, 8,
+                                     GLAMOR_CREATE_FBO_NO_FBO);
             port_priv->src_pix[1] =
                 glamor_create_pixmap(pScreen, width >> 1, height >> 1, 16,
                                      GLAMOR_CREATE_FBO_NO_FBO |
                                      GLAMOR_CREATE_FORMAT_CBCR);
             port_priv->src_pix[2] = NULL;
+
+            if (!port_priv->src_pix[1])
+                return BadAlloc;
             break;
         default:
             return BadMatch;
@@ -562,7 +578,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
         port_priv->src_pix_w = width;
         port_priv->src_pix_h = height;
 
-        if (!port_priv->src_pix[0] || !port_priv->src_pix[1])
+        if (!port_priv->src_pix[0])
             return BadAlloc;
     }
 
commit 81ef43dd4ab22185ba63aaa271fdbb36dd39f0c9
Author: Konstantin <ria.freelander at gmail.com>
Date:   Fri Oct 20 22:45:11 2023 +0300

    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 at redhat.com>
    Signed-off-by: Konstantin <ria.freelander at gmail.com>

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++)
commit a8270fc5f0d5e934c266a8b243a35ebd83e2f08f
Author: Konstantin <ria.freelander at gmail.com>
Date:   Tue Oct 10 13:07:41 2023 +0300

    glamor: xv: do not force a version on XV shaders
    
    There is a no need to force a low version for XV shaders, it will
    work on higher version too.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Konstantin <ria.freelander at gmail.com>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 1548f8079..f68053e8c 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -62,8 +62,6 @@ typedef struct tagREF_TRANSFORM {
 static const glamor_facet glamor_facet_xv_planar_2 = {
     .name = "xv_planar_2",
 
-    .version = 120,
-
     .source_name = "v_texcoord0",
     .vs_vars = ("in vec2 position;\n"
                 "in vec2 v_texcoord0;\n"
@@ -94,8 +92,6 @@ static const glamor_facet glamor_facet_xv_planar_2 = {
 static const glamor_facet glamor_facet_xv_planar_3 = {
     .name = "xv_planar_3",
 
-    .version = 120,
-
     .source_name = "v_texcoord0",
     .vs_vars = ("in vec2 position;\n"
                 "in vec2 v_texcoord0;\n"


More information about the xorg-commit mailing list