⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 280963 in webkit


Ignore:
Timestamp:
Aug 12, 2021, 6:35:06 AM (5 years ago)
Author:
commit-queue@webkit.org
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 <kkinnunen@apple.com> 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:
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/TestExpectations

    r280960 r280963  
    36873687webgl/1.0.x/conformance/misc/invalid-passed-params.html [ Pass ]
    36883688webgl/1.0.x/conformance/glsl/bugs/character-set.html [ Pass ]
     3689webgl/1.0.x/conformance/textures/misc/texture-corner-case-videos.html [ Pass ]
    36893690
    36903691# WebGL conformance test suite 2.0.1 is skipped until 2.0.0 is retired.
    36913692webgl/2.0.y [ Skip ]
    36923693
    3693 # Explicitly enable tests which we have fixed and do not have corresponding 2.0.y test functionality.
     3694# Explicitly enable tests which we have fixed and do not have corresponding 2.0.0 test functionality.
    36943695webgl/2.0.y/conformance/canvas/to-data-url-test.html [ Pass ]
    36953696webgl/2.0.y/conformance/misc/invalid-passed-params.html [ Pass ]
    36963697webgl/2.0.y/conformance/glsl/bugs/character-set.html [ Pass ]
     3698webgl/2.0.y/conformance/textures/misc/texture-corner-case-videos.html [ Pass ]
    36973699
    36983700# WebGL 1.0.3 and 2.0.0 tests where behavior is obsolete and WebKit contains implementation
  • trunk/Source/WebCore/ChangeLog

    r280958 r280963  
     12021-08-12  Kimmo Kinnunen  <kkinnunen@apple.com>
     2
     3        webgl/1.0.x/conformance/textures/misc/texture-corner-case-videos.html fails on Cocoa
     4        https://bugs.webkit.org/show_bug.cgi?id=228821
     5        <rdar://problem/81562236>
     6
     7        Reviewed by Kenneth Russell.
     8
     9        When uploading the WebGL texture content from videos, use the video
     10        visible data size instead of video element size. The video data can
     11        be scaled with its filters, but we should upload only the original
     12        pixels.
     13
     14        The GPU codepath already did this, but CPU codepath did not.
     15        This change fixes the CPU codepath.
     16
     17        Fixes webgl/1.0.x/conformance/textures/misc/texture-corner-case-videos.html
     18        webgl/2.0.y/conformance/textures/misc/texture-corner-case-videos.html
     19
     20        * html/canvas/WebGLRenderingContextBase.cpp:
     21        (WebCore::WebGLRenderingContextBase::texImageSourceHelper):
     22        (WebCore::WebGLRenderingContextBase::videoFrameToImage):
     23        (WebCore::WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer):
     24        * html/canvas/WebGLRenderingContextBase.h:
     25
    1262021-08-12  Youenn Fablet  <youenn@apple.com>
    227
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

    r280601 r280963  
    49354935
    49364936        // Fallback pure SW path.
    4937         RefPtr<Image> image = videoFrameToImage(video.get(), DontCopyBackingStore);
     4937        RefPtr<Image> image = videoFrameToImage(video.get(), DontCopyBackingStore, functionName);
    49384938        if (!image)
    49394939            return { };
     
    57695769#if ENABLE(VIDEO)
    57705770
    5771 RefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
    5772 {
    5773     IntSize size(video->videoWidth(), video->videoHeight());
    5774     ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
    5775     if (!buf) {
    5776         synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, "texImage2D", "out of memory");
     5771RefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy, const char* functionName)
     5772{
     5773#if USE(AVFOUNDATION)
     5774    auto nativeImage = video->nativeImageForCurrentTime();
     5775    // Currently we might be missing an image due to MSE not being able to provide the first requested frame.
     5776    // https://bugs.webkit.org/show_bug.cgi?id=228997
     5777    if (!nativeImage)
    57775778        return nullptr;
    5778     }
    5779     FloatRect destRect(0, 0, size.width(), size.height());
    5780     // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
    5781     video->paintCurrentFrameInContext(buf->context(), destRect);
    5782     return buf->copyImage(backingStoreCopy);
     5779    IntSize imageSize = nativeImage->size();
     5780    if (imageSize.isEmpty()) {
     5781        synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "video visible size is empty");
     5782        return nullptr;
     5783    }
     5784    FloatRect imageRect { { }, imageSize };
     5785    ImageBuffer* imageBuffer = m_generatedImageCache.imageBuffer(imageSize, CompositeOperator::Copy);
     5786    if (!imageBuffer) {
     5787        synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, functionName, "out of memory");
     5788        return nullptr;
     5789    }
     5790    imageBuffer->context().drawNativeImage(*nativeImage, imageRect.size(), imageRect, imageRect, CompositeOperator::Copy);
     5791#else
     5792    // This is a legacy code path that produces incompatible texture size when the
     5793    // video visible size is different to the natural size. This should be removed
     5794    // once all platforms implement nativeImageForCurrentTime().
     5795    IntSize videoSize { static_cast<int>(video->videoWidth()), static_cast<int>(video->videoHeight()) };
     5796    ImageBuffer* imageBuffer = m_generatedImageCache.imageBuffer(videoSize);
     5797    if (!imageBuffer) {
     5798        synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, functionName, "out of memory");
     5799        return nullptr;
     5800    }
     5801    video->paintCurrentFrameInContext(imageBuffer->context(), { { }, videoSize });
     5802#endif
     5803    RefPtr<Image> image = imageBuffer->copyImage(backingStoreCopy);
     5804    if (!image) {
     5805        synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, functionName, "out of memory");
     5806        return nullptr;
     5807    }
     5808    return image;
    57835809}
    57845810
     
    76227648}
    76237649
    7624 ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size)
     7650ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size, CompositeOperator fillOperator)
    76257651{
    76267652    size_t i;
     
    76327658            continue;
    76337659        bubbleToFront(i);
    7634         buf->context().clearRect(FloatRect({ }, FloatSize(size)));
     7660        if (fillOperator != CompositeOperator::Copy && fillOperator != CompositeOperator::Clear)
     7661            buf->context().clearRect({ { }, size });
    76357662        return buf;
    76367663    }
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h

    r278338 r280963  
    525525
    526526#if ENABLE(VIDEO)
    527     RefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
     527    RefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, const char* functionName);
    528528#endif
    529529
     
    615615    public:
    616616        LRUImageBufferCache(int capacity);
    617         // The pointer returned is owned by the image buffer map.
    618         ImageBuffer* imageBuffer(const IntSize& size);
     617        // Returns pointer to a cleared image buffer that is owned by the cache. The pointer is valid until next call.
     618        // Using fillOperator == CompositeOperator::Copy can be used to omit the clear of the buffer.
     619        ImageBuffer* imageBuffer(const IntSize&, CompositeOperator fillOperator = CompositeOperator::SourceOver);
    619620    private:
    620621        void bubbleToFront(size_t idx);
Note: See TracChangeset for help on using the changeset viewer.