Changeset 265116 in webkit


Ignore:
Timestamp:
Jul 30, 2020 4:22:55 PM (4 years ago)
Author:
dino@apple.com
Message:

[WebGL] Safari snapshots of WebGL content in the tab picker don't work
https://bugs.webkit.org/show_bug.cgi?id=214452
<rdar://problem/21243082>

Source/WebCore:

Original patch by Justin Fan. Reviewed by Darin Adler.

Test is in TestWebKitAPI/Tests/WebKitCocoa/WKWebViewSnapshot.mm.

  • html/HTMLCanvasElement.cpp:

(WebCore::HTMLCanvasElement::paint): Will properly request a paint when a snapshot is requested.

  • html/HTMLCanvasElement.h:
  • html/canvas/WebGLRenderingContextBase.cpp:

(WebCore::WebGLRenderingContextBase::paintRenderingResultsToCanvas): Only clear the last snapshot if readPixels will succeed.

  • rendering/RenderHTMLCanvas.cpp:

(WebCore::RenderHTMLCanvas::paintReplaced):

Tools:

Test for snapshotting. Marked as PLATFORM(MAC) for now.

  • TestWebKitAPI/Tests/WebKitCocoa/WKWebViewSnapshot.mm:

(TEST):

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r265115 r265116  
     12020-07-30  Dean Jackson  <dino@apple.com>
     2
     3        [WebGL] Safari snapshots of WebGL content in the tab picker don't work
     4        https://bugs.webkit.org/show_bug.cgi?id=214452
     5        <rdar://problem/21243082>
     6
     7        Original patch by Justin Fan. Reviewed by Darin Adler.
     8
     9        Test is in TestWebKitAPI/Tests/WebKitCocoa/WKWebViewSnapshot.mm.
     10
     11        * html/HTMLCanvasElement.cpp:
     12        (WebCore::HTMLCanvasElement::paint): Will properly request a paint when a snapshot is requested.
     13        * html/HTMLCanvasElement.h:
     14        * html/canvas/WebGLRenderingContextBase.cpp:
     15        (WebCore::WebGLRenderingContextBase::paintRenderingResultsToCanvas): Only clear the last snapshot if readPixels will succeed.
     16        * rendering/RenderHTMLCanvas.cpp:
     17        (WebCore::RenderHTMLCanvas::paintReplaced):
     18
    1192020-07-30  Jer Noble  <jer.noble@apple.com>
    220
  • trunk/Source/WebCore/html/HTMLCanvasElement.cpp

    r264607 r265116  
    636636
    637637        if (m_context) {
    638             shouldPaint = paintsIntoCanvasBuffer() || document().printing();
     638            shouldPaint = paintsIntoCanvasBuffer() || document().printing() || m_isSnapshotting;
    639639            if (shouldPaint)
    640640                m_context->paintRenderingResultsToCanvas();
  • trunk/Source/WebCore/html/HTMLCanvasElement.h

    r264334 r265116  
    133133    void prepareForDisplay();
    134134
     135    void setIsSnapshotting(bool isSnapshotting) { m_isSnapshotting = isSnapshotting; }
     136    bool isSnapshotting() const { return m_isSnapshotting; }
     137
    135138private:
    136139    HTMLCanvasElement(const QualifiedName&, Document&);
     
    188191    bool m_hasRelevantWebGLEventListener { false };
    189192#endif
     193
     194    bool m_isSnapshotting { false };
    190195
    191196    mutable RefPtr<Image> m_presentedImage;
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

    r265114 r265116  
    11891189        return;
    11901190
    1191     if (canvas->document().printing())
     1191    if (canvas->document().printing() || (canvas->isSnapshotting() && canvas->document().page()->isVisible()))
    11921192        canvas->clearPresentationCopy();
    11931193
     
    11951195    // happened after it was composited should be ignored by the compositor.
    11961196    if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
    1197         m_context->paintCompositedResultsToCanvas(canvas->buffer());
     1197        m_context->paintRenderingResultsToCanvas(canvas->buffer());
    11981198
    11991199        canvas->makePresentationCopy();
  • trunk/Source/WebCore/rendering/RenderHTMLCanvas.cpp

    r260851 r265116  
    9393
    9494    InterpolationQualityMaintainer interpolationMaintainer(context, ImageQualityController::interpolationQualityFromStyle(style()));
     95
     96    canvasElement().setIsSnapshotting(paintInfo.paintBehavior.contains(PaintBehavior::Snapshotting));
    9597    canvasElement().paint(context, replacedContentRect);
     98    canvasElement().setIsSnapshotting(false);
    9699}
    97100
  • trunk/Tools/ChangeLog

    r265115 r265116  
     12020-07-30  Dean Jackson  <dino@apple.com>
     2
     3        [WebGL] Safari snapshots of WebGL content in the tab picker don't work
     4        https://bugs.webkit.org/show_bug.cgi?id=214452
     5        <rdar://problem/21243082>
     6
     7        Test for snapshotting. Marked as PLATFORM(MAC) for now.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewSnapshot.mm:
     10        (TEST):
     11
    1122020-07-30  Jer Noble  <jer.noble@apple.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewSnapshot.mm

    r251896 r265116  
    421421    TestWebKitAPI::Util::run(&isDone);
    422422}
     423
     424// FIXME: Confirm that this works on iOS too.
     425#if PLATFORM(MAC)
     426TEST(WKWebView, SnapshotWebGL)
     427{
     428    NSInteger viewWidth = 800;
     429    NSInteger viewHeight = 600;
     430    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, viewWidth, viewHeight)]);
     431
     432    RetainPtr<PlatformWindow> window;
     433    CGFloat backingScaleFactor;
     434
     435#if PLATFORM(MAC)
     436    window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
     437    [[window contentView] addSubview:webView.get()];
     438    backingScaleFactor = [window backingScaleFactor];
     439#elif PLATFORM(IOS_FAMILY)
     440    window = adoptNS([[UIWindow alloc] initWithFrame:[webView frame]]);
     441    [window addSubview:webView.get()];
     442    backingScaleFactor = [[window screen] scale];
     443#endif
     444
     445    [webView loadHTMLString:@"<style>body{margin:0;padding:0}</style><canvas></canvas><script>window.addEventListener('load', () => { let ctx = document.querySelector('canvas').getContext('webgl'); ctx.clearColor(0, 1, 0, 1); ctx.clear(ctx.COLOR_BUFFER_BIT); }, false);</script>" baseURL:nil];
     446    [webView _test_waitForDidFinishNavigation];
     447
     448    RetainPtr<WKSnapshotConfiguration> snapshotConfiguration = adoptNS([[WKSnapshotConfiguration alloc] init]);
     449    [snapshotConfiguration setRect:NSMakeRect(0, 0, viewWidth, viewHeight)];
     450    [snapshotConfiguration setSnapshotWidth:@(viewWidth)];
     451    [snapshotConfiguration setAfterScreenUpdates:YES];
     452
     453    isDone = false;
     454    [webView takeSnapshotWithConfiguration:snapshotConfiguration.get() completionHandler:^(PlatformImage snapshotImage, NSError *error) {
     455        EXPECT_NULL(error);
     456
     457        EXPECT_EQ(viewWidth, snapshotImage.size.width);
     458
     459        RetainPtr<CGImageRef> cgImage = convertToCGImage(snapshotImage);
     460        RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
     461
     462        NSInteger viewWidthInPixels = viewWidth * backingScaleFactor;
     463        NSInteger viewHeightInPixels = viewHeight * backingScaleFactor;
     464
     465        uint8_t *rgba = (unsigned char *)calloc(viewWidthInPixels * viewHeightInPixels * 4, sizeof(unsigned char));
     466        RetainPtr<CGContextRef> context = CGBitmapContextCreate(rgba, viewWidthInPixels, viewHeightInPixels, 8, 4 * viewWidthInPixels, colorSpace.get(), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
     467        CGContextDrawImage(context.get(), CGRectMake(0, 0, viewWidthInPixels, viewHeightInPixels), cgImage.get());
     468
     469        NSInteger pixelIndex = getPixelIndex(0, 0, viewWidthInPixels);
     470        EXPECT_EQ(0, rgba[pixelIndex]);
     471        EXPECT_EQ(255, rgba[pixelIndex + 1]);
     472        EXPECT_EQ(0, rgba[pixelIndex + 2]);
     473        EXPECT_EQ(255, rgba[pixelIndex + 3]);
     474
     475        free(rgba);
     476
     477        isDone = true;
     478    }];
     479
     480    TestWebKitAPI::Util::run(&isDone);
     481}
     482#endif
Note: See TracChangeset for help on using the changeset viewer.