Title: [294935] trunk/Source/WebCore/platform/graphics
Revision
294935
Author
commit-qu...@webkit.org
Date
2022-05-27 04:03:47 -0700 (Fri, 27 May 2022)

Log Message

[TextureMapper] Generalize YUV-to-RGB matrices
https://bugs.webkit.org/show_bug.cgi?id=240952

Patch by Žan Doberšek <zdober...@igalia.com> on 2022-05-27
Reviewed by Miguel Gomez.

Right now, TextureMapper supports converting YUV data to RGB when using either
the BT.601 or BT.709 colorspaces. The caller provides the basic 3x3 conversion
matrix for the given colorspace, and the offsets agains the initial YUV values
are hard-coded in the shader since they are the same for both colorspaces.

To support additional colorspaces (which don't share the same offset values) the
matrix handling has to be generalized. This means every conversion matrix is now
4x4 in size, with the adjusted offset values residing in the last column.

* Source/WebCore/platform/graphics/gstreamer/GStreamerVideoFrameHolder.cpp:
(WebCore::GstVideoFrameHolder::platformLayerBuffer):
* Source/WebCore/platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp:
(WebCore::VideoTextureCopierGStreamer::copyVideoTextureToPlatformTexture):
* Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp:
(WebCore::TextureMapperGL::drawTexturePlanarYUV):
(WebCore::TextureMapperGL::drawTextureSemiPlanarYUV):
(WebCore::TextureMapperGL::drawTexturePackedYUV):
* Source/WebCore/platform/graphics/texmap/TextureMapperGL.h:
* Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h:
* Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxyDMABuf.cpp:
(WebCore::TextureMapperPlatformLayerProxyDMABuf::DMABufLayer::paintToTextureMapper):
* Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp:

Canonical link: https://commits.webkit.org/251046@main

Modified Paths

Diff

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVideoFrameHolder.cpp (294934 => 294935)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVideoFrameHolder.cpp	2022-05-27 08:47:21 UTC (rev 294934)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVideoFrameHolder.cpp	2022-05-27 11:03:47 UTC (rev 294935)
@@ -203,19 +203,21 @@
             yuvPlaneOffset[i] = GST_VIDEO_INFO_COMP_POFFSET(&m_videoFrame.info, i);
         }
 
-        std::array<GLfloat, 9> yuvToRgb;
+        std::array<GLfloat, 16> yuvToRgb;
         if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(&m_videoFrame.info), GST_VIDEO_COLORIMETRY_BT709)) {
             yuvToRgb = {
-                1.164f,  0.0f,    1.787f,
-                1.164f, -0.213f, -0.531f,
-                1.164f,  2.112f,  0.0f
+                1.164383561643836f, -0.0f,                1.792741071428571f, -0.972945075016308f,
+                1.164383561643836f, -0.213248614273739f, -0.532909328559444f,  0.301482665475862f,
+                1.164383561643836f,  2.112401785714286f, -0.0f,               -1.133402217873451f,
+                0.0f,                0.0f,                0.0f,                1.0f,
             };
         } else {
             // Default to bt601. This is the same behaviour as GStreamer's glcolorconvert element.
             yuvToRgb = {
-                1.164f,  0.0f,    1.596f,
-                1.164f, -0.391f, -0.813f,
-                1.164f,  2.018f,  0.0f
+                1.164383561643836f,  0.0f,                1.596026785714286f, -0.874202217873451f,
+                1.164383561643836f, -0.391762290094914f, -0.812967647237771f,  0.531667823499146f,
+                1.164383561643836f,  2.017232142857143f, -0.0f,               -1.085630789302022f,
+                0.0f,                0.0f,                0.0f,                1.0f,
             };
         }
 

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp (294934 => 294935)


--- trunk/Source/WebCore/platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp	2022-05-27 08:47:21 UTC (rev 294934)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp	2022-05-27 11:03:47 UTC (rev 294935)
@@ -260,7 +260,7 @@
                 glUniform1i(m_shaderProgram->samplerALocation(), texture.yuvPlane[3]);
                 break;
             }
-            glUniformMatrix3fv(m_shaderProgram->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&texture.yuvToRgbMatrix[0]));
+            glUniformMatrix4fv(m_shaderProgram->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&texture.yuvToRgbMatrix[0]));
 
             for (int i = texture.numberOfPlanes - 1; i >= 0; --i) {
                 glActiveTexture(GL_TEXTURE0 + i);

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp (294934 => 294935)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp	2022-05-27 08:47:21 UTC (rev 294934)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp	2022-05-27 11:03:47 UTC (rev 294935)
@@ -542,7 +542,7 @@
         patternTransform.translate(0, -1);
 }
 
-void TextureMapperGL::drawTexturePlanarYUV(const std::array<GLuint, 3>& textures, const std::array<GLfloat, 9>& yuvToRgbMatrix, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, std::optional<GLuint> alphaPlane, unsigned exposedEdges)
+void TextureMapperGL::drawTexturePlanarYUV(const std::array<GLuint, 3>& textures, const std::array<GLfloat, 16>& yuvToRgbMatrix, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, std::optional<GLuint> alphaPlane, unsigned exposedEdges)
 {
     bool useRect = flags & ShouldUseARBTextureRect;
     bool useAntialiasing = m_enableEdgeDistanceAntialiasing
@@ -601,11 +601,11 @@
         texturesAndSamplers.append({*alphaPlane, program->samplerALocation() });
 
     glUseProgram(program->programID());
-    glUniformMatrix3fv(program->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&yuvToRgbMatrix[0]));
+    glUniformMatrix4fv(program->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&yuvToRgbMatrix[0]));
     drawTexturedQuadWithProgram(program.get(), texturesAndSamplers, flags, textureSize, targetRect, modelViewMatrix, opacity);
 }
 
-void TextureMapperGL::drawTextureSemiPlanarYUV(const std::array<GLuint, 2>& textures, bool uvReversed, const std::array<GLfloat, 9>& yuvToRgbMatrix, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges)
+void TextureMapperGL::drawTextureSemiPlanarYUV(const std::array<GLuint, 2>& textures, bool uvReversed, const std::array<GLfloat, 16>& yuvToRgbMatrix, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges)
 {
     bool useRect = flags & ShouldUseARBTextureRect;
     bool useAntialiasing = m_enableEdgeDistanceAntialiasing
@@ -658,11 +658,11 @@
     };
 
     glUseProgram(program->programID());
-    glUniformMatrix3fv(program->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&yuvToRgbMatrix[0]));
+    glUniformMatrix4fv(program->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&yuvToRgbMatrix[0]));
     drawTexturedQuadWithProgram(program.get(), texturesAndSamplers, flags, textureSize, targetRect, modelViewMatrix, opacity);
 }
 
-void TextureMapperGL::drawTexturePackedYUV(GLuint texture, const std::array<GLfloat, 9>& yuvToRgbMatrix, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges)
+void TextureMapperGL::drawTexturePackedYUV(GLuint texture, const std::array<GLfloat, 16>& yuvToRgbMatrix, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges)
 {
     bool useRect = flags & ShouldUseARBTextureRect;
     bool useAntialiasing = m_enableEdgeDistanceAntialiasing
@@ -713,7 +713,7 @@
     };
 
     glUseProgram(program->programID());
-    glUniformMatrix3fv(program->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&yuvToRgbMatrix[0]));
+    glUniformMatrix4fv(program->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&yuvToRgbMatrix[0]));
     drawTexturedQuadWithProgram(program.get(), texturesAndSamplers, flags, textureSize, targetRect, modelViewMatrix, opacity);
 }
 

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h (294934 => 294935)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h	2022-05-27 08:47:21 UTC (rev 294934)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h	2022-05-27 11:03:47 UTC (rev 294935)
@@ -68,9 +68,9 @@
     void drawNumber(int number, const Color&, const FloatPoint&, const TransformationMatrix&) override;
     void drawTexture(const BitmapTexture&, const FloatRect&, const TransformationMatrix&, float opacity, unsigned exposedEdges) override;
     virtual void drawTexture(GLuint texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges = AllEdges);
-    void drawTexturePlanarYUV(const std::array<GLuint, 3>& textures, const std::array<GLfloat, 9>& yuvToRgbMatrix, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, std::optional<GLuint> alphaPlane, unsigned exposedEdges = AllEdges);
-    void drawTextureSemiPlanarYUV(const std::array<GLuint, 2>& textures, bool uvReversed, const std::array<GLfloat, 9>& yuvToRgbMatrix, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges = AllEdges);
-    void drawTexturePackedYUV(GLuint texture, const std::array<GLfloat, 9>& yuvToRgbMatrix, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges = AllEdges);
+    void drawTexturePlanarYUV(const std::array<GLuint, 3>& textures, const std::array<GLfloat, 16>& yuvToRgbMatrix, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, std::optional<GLuint> alphaPlane, unsigned exposedEdges = AllEdges);
+    void drawTextureSemiPlanarYUV(const std::array<GLuint, 2>& textures, bool uvReversed, const std::array<GLfloat, 16>& yuvToRgbMatrix, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges = AllEdges);
+    void drawTexturePackedYUV(GLuint texture, const std::array<GLfloat, 16>& yuvToRgbMatrix, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges = AllEdges);
     void drawSolidColor(const FloatRect&, const TransformationMatrix&, const Color&, bool) override;
     void clearColor(const Color&) override;
 

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h (294934 => 294935)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h	2022-05-27 08:47:21 UTC (rev 294934)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h	2022-05-27 11:03:47 UTC (rev 294935)
@@ -51,7 +51,7 @@
         std::array<GLuint, 4> planes;
         std::array<unsigned, 4> yuvPlane;
         std::array<unsigned, 4> yuvPlaneOffset;
-        std::array<GLfloat, 9> yuvToRgbMatrix;
+        std::array<GLfloat, 16> yuvToRgbMatrix;
     };
     struct ExternalOESTexture {
         GLuint id;

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxyDMABuf.cpp (294934 => 294935)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxyDMABuf.cpp	2022-05-27 08:47:21 UTC (rev 294934)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxyDMABuf.cpp	2022-05-27 11:03:47 UTC (rev 294935)
@@ -197,10 +197,11 @@
 
     // TODO: this is the BT.601 colorspace conversion matrix. The exact desired colorspace should be included
     // in the DMABufObject, and the relevant matrix decided based on it. BT.601 should remain the default.
-    static constexpr std::array<GLfloat, 9> s_yuvToRGB {
-        1.164f,  0.0f,    1.596f,
-        1.164f, -0.391f, -0.813f,
-        1.164f,  2.018f,  0.0f
+    static constexpr std::array<GLfloat, 16> s_yuvToRGB {
+        1.164383561643836f,  0.0f,                1.596026785714286f, -0.874202217873451f,
+        1.164383561643836f, -0.391762290094914f, -0.812967647237771f,  0.531667823499146f,
+        1.164383561643836f,  2.017232142857143f, -0.0f,               -1.085630789302022f,
+        0.0f,                0.0f,                0.0f,                1.0f,
     };
 
     TextureMapperGL& texmapGL = static_cast<TextureMapperGL&>(textureMapper);

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp (294934 => 294935)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp	2022-05-27 08:47:21 UTC (rev 294934)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp	2022-05-27 11:03:47 UTC (rev 294935)
@@ -238,7 +238,7 @@
         uniform SamplerExternalOESType s_externalOESTexture;
         uniform float u_opacity;
         uniform float u_filterAmount;
-        uniform mat3 u_yuvToRgb;
+        uniform mat4 u_yuvToRgb;
         uniform vec2 u_blurRadius;
         uniform vec2 u_shadowOffset;
         uniform vec4 u_color;
@@ -269,9 +269,8 @@
 
         vec3 yuvToRgb(float y, float u, float v)
         {
-            // yuv is either bt601 or bt709 so the offset is the same
-            vec3 yuv = vec3(y - 0.0625, u - 0.5, v - 0.5);
-            return yuv * u_yuvToRgb;
+            vec4 rgb = vec4(y, u, v, 1.0) * u_yuvToRgb;
+            return rgb.xyz;
         }
         void applyTextureYUV(inout vec4 color, vec2 texCoord)
         {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to