Changeset 192510 in webkit


Ignore:
Timestamp:
Nov 17, 2015 12:37:21 AM (8 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK] Web Process crashes on reparenting a WebView with AC mode on
https://bugs.webkit.org/show_bug.cgi?id=151139

Reviewed by Mario Sanchez Prada.

When the web view is reparented, the widget is first unrealized,
and then realized again when added to the new parent. In the
second realize, the old redirected XComposite window is destroyed
and a new one is created, but the web process is still using the
old redirected window ID. As soon as the redirected window is
destroyed and the web process tries to use the window ID, it
crashes due to a BadDrawable X error. We have to notify the web
process as soon as the web view is unrealized to stop using the
current window ID and exit accelerated compositing mode until a
new window ID is given. This notification needs to be synchronous,
because the window can be destroyed in the UI process before the
message is received in the web process.

  • UIProcess/API/gtk/WebKitWebViewBase.cpp:

(webkitWebViewBaseRealize): Add an assert to ensure we never have
a redirected window when the view is realized. Also check drawing
area is not nullptr, since it can be destroyed at any time if the
web process crashes.
(webkitWebViewBaseUnrealize): Call
DrawingAreaProxyImpl::destroyNativeSurfaceHandleForCompositing()
and destroy the redirected XComposite window.

  • UIProcess/DrawingAreaProxyImpl.cpp:

(WebKit::DrawingAreaProxyImpl::destroyNativeSurfaceHandleForCompositing):
Send DestroyNativeSurfaceHandleForCompositing synchronous messsage
to the web process.

  • UIProcess/DrawingAreaProxyImpl.h:
  • WebProcess/WebPage/DrawingArea.h:
  • WebProcess/WebPage/DrawingArea.messages.in: Add

DestroyNativeSurfaceHandleForCompositing message.

  • WebProcess/WebPage/DrawingAreaImpl.cpp:

(WebKit::DrawingAreaImpl::destroyNativeSurfaceHandleForCompositing):
Set the native surface handler for compositing to 0 to reset it.

  • WebProcess/WebPage/DrawingAreaImpl.h:
  • WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp:

(WebKit::LayerTreeHostGtk::makeContextCurrent): Return false
early always when layer tree context ID is 0, even if we already
have a context.
(WebKit::LayerTreeHostGtk::setNativeSurfaceHandleForCompositing):
Cancel any pending layer flush when setting a new handler.

Location:
trunk/Source/WebKit2
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r192502 r192510  
     12015-11-17  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] Web Process crashes on reparenting a WebView with AC mode on
     4        https://bugs.webkit.org/show_bug.cgi?id=151139
     5
     6        Reviewed by Mario Sanchez Prada.
     7
     8        When the web view is reparented, the widget is first unrealized,
     9        and then realized again when added to the new parent. In the
     10        second realize, the old redirected XComposite window is destroyed
     11        and a new one is created, but the web process is still using the
     12        old redirected window ID. As soon as the redirected window is
     13        destroyed and the web process tries to use the window ID, it
     14        crashes due to a BadDrawable X error. We have to notify the web
     15        process as soon as the web view is unrealized to stop using the
     16        current window ID and exit accelerated compositing mode until a
     17        new window ID is given. This notification needs to be synchronous,
     18        because the window can be destroyed in the UI process before the
     19        message is received in the web process.
     20
     21        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
     22        (webkitWebViewBaseRealize): Add an assert to ensure we never have
     23        a redirected window when the view is realized. Also check drawing
     24        area is not nullptr, since it can be destroyed at any time if the
     25        web process crashes.
     26        (webkitWebViewBaseUnrealize): Call
     27        DrawingAreaProxyImpl::destroyNativeSurfaceHandleForCompositing()
     28        and destroy the redirected XComposite window.
     29        * UIProcess/DrawingAreaProxyImpl.cpp:
     30        (WebKit::DrawingAreaProxyImpl::destroyNativeSurfaceHandleForCompositing):
     31        Send DestroyNativeSurfaceHandleForCompositing synchronous messsage
     32        to the web process.
     33        * UIProcess/DrawingAreaProxyImpl.h:
     34        * WebProcess/WebPage/DrawingArea.h:
     35        * WebProcess/WebPage/DrawingArea.messages.in: Add
     36        DestroyNativeSurfaceHandleForCompositing message.
     37        * WebProcess/WebPage/DrawingAreaImpl.cpp:
     38        (WebKit::DrawingAreaImpl::destroyNativeSurfaceHandleForCompositing):
     39        Set the native surface handler for compositing to 0 to reset it.
     40        * WebProcess/WebPage/DrawingAreaImpl.h:
     41        * WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp:
     42        (WebKit::LayerTreeHostGtk::makeContextCurrent): Return false
     43        early always when layer tree context ID is 0, even if we already
     44        have a context.
     45        (WebKit::LayerTreeHostGtk::setNativeSurfaceHandleForCompositing):
     46        Cancel any pending layer flush when setting a new handler.
     47
    1482015-11-16  Alex Christensen  <achristensen@webkit.org>
    249
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp

    r191881 r192510  
    281281#if USE(REDIRECTED_XCOMPOSITE_WINDOW)
    282282    if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) {
     283        ASSERT(!priv->redirectedWindow);
    283284        priv->redirectedWindow = RedirectedXCompositeWindow::create(
    284285            gtk_widget_get_parent_window(widget),
     
    289290            });
    290291        if (priv->redirectedWindow) {
    291             DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea());
    292             drawingArea->setNativeSurfaceHandleForCompositing(priv->redirectedWindow->windowID());
     292            if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea()))
     293                drawingArea->setNativeSurfaceHandleForCompositing(priv->redirectedWindow->windowID());
    293294        }
    294295    }
     
    330331
    331332#if USE(TEXTURE_MAPPER) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
    332     DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea());
    333     drawingArea->setNativeSurfaceHandleForCompositing(GDK_WINDOW_XID(window));
     333    if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea()))
     334        drawingArea->setNativeSurfaceHandleForCompositing(GDK_WINDOW_XID(window));
    334335#endif
    335336
     
    346347{
    347348    WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(widget);
     349#if USE(TEXTURE_MAPPER) && PLATFORM(X11)
     350    if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(webView->priv->pageProxy->drawingArea()))
     351        drawingArea->destroyNativeSurfaceHandleForCompositing();
     352#endif
     353#if USE(REDIRECTED_XCOMPOSITE_WINDOW)
     354    webView->priv->redirectedWindow = nullptr;
     355#endif
    348356    gtk_im_context_set_client_window(webView->priv->inputMethodFilter.context(), nullptr);
    349357
  • trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp

    r192052 r192510  
    315315    m_webPageProxy.process().send(Messages::DrawingArea::SetNativeSurfaceHandleForCompositing(handle), m_webPageProxy.pageID());
    316316}
     317
     318void DrawingAreaProxyImpl::destroyNativeSurfaceHandleForCompositing()
     319{
     320    bool handled;
     321    m_webPageProxy.process().sendSync(Messages::DrawingArea::DestroyNativeSurfaceHandleForCompositing(), Messages::DrawingArea::DestroyNativeSurfaceHandleForCompositing::Reply(handled), m_webPageProxy.pageID());
     322}
    317323#endif
    318324
  • trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h

    r191453 r192510  
    5151#if USE(TEXTURE_MAPPER) && PLATFORM(GTK)
    5252    void setNativeSurfaceHandleForCompositing(uint64_t);
     53    void destroyNativeSurfaceHandleForCompositing();
    5354#endif
    5455
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h

    r190615 r192510  
    151151    // IPC::MessageReceiver.
    152152    virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
     153    virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
    153154
    154155    // Message handlers.
     
    171172#if USE(TEXTURE_MAPPER) && PLATFORM(GTK)
    172173    virtual void setNativeSurfaceHandleForCompositing(uint64_t) = 0;
     174    virtual void destroyNativeSurfaceHandleForCompositing(bool&) = 0;
    173175#endif
    174176};
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in

    r190615 r192510  
    4343#if USE(TEXTURE_MAPPER) && PLATFORM(GTK)
    4444    SetNativeSurfaceHandleForCompositing(uint64_t handle)
     45    DestroyNativeSurfaceHandleForCompositing() -> (bool handled)
    4546#endif
    4647}
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp

    r191340 r192510  
    700700    }
    701701}
     702
     703void DrawingAreaImpl::destroyNativeSurfaceHandleForCompositing(bool& handled)
     704{
     705    handled = true;
     706    setNativeSurfaceHandleForCompositing(0);
     707}
    702708#endif
    703709
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h

    r190615 r192510  
    7373#if USE(TEXTURE_MAPPER) && PLATFORM(GTK)
    7474    virtual void setNativeSurfaceHandleForCompositing(uint64_t) override;
     75    virtual void destroyNativeSurfaceHandleForCompositing(bool&) override;
    7576#endif
    7677
  • trunk/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp

    r192201 r192510  
    146146bool LayerTreeHostGtk::makeContextCurrent()
    147147{
     148    if (!m_layerTreeContext.contextID) {
     149        m_context = nullptr;
     150        return false;
     151    }
     152
    148153    if (!m_context) {
    149         if (!m_layerTreeContext.contextID)
    150             return false;
    151 
    152154        m_context = GLContext::createContextForWindow(reinterpret_cast<GLNativeWindowType>(m_layerTreeContext.contextID), GLContext::sharingContext());
    153155        if (!m_context)
     
    417419void LayerTreeHostGtk::setNativeSurfaceHandleForCompositing(uint64_t handle)
    418420{
     421    cancelPendingLayerFlush();
    419422    m_layerTreeContext.contextID = handle;
    420423
Note: See TracChangeset for help on using the changeset viewer.