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

Changeset 144067 in webkit


Ignore:
Timestamp:
Feb 26, 2013, 9:16:35 AM (14 years ago)
Author:
dino@apple.com
Message:

Draw intermediate snapshots if possible
https://bugs.webkit.org/show_bug.cgi?id=110811

Reviewed by Simon Fraser.

After http://webkit.org/b/110495 we delayed snapshotting until we've
received a nice image, but this made the page look like it is broken.
We should draw any intermediate snapshots that we find, which might
include content such as progress bars/spinners.

Source/WebCore:

  • html/HTMLPlugInElement.h:

(WebCore::HTMLPlugInElement::isPlugInImageElement): Expose virtual method
to indicate if this is a HTMLPlugInImageElement or not.

  • html/HTMLPlugInImageElement.cpp:

(WebCore::HTMLPlugInImageElement::updateSnapshot): If we have
a RenderEmbeddedObject renderer, then tell it to repaint.

  • html/HTMLPlugInImageElement.h:

(WebCore::HTMLPlugInImageElement::snapshotImage): Expose an
accessor for snapshot images.

  • rendering/RenderEmbeddedObject.cpp:

(WebCore::RenderEmbeddedObject::paintSnapshotImage): New helper
method to render an image directly. This code is similar to
that in RenderSnapshottedPlugIn.
(WebCore::RenderEmbeddedObject::paintContents): The virtual implementation
of this method for use when we have a snapshot to paint. If we are a plugin that is
in the process of being snapshotted, ask our HTMLPlugInImageElement for a
snapshot and paint that instead. In the case where we are not snapshotting,
or we do not yet have a snapshot, this will call back into the RenderWidget code.

  • rendering/RenderEmbeddedObject.h:

(RenderEmbeddedObject): New methods paintSnapshotImage and paintContents

  • rendering/RenderWidget.cpp:

(WebCore::RenderWidget::paintContents): New method called in the middle
of paint() that can be overridden by RenderEmbeddedObject. The code here was
simply moved out of the previous paint().
(WebCore::RenderWidget::paint): Call paintContents at the appropriate time.

  • rendering/RenderWidget.h:

(RenderWidget): New virtual method paintContents.

Source/WebKit2:

  • WebProcess/Plugins/PluginView.cpp:

(WebKit): Reinstate 60 attempts at snapshots before giving up.
(WebKit::PluginView::isAcceleratedCompositingEnabled): We do not
want accelerated compositing enabled when we are trying to capture
snapshots.

Location:
trunk/Source
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r144065 r144067  
     12013-02-26  Dean Jackson  <dino@apple.com>
     2
     3        Draw intermediate snapshots if possible
     4        https://bugs.webkit.org/show_bug.cgi?id=110811
     5
     6        Reviewed by Simon Fraser.
     7
     8        After http://webkit.org/b/110495 we delayed snapshotting until we've
     9        received a nice image, but this made the page look like it is broken.
     10        We should draw any intermediate snapshots that we find, which might
     11        include content such as progress bars/spinners.
     12
     13        * html/HTMLPlugInElement.h:
     14        (WebCore::HTMLPlugInElement::isPlugInImageElement): Expose virtual method
     15        to indicate if this is a HTMLPlugInImageElement or not.
     16        * html/HTMLPlugInImageElement.cpp:
     17        (WebCore::HTMLPlugInImageElement::updateSnapshot): If we have
     18        a RenderEmbeddedObject renderer, then tell it to repaint.
     19        * html/HTMLPlugInImageElement.h:
     20        (WebCore::HTMLPlugInImageElement::snapshotImage): Expose an
     21        accessor for snapshot images.
     22        * rendering/RenderEmbeddedObject.cpp:
     23        (WebCore::RenderEmbeddedObject::paintSnapshotImage): New helper
     24        method to render an image directly. This code is similar to
     25        that in RenderSnapshottedPlugIn.
     26        (WebCore::RenderEmbeddedObject::paintContents): The virtual implementation
     27        of this method for use when we have a snapshot to paint. If we are a plugin that is
     28        in the process of being snapshotted, ask our HTMLPlugInImageElement for a
     29        snapshot and paint that instead. In the case where we are not snapshotting,
     30        or we do not yet have a snapshot, this will call back into the RenderWidget code.
     31        * rendering/RenderEmbeddedObject.h:
     32        (RenderEmbeddedObject): New methods paintSnapshotImage and paintContents
     33        * rendering/RenderWidget.cpp:
     34        (WebCore::RenderWidget::paintContents): New method called in the middle
     35        of paint() that can be overridden by RenderEmbeddedObject. The code here was
     36        simply moved out of the previous paint().
     37        (WebCore::RenderWidget::paint): Call paintContents at the appropriate time.
     38        * rendering/RenderWidget.h:
     39        (RenderWidget): New virtual method paintContents.
     40
    1412013-02-26  Levi Weintraub  <leviw@chromium.org>
    242
  • trunk/Source/WebCore/html/HTMLPlugInElement.h

    r143843 r144067  
    7575    virtual bool willRespondToMouseClickEvents() OVERRIDE;
    7676
     77    virtual bool isPlugInImageElement() const { return false; }
     78
    7779protected:
    7880    HTMLPlugInElement(const QualifiedName& tagName, Document*);
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp

    r143684 r144067  
    285285
    286286    m_snapshotImage = image;
     287
    287288    if (renderer()->isSnapshottedPlugIn()) {
    288289        toRenderSnapshottedPlugIn(renderer())->updateSnapshot(image);
    289290        return;
    290291    }
     292
     293    if (renderer()->isEmbeddedObject())
     294        renderer()->repaint();
    291295}
    292296
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.h

    r143680 r144067  
    6767    void userDidClickSnapshot(PassRefPtr<MouseEvent>);
    6868    void updateSnapshotInfo();
     69    Image* snapshotImage() const { return m_snapshotImage.get(); }
    6970
    7071    // Plug-in URL might not be the same as url() with overriding parameters.
     
    112113    void swapRendererTimerFired(Timer<HTMLPlugInImageElement>*);
    113114
     115    virtual bool isPlugInImageElement() const OVERRIDE { return true; }
     116
    114117    bool m_needsWidgetUpdate;
    115118    bool m_shouldPreferPlugInsForImages;
  • trunk/Source/WebCore/rendering/RenderEmbeddedObject.cpp

    r137847 r144067  
    149149}
    150150
     151void RenderEmbeddedObject::paintSnapshotImage(PaintInfo& paintInfo, const LayoutPoint& paintOffset, Image* image)
     152{
     153    LayoutUnit cWidth = contentWidth();
     154    LayoutUnit cHeight = contentHeight();
     155    if (!cWidth || !cHeight)
     156        return;
     157
     158    GraphicsContext* context = paintInfo.context;
     159    LayoutSize contentSize(cWidth, cHeight);
     160    LayoutPoint contentLocation = location() + paintOffset;
     161    contentLocation.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
     162
     163    LayoutRect rect(contentLocation, contentSize);
     164    IntRect alignedRect = pixelSnappedIntRect(rect);
     165    if (alignedRect.width() <= 0 || alignedRect.height() <= 0)
     166        return;
     167
     168    bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, alignedRect.size());
     169    context->drawImage(image, style()->colorSpace(), alignedRect, CompositeSourceOver, shouldRespectImageOrientation(), useLowQualityScaling);
     170}
     171
     172void RenderEmbeddedObject::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     173{
     174    Element* element = static_cast<Element*>(node());
     175    if (!element || !element->isPluginElement())
     176        return;
     177
     178    HTMLPlugInElement* plugInElement = static_cast<HTMLPlugInElement*>(element);
     179    if (plugInElement->displayState() > HTMLPlugInElement::DisplayingSnapshot) {
     180        RenderPart::paintContents(paintInfo, paintOffset);
     181        return;
     182    }
     183
     184    if (!plugInElement->isPlugInImageElement())
     185        return;
     186
     187    Image* snapshot = static_cast<HTMLPlugInImageElement*>(plugInElement)->snapshotImage();
     188    if (snapshot)
     189        paintSnapshotImage(paintInfo, paintOffset, snapshot);
     190}
     191
    151192void RenderEmbeddedObject::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    152193{
  • trunk/Source/WebCore/rendering/RenderEmbeddedObject.h

    r140640 r144067  
    7676    virtual bool isEmbeddedObject() const { return true; }
    7777
     78    void paintSnapshotImage(PaintInfo&, const LayoutPoint&, Image*);
     79    virtual void paintContents(PaintInfo&, const LayoutPoint&) OVERRIDE;
     80
    7881#if USE(ACCELERATED_COMPOSITING)
    7982    virtual bool requiresLayer() const;
  • trunk/Source/WebCore/rendering/RenderWidget.cpp

    r143990 r144067  
    236236}
    237237
     238void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     239{
     240    LayoutPoint adjustedPaintOffset = paintOffset + location();
     241
     242    // Tell the widget to paint now. This is the only time the widget is allowed
     243    // to paint itself. That way it will composite properly with z-indexed layers.
     244    IntPoint widgetLocation = m_widget->frameRect().location();
     245    IntPoint paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + paddingLeft()),
     246        roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop()));
     247    IntRect paintRect = paintInfo.rect;
     248
     249    IntSize widgetPaintOffset = paintLocation - widgetLocation;
     250    // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
     251    // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
     252    if (!widgetPaintOffset.isZero()) {
     253        paintInfo.context->translate(widgetPaintOffset);
     254        paintRect.move(-widgetPaintOffset);
     255    }
     256    m_widget->paint(paintInfo.context, paintRect);
     257
     258    if (!widgetPaintOffset.isZero())
     259        paintInfo.context->translate(-widgetPaintOffset);
     260
     261    if (m_widget->isFrameView()) {
     262        FrameView* frameView = static_cast<FrameView*>(m_widget.get());
     263        bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContentIncludingDescendants();
     264        if (paintInfo.overlapTestRequests && runOverlapTests) {
     265            ASSERT(!paintInfo.overlapTestRequests->contains(this));
     266            paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
     267        }
     268    }
     269}
     270
    238271void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    239272{
     
    275308    }
    276309
    277     if (m_widget) {
    278         // Tell the widget to paint now.  This is the only time the widget is allowed
    279         // to paint itself.  That way it will composite properly with z-indexed layers.
    280         IntPoint widgetLocation = m_widget->frameRect().location();
    281         IntPoint paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + paddingLeft()),
    282             roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop()));
    283         IntRect paintRect = paintInfo.rect;
    284 
    285         IntSize widgetPaintOffset = paintLocation - widgetLocation;
    286         // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
    287         // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
    288         if (!widgetPaintOffset.isZero()) {
    289             paintInfo.context->translate(widgetPaintOffset);
    290             paintRect.move(-widgetPaintOffset);
    291         }
    292         m_widget->paint(paintInfo.context, paintRect);
    293 
    294         if (!widgetPaintOffset.isZero())
    295             paintInfo.context->translate(-widgetPaintOffset);
    296 
    297         if (m_widget->isFrameView()) {
    298             FrameView* frameView = static_cast<FrameView*>(m_widget.get());
    299             bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContentIncludingDescendants();
    300             if (paintInfo.overlapTestRequests && runOverlapTests) {
    301                 ASSERT(!paintInfo.overlapTestRequests->contains(this));
    302                 paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
    303             }
    304          }
    305     }
     310    if (m_widget)
     311        paintContents(paintInfo, paintOffset);
    306312
    307313    if (style()->hasBorderRadius())
  • trunk/Source/WebCore/rendering/RenderWidget.h

    r140640 r144067  
    8686    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
    8787
     88    virtual void paintContents(PaintInfo&, const LayoutPoint&);
     89
    8890private:
    8991    virtual bool isWidget() const { return true; }
  • trunk/Source/WebKit2/ChangeLog

    r144066 r144067  
     12013-02-26  Dean Jackson  <dino@apple.com>
     2
     3        Draw intermediate snapshots if possible
     4        https://bugs.webkit.org/show_bug.cgi?id=110811
     5
     6        Reviewed by Simon Fraser.
     7
     8        After http://webkit.org/b/110495 we delayed snapshotting until we've
     9        received a nice image, but this made the page look like it is broken.
     10        We should draw any intermediate snapshots that we find, which might
     11        include content such as progress bars/spinners.
     12
     13        * WebProcess/Plugins/PluginView.cpp:
     14        (WebKit): Reinstate 60 attempts at snapshots before giving up.
     15        (WebKit::PluginView::isAcceleratedCompositingEnabled): We do not
     16        want accelerated compositing enabled when we are trying to capture
     17        snapshots.
     18
    1192013-02-26  Andras Becsi  <andras.becsi@digia.com>
    220
  • trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp

    r143976 r144067  
    7272// This simulated mouse click delay in HTMLPlugInImageElement.cpp should generally be the same or shorter than this delay.
    7373static const double pluginSnapshotTimerDelay = 1.1;
    74 static const unsigned maximumSnapshotRetries = 4;
     74static const unsigned maximumSnapshotRetries = 60;
    7575
    7676class PluginView::URLRequest : public RefCounted<URLRequest> {
     
    13501350        return false;
    13511351
     1352    if (m_pluginElement->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick)
     1353        return false;
    13521354    return settings->acceleratedCompositingEnabled();
    13531355}
Note: See TracChangeset for help on using the changeset viewer.