Changeset 211365 in webkit


Ignore:
Timestamp:
Jan 30, 2017 8:42:12 AM (7 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK] Do not release OpenGL resource immediately when leaving accelerated compositing mode
https://bugs.webkit.org/show_bug.cgi?id=167544

Reviewed by Michael Catanzaro.

Sometimes the conditions to be in AC mode or not change quickly, and then we leave AC mode just enter it again
after a very short period of time. In those cases we are dropping all the GL resources and the compositor
thread, and creating it again. We could keep the layer tree host alive for a while when exiting AC mode, and
reuse it if we enter AC mode before the previous one has been discarded. While the previous layer tree host is
alive we still need to keep it up to date, for example if the web view is resized or contents size change, and
synchronize with the threaded compositor when it becomes the layer tree host again.

  • WebProcess/WebPage/AcceleratedDrawingArea.cpp:

(WebKit::AcceleratedDrawingArea::~AcceleratedDrawingArea): Discard the previous layer tree host.
(WebKit::AcceleratedDrawingArea::AcceleratedDrawingArea): Initialize the timer to discard the previous layer
tree host.
(WebKit::AcceleratedDrawingArea::pageBackgroundTransparencyChanged): Notify the previous layer tree host if needed.
(WebKit::AcceleratedDrawingArea::mainFrameContentSizeChanged): Ditto.
(WebKit::AcceleratedDrawingArea::updateBackingStoreState): Ditto.
(WebKit::AcceleratedDrawingArea::enterAcceleratedCompositingMode): Reuse the previous layer tree host if possible.
(WebKit::AcceleratedDrawingArea::exitAcceleratedCompositingModeNow): Exit AC mode and save the layer tree host
starting a timer of 5 seconds to discard it if not reused.
(WebKit::AcceleratedDrawingArea::discardPreviousLayerTreeHost): Invalidate and destroy the previous layer tree host.
(WebKit::AcceleratedDrawingArea::didChangeViewportAttributes): Notify the previous layer tree host if needed.
(WebKit::AcceleratedDrawingArea::deviceOrPageScaleFactorChanged): Ditto.

  • WebProcess/WebPage/AcceleratedDrawingArea.h:
  • WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp:

(WebKit::ThreadedCoordinatedLayerTreeHost::scrollNonCompositedContents): If it's discardable add the action to
be synchronized instead.
(WebKit::ThreadedCoordinatedLayerTreeHost::contentsSizeChanged): Ditto.
(WebKit::ThreadedCoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged): Ditto.
(WebKit::ThreadedCoordinatedLayerTreeHost::pageBackgroundTransparencyChanged): Ditto.
(WebKit::ThreadedCoordinatedLayerTreeHost::sizeDidChange): Ditto.
(WebKit::ThreadedCoordinatedLayerTreeHost::didChangeViewportAttributes): Ditto.
(WebKit::ThreadedCoordinatedLayerTreeHost::setIsDiscardable): When the layer tree host becomes discardable,
reset the sync actions and return. When it becomes the real layer tree host again, apply all pending actions to
synchronize with the threaded compositor.

  • WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h:
  • WebProcess/WebPage/DrawingAreaImpl.cpp:

(WebKit::DrawingAreaImpl::scroll): Notify the previous layer tree host if needed.
(WebKit::DrawingAreaImpl::mainFrameContentSizeChanged): Ditto.
(WebKit::DrawingAreaImpl::exitAcceleratedCompositingMode): Use AcceleratedDrawingArea::exitAcceleratedCompositingModeNow().

  • WebProcess/WebPage/LayerTreeHost.h:

(WebKit::LayerTreeHost::setIsDiscardable): Added.

Location:
trunk/Source/WebKit2
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r211364 r211365  
     12017-01-30  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] Do not release OpenGL resource immediately when leaving accelerated compositing mode
     4        https://bugs.webkit.org/show_bug.cgi?id=167544
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Sometimes the conditions to be in AC mode or not change quickly, and then we leave AC mode just enter it again
     9        after a very short period of time. In those cases we are dropping all the GL resources and the compositor
     10        thread, and creating it again. We could keep the layer tree host alive for a while when exiting AC mode, and
     11        reuse it if we enter AC mode before the previous one has been discarded. While the previous layer tree host is
     12        alive we still need to keep it up to date, for example if the web view is resized or contents size change, and
     13        synchronize with the threaded compositor when it becomes the layer tree host again.
     14
     15        * WebProcess/WebPage/AcceleratedDrawingArea.cpp:
     16        (WebKit::AcceleratedDrawingArea::~AcceleratedDrawingArea): Discard the previous layer tree host.
     17        (WebKit::AcceleratedDrawingArea::AcceleratedDrawingArea): Initialize the timer to discard the previous layer
     18        tree host.
     19        (WebKit::AcceleratedDrawingArea::pageBackgroundTransparencyChanged): Notify the previous layer tree host if needed.
     20        (WebKit::AcceleratedDrawingArea::mainFrameContentSizeChanged): Ditto.
     21        (WebKit::AcceleratedDrawingArea::updateBackingStoreState): Ditto.
     22        (WebKit::AcceleratedDrawingArea::enterAcceleratedCompositingMode): Reuse the previous layer tree host if possible.
     23        (WebKit::AcceleratedDrawingArea::exitAcceleratedCompositingModeNow): Exit AC mode and save the layer tree host
     24        starting a timer of 5 seconds to discard it if not reused.
     25        (WebKit::AcceleratedDrawingArea::discardPreviousLayerTreeHost): Invalidate and destroy the previous layer tree host.
     26        (WebKit::AcceleratedDrawingArea::didChangeViewportAttributes): Notify the previous layer tree host if needed.
     27        (WebKit::AcceleratedDrawingArea::deviceOrPageScaleFactorChanged): Ditto.
     28        * WebProcess/WebPage/AcceleratedDrawingArea.h:
     29        * WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp:
     30        (WebKit::ThreadedCoordinatedLayerTreeHost::scrollNonCompositedContents): If it's discardable add the action to
     31        be synchronized instead.
     32        (WebKit::ThreadedCoordinatedLayerTreeHost::contentsSizeChanged): Ditto.
     33        (WebKit::ThreadedCoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged): Ditto.
     34        (WebKit::ThreadedCoordinatedLayerTreeHost::pageBackgroundTransparencyChanged): Ditto.
     35        (WebKit::ThreadedCoordinatedLayerTreeHost::sizeDidChange): Ditto.
     36        (WebKit::ThreadedCoordinatedLayerTreeHost::didChangeViewportAttributes): Ditto.
     37        (WebKit::ThreadedCoordinatedLayerTreeHost::setIsDiscardable): When the layer tree host becomes discardable,
     38        reset the sync actions and return. When it becomes the real layer tree host again, apply all pending actions to
     39        synchronize with the threaded compositor.
     40        * WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h:
     41        * WebProcess/WebPage/DrawingAreaImpl.cpp:
     42        (WebKit::DrawingAreaImpl::scroll): Notify the previous layer tree host if needed.
     43        (WebKit::DrawingAreaImpl::mainFrameContentSizeChanged): Ditto.
     44        (WebKit::DrawingAreaImpl::exitAcceleratedCompositingMode): Use AcceleratedDrawingArea::exitAcceleratedCompositingModeNow().
     45        * WebProcess/WebPage/LayerTreeHost.h:
     46        (WebKit::LayerTreeHost::setIsDiscardable): Added.
     47
    1482017-01-30  Manuel Rego Casasnovas  <rego@igalia.com>
    249
  • trunk/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.cpp

    r211350 r211365  
    4545AcceleratedDrawingArea::~AcceleratedDrawingArea()
    4646{
     47    discardPreviousLayerTreeHost();
    4748    if (m_layerTreeHost)
    4849        m_layerTreeHost->invalidate();
     
    5657#endif
    5758    , m_exitCompositingTimer(RunLoop::main(), this, &AcceleratedDrawingArea::exitAcceleratedCompositingMode)
     59    , m_discardPreviousLayerTreeHostTimer(RunLoop::main(), this, &AcceleratedDrawingArea::discardPreviousLayerTreeHost)
    5860{
    5961    if (!m_webPage.isVisible())
     
    9294    if (m_layerTreeHost)
    9395        m_layerTreeHost->pageBackgroundTransparencyChanged();
     96    else if (m_previousLayerTreeHost)
     97        m_previousLayerTreeHost->pageBackgroundTransparencyChanged();
    9498}
    9599
     
    151155void AcceleratedDrawingArea::mainFrameContentSizeChanged(const IntSize& size)
    152156{
    153     if (m_webPage.useFixedLayout() && m_layerTreeHost)
    154         m_layerTreeHost->sizeDidChange(size);
     157    if (m_webPage.useFixedLayout()) {
     158        if (m_layerTreeHost)
     159            m_layerTreeHost->sizeDidChange(size);
     160        else if (m_previousLayerTreeHost)
     161            m_previousLayerTreeHost->sizeDidChange(size);
     162    }
    155163    m_webPage.mainFrame()->pageOverlayController().didChangeDocumentSize();
    156164}
     
    235243        if (m_layerTreeHost)
    236244            m_layerTreeHost->sizeDidChange(m_webPage.size());
     245        else if (m_previousLayerTreeHost)
     246            m_previousLayerTreeHost->sizeDidChange(m_webPage.size());
    237247#endif
    238248    } else {
     
    318328void AcceleratedDrawingArea::enterAcceleratedCompositingMode(GraphicsLayer* graphicsLayer)
    319329{
     330    m_discardPreviousLayerTreeHostTimer.stop();
     331
    320332    m_exitCompositingTimer.stop();
    321333    m_wantsToExitAcceleratedCompositingMode = false;
    322334
    323335    ASSERT(!m_layerTreeHost);
    324     m_layerTreeHost = LayerTreeHost::create(m_webPage);
     336    if (m_previousLayerTreeHost) {
     337        m_layerTreeHost = WTFMove(m_previousLayerTreeHost);
     338        m_layerTreeHost->setIsDiscardable(false);
     339        if (!m_isPaintingSuspended)
     340            m_layerTreeHost->resumeRendering();
     341        if (!m_layerTreeStateIsFrozen)
     342            m_layerTreeHost->setLayerFlushSchedulingEnabled(true);
     343    } else {
     344        m_layerTreeHost = LayerTreeHost::create(m_webPage);
     345
     346        if (m_isPaintingSuspended)
     347            m_layerTreeHost->pauseRendering();
     348    }
     349
    325350#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
    326351    if (m_nativeSurfaceHandleForCompositing)
     
    329354    if (!m_inUpdateBackingStoreState)
    330355        m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true);
    331     if (m_isPaintingSuspended)
    332         m_layerTreeHost->pauseRendering();
    333356
    334357    m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
     
    346369
    347370    m_exitCompositingTimer.startOneShot(0);
     371}
     372
     373void AcceleratedDrawingArea::exitAcceleratedCompositingModeNow()
     374{
     375    ASSERT(!m_alwaysUseCompositing);
     376    ASSERT(!m_layerTreeStateIsFrozen);
     377
     378    m_exitCompositingTimer.stop();
     379    m_wantsToExitAcceleratedCompositingMode = false;
     380
     381    ASSERT(m_layerTreeHost);
     382    m_previousLayerTreeHost = WTFMove(m_layerTreeHost);
     383    m_previousLayerTreeHost->setIsDiscardable(true);
     384    m_previousLayerTreeHost->pauseRendering();
     385    m_previousLayerTreeHost->setLayerFlushSchedulingEnabled(false);
     386    m_discardPreviousLayerTreeHostTimer.startOneShot(5);
     387}
     388
     389void AcceleratedDrawingArea::discardPreviousLayerTreeHost()
     390{
     391    m_discardPreviousLayerTreeHostTimer.stop();
     392    if (!m_previousLayerTreeHost)
     393        return;
     394
     395    m_previousLayerTreeHost->invalidate();
     396    m_previousLayerTreeHost = nullptr;
    348397}
    349398
     
    377426    if (m_layerTreeHost)
    378427        m_layerTreeHost->didChangeViewportAttributes(WTFMove(attrs));
     428    else if (m_previousLayerTreeHost)
     429        m_previousLayerTreeHost->didChangeViewportAttributes(WTFMove(attrs));
    379430}
    380431#endif
     
    385436    if (m_layerTreeHost)
    386437        m_layerTreeHost->deviceOrPageScaleFactorChanged();
     438    else if (m_previousLayerTreeHost)
     439        m_previousLayerTreeHost->deviceOrPageScaleFactorChanged();
    387440}
    388441#endif
  • trunk/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.h

    r211350 r211365  
    8787    void exitAcceleratedCompositingModeSoon();
    8888    bool exitAcceleratedCompositingModePending() const { return m_exitCompositingTimer.isActive(); }
     89    void exitAcceleratedCompositingModeNow();
     90    void discardPreviousLayerTreeHost();
    8991
    9092    virtual void suspendPainting();
     
    128130    // The layer tree host that handles accelerated compositing.
    129131    RefPtr<LayerTreeHost> m_layerTreeHost;
     132
     133    RefPtr<LayerTreeHost> m_previousLayerTreeHost;
     134    RunLoop::Timer<AcceleratedDrawingArea> m_discardPreviousLayerTreeHostTimer;
    130135};
    131136
  • trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp

    r211350 r211365  
    103103
    104104    m_viewportController.didScroll(rect.location());
    105     didChangeViewport();
     105    if (m_isDiscardable)
     106        m_discardableSyncActions |= DiscardableSyncActions::UpdateViewport;
     107    else
     108        didChangeViewport();
    106109}
    107110
     
    109112{
    110113    m_viewportController.didChangeContentsSize(newSize);
    111     didChangeViewport();
     114    if (m_isDiscardable)
     115        m_discardableSyncActions |= DiscardableSyncActions::UpdateViewport;
     116    else
     117        didChangeViewport();
    112118}
    113119
    114120void ThreadedCoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged()
    115121{
     122    if (m_isDiscardable) {
     123        m_discardableSyncActions |= DiscardableSyncActions::UpdateScale;
     124        return;
     125    }
     126
    116127    if (m_surface && m_surface->resize(m_webPage.size()))
    117128        m_layerTreeContext.contextID = m_surface->surfaceID();
     
    123134void ThreadedCoordinatedLayerTreeHost::pageBackgroundTransparencyChanged()
    124135{
     136    if (m_isDiscardable) {
     137        m_discardableSyncActions |= DiscardableSyncActions::UpdateBackground;
     138        return;
     139    }
     140
    125141    CoordinatedLayerTreeHost::pageBackgroundTransparencyChanged();
    126142    m_compositor->setDrawsBackground(m_webPage.drawsBackground());
     
    129145void ThreadedCoordinatedLayerTreeHost::sizeDidChange(const IntSize& size)
    130146{
     147    if (m_isDiscardable) {
     148        m_discardableSyncActions |= DiscardableSyncActions::UpdateSize;
     149        m_viewportController.didChangeViewportSize(size);
     150        return;
     151    }
     152
    131153    if (m_surface && m_surface->resize(size))
    132154        m_layerTreeContext.contextID = m_surface->surfaceID();
     
    143165{
    144166    m_viewportController.didChangeViewportAttributes(WTFMove(attr));
    145     didChangeViewport();
     167    if (m_isDiscardable)
     168        m_discardableSyncActions |= DiscardableSyncActions::UpdateViewport;
     169    else
     170        didChangeViewport();
    146171}
    147172
     
    196221}
    197222
     223void ThreadedCoordinatedLayerTreeHost::setIsDiscardable(bool discardable)
     224{
     225    m_isDiscardable = discardable;
     226    if (m_isDiscardable) {
     227        m_discardableSyncActions = OptionSet<DiscardableSyncActions>();
     228        return;
     229    }
     230
     231    if (m_discardableSyncActions.isEmpty())
     232        return;
     233
     234    if (m_discardableSyncActions.contains(DiscardableSyncActions::UpdateBackground))
     235        pageBackgroundTransparencyChanged();
     236
     237    if (m_discardableSyncActions.contains(DiscardableSyncActions::UpdateSize)) {
     238        // Size changes already sets the scale factor and updates the viewport.
     239        sizeDidChange(m_webPage.size());
     240        return;
     241    }
     242
     243    if (m_discardableSyncActions.contains(DiscardableSyncActions::UpdateScale))
     244        deviceOrPageScaleFactorChanged();
     245
     246    if (m_discardableSyncActions.contains(DiscardableSyncActions::UpdateViewport))
     247        didChangeViewport();
     248}
     249
    198250} // namespace WebKit
    199251
  • trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h

    r211350 r211365  
    3434#include "SimpleViewportController.h"
    3535#include "ThreadedCompositor.h"
     36#include <wtf/OptionSet.h>
    3637
    3738namespace WebCore {
     
    6768    bool forceRepaintAsync(uint64_t callbackID) override { return false; }
    6869
     70    void setIsDiscardable(bool) override;
     71
    6972#if PLATFORM(GTK) && PLATFORM(X11) &&  !USE(REDIRECTED_XCOMPOSITE_WINDOW)
    7073    void setNativeSurfaceHandleForCompositing(uint64_t) override;
     
    99102    void commitSceneState(const WebCore::CoordinatedGraphicsState&) override;
    100103
     104    enum class DiscardableSyncActions {
     105        UpdateSize = 1 << 1,
     106        UpdateViewport = 1 << 2,
     107        UpdateScale = 1 << 3,
     108        UpdateBackground = 1 << 4
     109    };
     110
    101111    CompositorClient m_compositorClient;
    102112    std::unique_ptr<AcceleratedSurface> m_surface;
     
    105115    float m_lastPageScaleFactor { 1 };
    106116    WebCore::IntPoint m_lastScrollPosition;
     117    bool m_isDiscardable { false };
     118    OptionSet<DiscardableSyncActions> m_discardableSyncActions;
    107119};
    108120
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp

    r211363 r211365  
    9999        return;
    100100
     101    if (m_previousLayerTreeHost)
     102        m_previousLayerTreeHost->scrollNonCompositedContents(scrollRect);
     103
    101104    if (!m_scrollRect.isEmpty() && scrollRect != m_scrollRect) {
    102105        unsigned scrollArea = scrollRect.width() * scrollRect.height();
     
    165168    if (m_layerTreeHost)
    166169        m_layerTreeHost->contentsSizeChanged(newSize);
     170    else if (m_previousLayerTreeHost)
     171        m_previousLayerTreeHost->contentsSizeChanged(newSize);
    167172#else
    168173    UNUSED_PARAM(newSize);
     
    290295        return;
    291296
    292     ASSERT(!m_layerTreeStateIsFrozen);
    293 
    294     m_exitCompositingTimer.stop();
    295     m_wantsToExitAcceleratedCompositingMode = false;
    296 
    297     ASSERT(m_layerTreeHost);
    298 
    299     m_layerTreeHost->invalidate();
    300     m_layerTreeHost = nullptr;
     297    AcceleratedDrawingArea::exitAcceleratedCompositingModeNow();
    301298    m_dirtyRegion = m_webPage.bounds();
    302299
  • trunk/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h

    r211350 r211365  
    9090#if USE(COORDINATED_GRAPHICS)
    9191    virtual void scheduleAnimation() = 0;
     92    virtual void setIsDiscardable(bool) { };
    9293#endif
    9394
Note: See TracChangeset for help on using the changeset viewer.