Title: [280963] trunk
Revision
280963
Author
[email protected]
Date
2021-08-12 06:35:06 -0700 (Thu, 12 Aug 2021)

Log Message

webgl/1.0.x/conformance/textures/misc/texture-corner-case-videos.html fails on Cocoa
https://bugs.webkit.org/show_bug.cgi?id=228821
<rdar://problem/81562236>

Patch by Kimmo Kinnunen <[email protected]> on 2021-08-12
Reviewed by Kenneth Russell.

When uploading the WebGL texture content from videos, use the video
visible data size instead of video element size. The video data can
be scaled with its filters, but we should upload only the original
pixels.

The GPU codepath already did this, but CPU codepath did not.
This change fixes the CPU codepath.

Fixes webgl/1.0.x/conformance/textures/misc/texture-corner-case-videos.html
webgl/2.0.y/conformance/textures/misc/texture-corner-case-videos.html

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::texImageSourceHelper):
(WebCore::WebGLRenderingContextBase::videoFrameToImage):
(WebCore::WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer):
* html/canvas/WebGLRenderingContextBase.h:

Modified Paths

Diff

Modified: trunk/LayoutTests/TestExpectations (280962 => 280963)


--- trunk/LayoutTests/TestExpectations	2021-08-12 13:01:27 UTC (rev 280962)
+++ trunk/LayoutTests/TestExpectations	2021-08-12 13:35:06 UTC (rev 280963)
@@ -3686,14 +3686,16 @@
 webgl/1.0.x/conformance/canvas/to-data-url-test.html [ Pass ]
 webgl/1.0.x/conformance/misc/invalid-passed-params.html [ Pass ]
 webgl/1.0.x/conformance/glsl/bugs/character-set.html [ Pass ]
+webgl/1.0.x/conformance/textures/misc/texture-corner-case-videos.html [ Pass ]
 
 # WebGL conformance test suite 2.0.1 is skipped until 2.0.0 is retired.
 webgl/2.0.y [ Skip ]
 
-# Explicitly enable tests which we have fixed and do not have corresponding 2.0.y test functionality.
+# Explicitly enable tests which we have fixed and do not have corresponding 2.0.0 test functionality.
 webgl/2.0.y/conformance/canvas/to-data-url-test.html [ Pass ]
 webgl/2.0.y/conformance/misc/invalid-passed-params.html [ Pass ]
 webgl/2.0.y/conformance/glsl/bugs/character-set.html [ Pass ]
+webgl/2.0.y/conformance/textures/misc/texture-corner-case-videos.html [ Pass ]
 
 # WebGL 1.0.3 and 2.0.0 tests where behavior is obsolete and WebKit contains implementation
 # and tests for the new behavior. Should be removed once 1.0.3 and 2.0.0 are retired.

Modified: trunk/Source/WebCore/ChangeLog (280962 => 280963)


--- trunk/Source/WebCore/ChangeLog	2021-08-12 13:01:27 UTC (rev 280962)
+++ trunk/Source/WebCore/ChangeLog	2021-08-12 13:35:06 UTC (rev 280963)
@@ -1,3 +1,28 @@
+2021-08-12  Kimmo Kinnunen  <[email protected]>
+
+        webgl/1.0.x/conformance/textures/misc/texture-corner-case-videos.html fails on Cocoa
+        https://bugs.webkit.org/show_bug.cgi?id=228821
+        <rdar://problem/81562236>
+
+        Reviewed by Kenneth Russell.
+
+        When uploading the WebGL texture content from videos, use the video
+        visible data size instead of video element size. The video data can
+        be scaled with its filters, but we should upload only the original
+        pixels.
+
+        The GPU codepath already did this, but CPU codepath did not.
+        This change fixes the CPU codepath.
+
+        Fixes webgl/1.0.x/conformance/textures/misc/texture-corner-case-videos.html
+        webgl/2.0.y/conformance/textures/misc/texture-corner-case-videos.html
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::texImageSourceHelper):
+        (WebCore::WebGLRenderingContextBase::videoFrameToImage):
+        (WebCore::WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer):
+        * html/canvas/WebGLRenderingContextBase.h:
+
 2021-08-12  Youenn Fablet  <[email protected]>
 
         Implement SFrameTransform error handling

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (280962 => 280963)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2021-08-12 13:01:27 UTC (rev 280962)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2021-08-12 13:35:06 UTC (rev 280963)
@@ -4934,7 +4934,7 @@
         }
 
         // Fallback pure SW path.
-        RefPtr<Image> image = videoFrameToImage(video.get(), DontCopyBackingStore);
+        RefPtr<Image> image = videoFrameToImage(video.get(), DontCopyBackingStore, functionName);
         if (!image)
             return { };
         texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zoffset, format, type, image.get(), GraphicsContextGL::DOMSource::Video, m_unpackFlipY, m_unpackPremultiplyAlpha, false, inputSourceImageRect, depth, unpackImageHeight);
@@ -5768,18 +5768,44 @@
 
 #if ENABLE(VIDEO)
 
-RefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
+RefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy, const char* functionName)
 {
-    IntSize size(video->videoWidth(), video->videoHeight());
-    ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
-    if (!buf) {
-        synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, "texImage2D", "out of memory");
+#if USE(AVFOUNDATION)
+    auto nativeImage = video->nativeImageForCurrentTime();
+    // Currently we might be missing an image due to MSE not being able to provide the first requested frame.
+    // https://bugs.webkit.org/show_bug.cgi?id=228997
+    if (!nativeImage)
         return nullptr;
+    IntSize imageSize = nativeImage->size();
+    if (imageSize.isEmpty()) {
+        synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "video visible size is empty");
+        return nullptr;
     }
-    FloatRect destRect(0, 0, size.width(), size.height());
-    // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
-    video->paintCurrentFrameInContext(buf->context(), destRect);
-    return buf->copyImage(backingStoreCopy);
+    FloatRect imageRect { { }, imageSize };
+    ImageBuffer* imageBuffer = m_generatedImageCache.imageBuffer(imageSize, CompositeOperator::Copy);
+    if (!imageBuffer) {
+        synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, functionName, "out of memory");
+        return nullptr;
+    }
+    imageBuffer->context().drawNativeImage(*nativeImage, imageRect.size(), imageRect, imageRect, CompositeOperator::Copy);
+#else
+    // This is a legacy code path that produces incompatible texture size when the
+    // video visible size is different to the natural size. This should be removed
+    // once all platforms implement nativeImageForCurrentTime().
+    IntSize videoSize { static_cast<int>(video->videoWidth()), static_cast<int>(video->videoHeight()) };
+    ImageBuffer* imageBuffer = m_generatedImageCache.imageBuffer(videoSize);
+    if (!imageBuffer) {
+        synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, functionName, "out of memory");
+        return nullptr;
+    }
+    video->paintCurrentFrameInContext(imageBuffer->context(), { { }, videoSize });
+#endif
+    RefPtr<Image> image = imageBuffer->copyImage(backingStoreCopy);
+    if (!image) {
+        synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, functionName, "out of memory");
+        return nullptr;
+    }
+    return image;
 }
 
 #endif
@@ -7621,7 +7647,7 @@
 {
 }
 
-ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size)
+ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size, CompositeOperator fillOperator)
 {
     size_t i;
     for (i = 0; i < m_buffers.size(); ++i) {
@@ -7631,7 +7657,8 @@
         if (buf->logicalSize() != size)
             continue;
         bubbleToFront(i);
-        buf->context().clearRect(FloatRect({ }, FloatSize(size)));
+        if (fillOperator != CompositeOperator::Copy && fillOperator != CompositeOperator::Clear)
+            buf->context().clearRect({ { }, size });
         return buf;
     }
 

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (280962 => 280963)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2021-08-12 13:01:27 UTC (rev 280962)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2021-08-12 13:35:06 UTC (rev 280963)
@@ -524,7 +524,7 @@
     RefPtr<Image> drawImageIntoBuffer(Image&, int width, int height, int deviceScaleFactor, const char* functionName);
 
 #if ENABLE(VIDEO)
-    RefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
+    RefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, const char* functionName);
 #endif
 
     WebGLTexture::TextureExtensionFlag textureExtensionFlags() const;
@@ -614,8 +614,9 @@
     class LRUImageBufferCache {
     public:
         LRUImageBufferCache(int capacity);
-        // The pointer returned is owned by the image buffer map.
-        ImageBuffer* imageBuffer(const IntSize& size);
+        // Returns pointer to a cleared image buffer that is owned by the cache. The pointer is valid until next call.
+        // Using fillOperator == CompositeOperator::Copy can be used to omit the clear of the buffer.
+        ImageBuffer* imageBuffer(const IntSize&, CompositeOperator fillOperator = CompositeOperator::SourceOver);
     private:
         void bubbleToFront(size_t idx);
         Vector<RefPtr<ImageBuffer>> m_buffers;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to