Title: [258197] trunk/Source/WebCore
Revision
258197
Author
[email protected]
Date
2020-03-10 05:08:53 -0700 (Tue, 10 Mar 2020)

Log Message

[GStreamer][GL] External OES textures rendering support
https://bugs.webkit.org/show_bug.cgi?id=208572

Patch by Philippe Normand <[email protected]> on 2020-03-10
Reviewed by Žan Doberšek.

For hardware that contains native YUV samplers, some drivers may
only support external-oes import of YUV textures, so by supporting
this texture target in the MediaPlayer we can avoid some costly
operations in the pipeline.

* platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp:
(webKitGLVideoSinkSetMediaPlayerPrivate):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::GstVideoFrameHolder::GstVideoFrameHolder):
(WebCore::GstVideoFrameHolder::platformLayerBuffer):
(WebCore::MediaPlayerPrivateGStreamer::paint):
* platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp:
(WebCore::VideoTextureCopierGStreamer::copyVideoTextureToPlatformTexture):
* platform/graphics/texmap/TextureMapperGL.cpp:
(WebCore::TextureMapperGL::drawTexturedQuadWithProgram):
(WebCore::TextureMapperGL::drawTextureExternalOES):
* platform/graphics/texmap/TextureMapperGL.h:
* platform/graphics/texmap/TextureMapperPlatformLayerBuffer.cpp:
(WebCore::TextureMapperPlatformLayerBuffer::clone):
(WebCore::TextureMapperPlatformLayerBuffer::paintToTextureMapper):
* platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h:
* platform/graphics/texmap/TextureMapperShaderProgram.cpp:
(WebCore::TextureMapperShaderProgram::create):
* platform/graphics/texmap/TextureMapperShaderProgram.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (258196 => 258197)


--- trunk/Source/WebCore/ChangeLog	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/ChangeLog	2020-03-10 12:08:53 UTC (rev 258197)
@@ -1,3 +1,35 @@
+2020-03-10  Philippe Normand  <[email protected]>
+
+        [GStreamer][GL] External OES textures rendering support
+        https://bugs.webkit.org/show_bug.cgi?id=208572
+
+        Reviewed by Žan Doberšek.
+
+        For hardware that contains native YUV samplers, some drivers may
+        only support external-oes import of YUV textures, so by supporting
+        this texture target in the MediaPlayer we can avoid some costly
+        operations in the pipeline.
+
+        * platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp:
+        (webKitGLVideoSinkSetMediaPlayerPrivate):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::GstVideoFrameHolder::GstVideoFrameHolder):
+        (WebCore::GstVideoFrameHolder::platformLayerBuffer):
+        (WebCore::MediaPlayerPrivateGStreamer::paint):
+        * platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp:
+        (WebCore::VideoTextureCopierGStreamer::copyVideoTextureToPlatformTexture):
+        * platform/graphics/texmap/TextureMapperGL.cpp:
+        (WebCore::TextureMapperGL::drawTexturedQuadWithProgram):
+        (WebCore::TextureMapperGL::drawTextureExternalOES):
+        * platform/graphics/texmap/TextureMapperGL.h:
+        * platform/graphics/texmap/TextureMapperPlatformLayerBuffer.cpp:
+        (WebCore::TextureMapperPlatformLayerBuffer::clone):
+        (WebCore::TextureMapperPlatformLayerBuffer::paintToTextureMapper):
+        * platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h:
+        * platform/graphics/texmap/TextureMapperShaderProgram.cpp:
+        (WebCore::TextureMapperShaderProgram::create):
+        * platform/graphics/texmap/TextureMapperShaderProgram.h:
+
 2020-03-10  Rob Buis  <[email protected]>
 
         Align with Origin header changes

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (258196 => 258197)


--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp	2020-03-10 12:08:53 UTC (rev 258197)
@@ -196,10 +196,13 @@
 #if USE(GSTREAMER_GL)
         m_flags = flags | (m_hasAlphaChannel ? TextureMapperGL::ShouldBlend : 0);
 
+        GstMemory* memory = gst_buffer_peek_memory(m_buffer.get(), 0);
+        if (gst_is_gl_memory(memory))
+            m_textureTarget = gst_gl_memory_get_texture_target(GST_GL_MEMORY_CAST(memory));
+
 #if USE(WPE_VIDEO_PLANE_DISPLAY_DMABUF)
         m_dmabufFD = -1;
         gsize offset;
-        GstMemory* memory = gst_buffer_peek_memory(m_buffer.get(), 0);
         if (gst_is_gl_memory_egl(memory)) {
             GstGLMemoryEGL* eglMemory = (GstGLMemoryEGL*) memory;
             gst_egl_image_export_dmabuf(eglMemory->image, &m_dmabufFD, &m_dmabufStride, &offset);
@@ -321,8 +324,11 @@
 
         using Buffer = TextureMapperPlatformLayerBuffer;
 
+        if (m_textureTarget == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
+            return makeUnique<Buffer>(Buffer::TextureVariant { Buffer::ExternalOESTexture { m_textureID } }, m_size, m_flags, GL_DONT_CARE);
+
         if ((GST_VIDEO_INFO_IS_RGB(&m_videoFrame.info) && GST_VIDEO_INFO_N_PLANES(&m_videoFrame.info) == 1))
-            return makeUnique<Buffer>(Buffer::TextureVariant { Buffer::RGBTexture { *static_cast<GLuint*>(m_videoFrame.data[0]) } }, m_size, m_flags, GL_RGBA);
+            return makeUnique<Buffer>(Buffer::TextureVariant { Buffer::RGBTexture { m_textureID } }, m_size, m_flags, GL_RGBA);
 
         if (GST_VIDEO_INFO_IS_YUV(&m_videoFrame.info)) {
             if (GST_VIDEO_INFO_N_COMPONENTS(&m_videoFrame.info) < 3 || GST_VIDEO_INFO_N_PLANES(&m_videoFrame.info) > 3)
@@ -332,7 +338,7 @@
                 // IMX VPU decoder decodes YUV data only into the Y texture from which the sampler
                 // then directly produces RGBA data. Textures for other planes aren't used, but
                 // that's decoder's problem. We have to treat that Y texture as having RGBA data.
-                return makeUnique<Buffer>(Buffer::TextureVariant { Buffer::RGBTexture { *static_cast<GLuint*>(m_videoFrame.data[0]) } }, m_size, m_flags, GL_RGBA);
+                return makeUnique<Buffer>(Buffer::TextureVariant { Buffer::RGBTexture { m_textureID } }, m_size, m_flags, GL_RGBA);
             }
 
             unsigned numberOfPlanes = GST_VIDEO_INFO_N_PLANES(&m_videoFrame.info);
@@ -385,6 +391,7 @@
     Optional<GstVideoDecoderPlatform> m_videoDecoderPlatform;
     TextureMapperGL::Flags m_flags { };
     GLuint m_textureID { 0 };
+    GstGLTextureTarget m_textureTarget { GST_GL_TEXTURE_TARGET_NONE };
     bool m_isMapped { false };
     bool m_hasMappedTextures { false };
 #if USE(WPE_VIDEO_PLANE_DISPLAY_DMABUF)
@@ -3334,13 +3341,15 @@
     if (!gst_video_info_from_caps(&videoInfo, caps))
         return;
 
-    if (!GST_VIDEO_INFO_IS_RGB(&videoInfo)) {
-        if (!m_colorConvert) {
-            GstMemory* mem = gst_buffer_peek_memory(buffer, 0);
-            GstGLContext* context = ((GstGLBaseMemory*)mem)->context;
-            m_colorConvert = adoptGRef(gst_gl_color_convert_new(context));
-        }
+    GstMemory* memory = gst_buffer_peek_memory(buffer, 0);
+    bool hasExternalOESTexture = false;
+    if (gst_is_gl_memory(memory))
+        hasExternalOESTexture = gst_gl_memory_get_texture_target(GST_GL_MEMORY_CAST(memory)) == GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
 
+    if (!GST_VIDEO_INFO_IS_RGB(&videoInfo) || hasExternalOESTexture) {
+        if (!m_colorConvert)
+            m_colorConvert = adoptGRef(gst_gl_color_convert_new(GST_GL_BASE_MEMORY_CAST(memory)->context));
+
         if (!m_colorConvertInputCaps || !gst_caps_is_equal(m_colorConvertInputCaps.get(), caps)) {
             m_colorConvertInputCaps = caps;
             m_colorConvertOutputCaps = adoptGRef(gst_caps_copy(caps));
@@ -3349,7 +3358,8 @@
 #else
             const char* formatString = GST_VIDEO_INFO_HAS_ALPHA(&videoInfo) ? "RGBA" : "RGBx";
 #endif
-            gst_caps_set_simple(m_colorConvertOutputCaps.get(), "format", G_TYPE_STRING, formatString, nullptr);
+            gst_caps_set_simple(m_colorConvertOutputCaps.get(), "format", G_TYPE_STRING, formatString,
+                "texture-target", G_TYPE_STRING, GST_GL_TEXTURE_TARGET_2D_STR, nullptr);
             if (!gst_gl_color_convert_set_caps(m_colorConvert.get(), caps, m_colorConvertOutputCaps.get()))
                 return;
         }

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


--- trunk/Source/WebCore/platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp	2020-03-10 12:08:53 UTC (rev 258197)
@@ -178,7 +178,11 @@
                 options = TextureMapperShaderProgram::TextureYUV;
                 break;
             }
-        });
+        },
+        [&](const Buffer::ExternalOESTexture&) {
+            options = TextureMapperShaderProgram::TextureExternalOES;
+        }
+    );
 
     if (options != m_shaderOptions) {
         m_shaderProgram = TextureMapperShaderProgram::create(options);
@@ -252,6 +256,15 @@
                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
             }
+        },
+        [&](const Buffer::ExternalOESTexture& texture) {
+            glUniform1i(m_shaderProgram->externalOESTextureLocation(), 0);
+
+            glActiveTexture(GL_TEXTURE0);
+            glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture.id);
+            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+            glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         });
 
     m_shaderProgram->setMatrix(m_shaderProgram->modelViewMatrixLocation(), m_modelViewMatrix);

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


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp	2020-03-10 12:08:53 UTC (rev 258197)
@@ -773,7 +773,12 @@
     glUseProgram(program.programID());
 
     bool repeatWrap = wrapMode() == RepeatWrap && m_contextAttributes.supportsNPOTTextures;
-    GLenum target = flags & ShouldUseARBTextureRect ? GLenum(GL_TEXTURE_RECTANGLE_ARB) : GLenum(GL_TEXTURE_2D);
+    GLenum target;
+    if (flags & ShouldUseExternalOESTextureRect)
+        target = GLenum(GL_TEXTURE_EXTERNAL_OES);
+    else
+        target = flags & ShouldUseARBTextureRect ? GLenum(GL_TEXTURE_RECTANGLE_ARB) : GLenum(GL_TEXTURE_2D);
+
     for (unsigned i = 0; i < texturesAndSamplers.size(); ++i) {
         auto& textureAndSampler = texturesAndSamplers[i];
 
@@ -961,6 +966,13 @@
     return makeUnique<TextureMapperGL>();
 }
 
+void TextureMapperGL::drawTextureExternalOES(GLuint texture, Flags flags, const IntSize& size, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity)
+{
+    Ref<TextureMapperShaderProgram> program = data().getShaderProgram(TextureMapperShaderProgram::Option::TextureExternalOES);
+    drawTexturedQuadWithProgram(program.get(), { { texture, program->externalOESTextureLocation() } },
+        flags | TextureMapperGL::ShouldUseExternalOESTextureRect, size, targetRect, modelViewMatrix, opacity);
+}
+
 };
 
 #endif // USE(TEXTURE_MAPPER_GL)

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


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h	2020-03-10 12:08:53 UTC (rev 258197)
@@ -56,7 +56,8 @@
         ShouldRotateTexture270 = 0x40,
         ShouldConvertTextureBGRAToRGBA = 0x80,
         ShouldConvertTextureARGBToRGBA = 0x100,
-        ShouldNotBlend = 0x200
+        ShouldNotBlend = 0x200,
+        ShouldUseExternalOESTextureRect = 0x400
     };
 
     typedef int Flags;
@@ -86,6 +87,7 @@
     void drawFiltered(const BitmapTexture& sourceTexture, const BitmapTexture* contentTexture, const FilterOperation&, int pass);
 
     void setEnableEdgeDistanceAntialiasing(bool enabled) { m_enableEdgeDistanceAntialiasing = enabled; }
+    void drawTextureExternalOES(GLuint texture, Flags, const IntSize&, const FloatRect&, const TransformationMatrix& modelViewMatrix, float opacity);
 
 private:
     void drawTexturedQuadWithProgram(TextureMapperShaderProgram&, uint32_t texture, Flags, const IntSize&, const FloatRect&, const TransformationMatrix& modelViewMatrix, float opacity);

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGLHeaders.h (258196 => 258197)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGLHeaders.h	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGLHeaders.h	2020-03-10 12:08:53 UTC (rev 258197)
@@ -52,3 +52,7 @@
 #ifndef GL_UNPACK_SKIP_PIXELS
 #define GL_UNPACK_SKIP_PIXELS 0x0CF4
 #endif
+
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.cpp (258196 => 258197)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.cpp	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.cpp	2020-03-10 12:08:53 UTC (rev 258197)
@@ -87,6 +87,11 @@
         {
             notImplemented();
             return nullptr;
+        },
+        [](const ExternalOESTexture&)
+        {
+            notImplemented();
+            return nullptr;
         });
 }
 
@@ -141,6 +146,10 @@
                     texture.yuvToRgbMatrix, m_extraFlags, m_size, targetRect, modelViewMatrix, opacity);
                 break;
             }
+        },
+        [&](const ExternalOESTexture& texture) {
+            ASSERT(texture.id);
+            texmapGL.drawTextureExternalOES(texture.id, m_extraFlags, m_size, targetRect, modelViewMatrix, opacity);
         });
 }
 

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


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h	2020-03-10 12:08:53 UTC (rev 258197)
@@ -53,7 +53,10 @@
         std::array<unsigned, 3> yuvPlaneOffset;
         std::array<GLfloat, 9> yuvToRgbMatrix;
     };
-    using TextureVariant = WTF::Variant<RGBTexture, YUVTexture>;
+    struct ExternalOESTexture {
+        GLuint id;
+    };
+    using TextureVariant = WTF::Variant<RGBTexture, YUVTexture, ExternalOESTexture>;
 
     TextureMapperPlatformLayerBuffer(TextureVariant&&, const IntSize&, TextureMapperGL::Flags, GLint internalFormat);
 

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


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp	2020-03-10 12:08:53 UTC (rev 258197)
@@ -160,6 +160,14 @@
     GLSL_DIRECTIVE(define GAUSSIAN_KERNEL_STEP 0.2)
 
 
+#define OES_EGL_IMAGE_EXTERNAL_DIRECTIVE \
+    GLSL_DIRECTIVE(ifdef ENABLE_TextureExternalOES) \
+        GLSL_DIRECTIVE(extension GL_OES_EGL_image_external : require) \
+        GLSL_DIRECTIVE(define SamplerExternalOESType samplerExternalOES) \
+    GLSL_DIRECTIVE(else) \
+        GLSL_DIRECTIVE(define SamplerExternalOESType sampler2D) \
+    GLSL_DIRECTIVE(endif)
+
 // Common header for all versions. We define the matrices variables here to keep the precision
 // directives scope: the first one applies to the matrices variables and the next one to the
 // rest of them. The precision is only used in GLES.
@@ -167,10 +175,9 @@
     RECT_TEXTURE_DIRECTIVE
     ANTIALIASING_TEX_COORD_DIRECTIVE
     BLUR_CONSTANTS
+    OES_EGL_IMAGE_EXTERNAL_DIRECTIVE
 #if USE(OPENGL_ES)
     TEXTURE_SPACE_MATRIX_PRECISION_DIRECTIVE
-#endif
-#if USE(OPENGL_ES)
     STRINGIFY(
         precision TextureSpaceMatrixPrecision float;
     )
@@ -211,6 +218,7 @@
         uniform SamplerType s_samplerU;
         uniform SamplerType s_samplerV;
         uniform sampler2D s_contentTexture;
+        uniform SamplerExternalOESType s_externalOESTexture;
         uniform float u_opacity;
         uniform float u_filterAmount;
         uniform mat3 u_yuvToRgb;
@@ -374,6 +382,12 @@
             color = sourceOver(contentColor, color);
         }
 
+        void applyTextureExternalOES(inout vec4 color, vec2 texCoord)
+        {
+            vec4 contentColor = texture2D(s_externalOESTexture, texCoord);
+            color = sourceOver(contentColor, color);
+        }
+
         void applySolidColor(inout vec4 color) { color *= u_color; }
 
         void main(void)
@@ -400,6 +414,7 @@
             applyBlurFilterIfNeeded(color, texCoord);
             applyAlphaBlurIfNeeded(color, texCoord);
             applyContentTextureIfNeeded(color, texCoord);
+            applyTextureExternalOESIfNeeded(color, texCoord);
             gl_FragColor = color;
         }
     );
@@ -432,6 +447,7 @@
     SET_APPLIER_FROM_OPTIONS(AlphaBlur);
     SET_APPLIER_FROM_OPTIONS(ContentTexture);
     SET_APPLIER_FROM_OPTIONS(ManualRepeat);
+    SET_APPLIER_FROM_OPTIONS(TextureExternalOES);
 
     StringBuilder vertexShaderBuilder;
 

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h (258196 => 258197)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h	2020-03-10 12:08:16 UTC (rev 258196)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h	2020-03-10 12:08:53 UTC (rev 258197)
@@ -66,6 +66,7 @@
         TextureNV12      = 1L << 19,
         TextureNV21      = 1L << 20,
         TexturePackedYUV = 1L << 21,
+        TextureExternalOES = 1L << 22,
     };
 
     typedef unsigned Options;
@@ -96,6 +97,7 @@
     TEXMAP_DECLARE_UNIFORM(blurRadius)
     TEXMAP_DECLARE_UNIFORM(shadowOffset)
     TEXMAP_DECLARE_SAMPLER(contentTexture)
+    TEXMAP_DECLARE_SAMPLER(externalOESTexture)
 
     void setMatrix(GLuint, const TransformationMatrix&);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to