Changeset 169820 in webkit


Ignore:
Timestamp:
Jun 11, 2014 12:59:24 PM (10 years ago)
Author:
roger_fong@apple.com
Message:

Don't snapshot offscreen plugins that would normally be considered primary plugins after they are moved in view.
https://bugs.webkit.org/show_bug.cgi?id=133667.
<rdar://problem/16743250>

Reviewed by Tim Horton.

  • WebProcess/Plugins/PluginView.cpp:

(WebKit::PluginView::PluginView):
(WebKit::PluginView::pluginSnapshotTimerFired):
Set the display state to Playing if the following is true:
The plugin in question is large enough to be considered the primary snapshot and either:
a) The maximum number of snapshot retries has been reached and no good snapshot has been found.
b) The plugin is moved to be on-screen while the snapshot attempts are in progress.

  • WebProcess/Plugins/PluginView.h:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::plugInIntersectsSearchRect): Re-factor out intersection logic.
(WebKit::WebPage::plugInIsPrimarySize): Re-factor out primary plugin size logic.
(WebKit::WebPage::determinePrimarySnapshottedPlugIn): Use the above two methods here.

  • WebProcess/WebPage/WebPage.h:
Location:
trunk/Source/WebKit2
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r169818 r169820  
     12014-06-11  Roger Fong  <roger_fong@apple.com>
     2
     3        Don't snapshot offscreen plugins that would normally be considered primary plugins after they are moved in view.
     4        https://bugs.webkit.org/show_bug.cgi?id=133667.
     5        <rdar://problem/16743250>
     6
     7        Reviewed by Tim Horton.
     8
     9        * WebProcess/Plugins/PluginView.cpp:
     10        (WebKit::PluginView::PluginView):
     11        (WebKit::PluginView::pluginSnapshotTimerFired):
     12        Set the display state to Playing if the following is true:
     13        The plugin in question is large enough to be considered the primary snapshot and either:
     14        a) The maximum number of snapshot retries has been reached and no good snapshot has been found.
     15        b) The plugin is moved to be on-screen while the snapshot attempts are in progress.
     16        * WebProcess/Plugins/PluginView.h:
     17        * WebProcess/WebPage/WebPage.cpp:
     18        (WebKit::WebPage::plugInIntersectsSearchRect): Re-factor out intersection logic.
     19        (WebKit::WebPage::plugInIsPrimarySize): Re-factor out primary plugin size logic.
     20        (WebKit::WebPage::determinePrimarySnapshottedPlugIn): Use the above two methods here.
     21        * WebProcess/WebPage/WebPage.h:
     22
    1232014-06-11  Anders Carlsson  <andersca@apple.com>
    224
  • trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp

    r169724 r169820  
    287287    , m_isBeingDestroyed(false)
    288288    , m_pluginProcessHasCrashed(false)
     289    , m_didPlugInStartOffScreen(false)
    289290    , m_pendingURLRequestsTimer(RunLoop::main(), this, &PluginView::pendingURLRequestsTimerFired)
    290291#if ENABLE(NETSCAPE_PLUGIN_API)
     
    16891690    ASSERT(m_plugin);
    16901691
     1692    HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(m_pluginElement.get());
     1693    bool isPlugInOnScreen = m_webPage->plugInIntersectsSearchRect(*plugInImageElement);
     1694    if (!m_countSnapshotRetries)
     1695        m_didPlugInStartOffScreen = !isPlugInOnScreen;
     1696
     1697    bool plugInCameOnScreen = isPlugInOnScreen && m_didPlugInStartOffScreen;
     1698    bool snapshotFound = false;
     1699
    16911700    if (m_plugin->supportsSnapshotting()) {
    16921701        // Snapshot might be 0 if plugin size is 0x0.
     
    16961705            snapshotImage = snapshot->createImage();
    16971706        m_pluginElement->updateSnapshot(snapshotImage.get());
     1707        bool snapshotIsAlmostSolidColor = isAlmostSolidColor(toBitmapImage(snapshotImage.get()));
     1708        snapshotFound = snapshotImage && !snapshotIsAlmostSolidColor;
    16981709
    16991710#if PLATFORM(COCOA)
    17001711        unsigned maximumSnapshotRetries = frame() ? frame()->settings().maximumPlugInSnapshotAttempts() : 0;
    1701         if (snapshotImage && isAlmostSolidColor(toBitmapImage(snapshotImage.get())) && m_countSnapshotRetries < maximumSnapshotRetries) {
     1712        if (snapshotImage && snapshotIsAlmostSolidColor && m_countSnapshotRetries < maximumSnapshotRetries && !plugInCameOnScreen) {
    17021713            ++m_countSnapshotRetries;
    17031714            m_pluginSnapshotTimer.restart();
     
    17061717#endif
    17071718    }
    1708     // Even if there is no snapshot we still set the state to DisplayingSnapshot
    1709     // since we just want to display the default empty box.
    1710     m_pluginElement->setDisplayState(HTMLPlugInElement::DisplayingSnapshot);
     1719    unsigned candidateArea = 0;
     1720    bool noSnapshotFoundAfterMaxRetries = m_countSnapshotRetries == frame()->settings().maximumPlugInSnapshotAttempts() && !isPlugInOnScreen && !snapshotFound;
     1721    if (m_webPage->plugInIsPrimarySize(*plugInImageElement, candidateArea)
     1722        && (noSnapshotFoundAfterMaxRetries || plugInCameOnScreen))
     1723        m_pluginElement->setDisplayState(HTMLPlugInElement::Playing);
     1724    else
     1725        m_pluginElement->setDisplayState(HTMLPlugInElement::DisplayingSnapshot);
    17111726}
    17121727
  • trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h

    r169724 r169820  
    239239    bool m_isBeingDestroyed;
    240240    bool m_pluginProcessHasCrashed;
     241    bool m_didPlugInStartOffScreen;
    241242
    242243    // Pending URLRequests that the plug-in has made.
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r169799 r169820  
    44734473                continue;
    44744474            auto& pluginRenderBox = toRenderBox(*pluginRenderer);
     4475            if (!plugInIntersectsSearchRect(plugInImageElement))
     4476                continue;
     4477
    44754478            IntRect plugInRectRelativeToView = plugInImageElement.clientRect();
    4476             if (plugInRectRelativeToView.isEmpty())
    4477                 continue;
    44784479            IntSize scrollOffset = mainFrame.view()->documentScrollOffsetRelativeToViewOrigin();
    44794480            IntRect plugInRectRelativeToTopDocument(plugInRectRelativeToView.location() + scrollOffset, plugInRectRelativeToView.size());
    4480             if (!plugInRectRelativeToTopDocument.intersects(searchRect))
    4481                 continue;
    4482 
    44834481            HitTestResult hitTestResult(plugInRectRelativeToTopDocument.center());
    44844482            mainRenderView.hitTest(request, hitTestResult);
     
    45054503                plugInImageElement.restartSnapshottedPlugIn();
    45064504            }
    4507             if (pluginRenderBox.contentWidth() < primarySnapshottedPlugInMinimumWidth || pluginRenderBox.contentHeight() < primarySnapshottedPlugInMinimumHeight)
    4508                 continue;
    4509 
    4510             LayoutUnit contentArea = pluginRenderBox.contentWidth() * pluginRenderBox.contentHeight();
    4511             if (contentArea > candidatePlugInArea * primarySnapshottedPlugInSearchBucketSize) {
     4505
     4506            if (plugInIsPrimarySize(plugInImageElement, candidatePlugInArea))
    45124507                candidatePlugIn = &plugInImageElement;
    4513                 candidatePlugInArea = contentArea;
    4514             }
    45154508        }
    45164509    }
     
    45474540
    45484541    return (pageOrigin == m_primaryPlugInPageOrigin && pluginOrigin == m_primaryPlugInOrigin && mimeType == m_primaryPlugInMimeType);
     4542}
     4543
     4544bool WebPage::plugInIntersectsSearchRect(HTMLPlugInImageElement& plugInImageElement)
     4545{
     4546    MainFrame& mainFrame = corePage()->mainFrame();
     4547    if (!mainFrame.view())
     4548        return false;
     4549    if (!mainFrame.view()->renderView())
     4550        return false;
     4551
     4552    IntRect searchRect = IntRect(IntPoint(), corePage()->mainFrame().view()->contentsSize());
     4553    searchRect.intersect(IntRect(IntPoint(), IntSize(primarySnapshottedPlugInSearchLimit, primarySnapshottedPlugInSearchLimit)));
     4554
     4555    IntRect plugInRectRelativeToView = plugInImageElement.clientRect();
     4556    if (plugInRectRelativeToView.isEmpty())
     4557        return false;
     4558    IntSize scrollOffset = mainFrame.view()->documentScrollOffsetRelativeToViewOrigin();
     4559    IntRect plugInRectRelativeToTopDocument(plugInRectRelativeToView.location() + scrollOffset, plugInRectRelativeToView.size());
     4560
     4561    return plugInRectRelativeToTopDocument.intersects(searchRect);
     4562}
     4563
     4564bool WebPage::plugInIsPrimarySize(WebCore::HTMLPlugInImageElement& plugInImageElement, unsigned& candidatePlugInArea)
     4565{
     4566    auto& pluginRenderBox = toRenderBox(*(plugInImageElement.renderer()));
     4567    if (pluginRenderBox.contentWidth() < primarySnapshottedPlugInMinimumWidth || pluginRenderBox.contentHeight() < primarySnapshottedPlugInMinimumHeight)
     4568        return false;
     4569
     4570    LayoutUnit contentArea = pluginRenderBox.contentWidth() * pluginRenderBox.contentHeight();
     4571    if (contentArea > candidatePlugInArea * primarySnapshottedPlugInSearchBucketSize) {
     4572        candidatePlugInArea = contentArea;
     4573        return true;
     4574    }
     4575    return false;
    45494576}
    45504577#endif // ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r169799 r169820  
    119119class FrameView;
    120120class HTMLPlugInElement;
     121class HTMLPlugInImageElement;
    121122class IntPoint;
    122123class KeyboardEvent;
     
    792793    void resetPrimarySnapshottedPlugIn();
    793794    bool matchesPrimaryPlugIn(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) const;
     795    bool plugInIntersectsSearchRect(WebCore::HTMLPlugInImageElement& pluginImageElement);
     796    bool plugInIsPrimarySize(WebCore::HTMLPlugInImageElement& pluginImageElement, unsigned &pluginArea);
    794797#endif
    795798
Note: See TracChangeset for help on using the changeset viewer.