Changeset 172869 in webkit


Ignore:
Timestamp:
Aug 22, 2014 1:26:14 PM (10 years ago)
Author:
Simon Fraser
Message:

Implement paint flashing in the WK1 InspectorOverlay page
https://bugs.webkit.org/show_bug.cgi?id=136138

Reviewed by Sam Weinig, Joseph Pecoraro.

Implement paint flashing for the WebKit1 InspectorOverlay via a second canvas in the overlay page.
We avoid allocating backing store for this canvas until we have paint rects.

Because this overlay page is weird and doesn't know how to paint itself, InspectorOverlay manages
an array of rects, and pushes them to the page when they change, before forcing a paint.

Because iOS doesn't use the InspectorOverlay page, stub out setShowPaintRects on its
WebKit WebInspectorClient, but don't yet implement paint flashing there.

Source/WebCore:

  • inspector/InspectorOverlay.cpp:

(WebCore::InspectorOverlay::InspectorOverlay):
(WebCore::InspectorOverlay::shouldShowOverlay):
(WebCore::InspectorOverlay::update):
(WebCore::buildObjectForRect):
(WebCore::InspectorOverlay::setShowingPaintRects):
(WebCore::InspectorOverlay::showPaintRect):
(WebCore::InspectorOverlay::updatePaintRectsTimerFired):
(WebCore::InspectorOverlay::drawPaintRects):
(WebCore::InspectorOverlay::forcePaint):
(WebCore::quadToPath): Deleted.
(WebCore::drawOutlinedQuad): Deleted.
(WebCore::InspectorOverlay::drawOutline): Deleted.

  • inspector/InspectorOverlay.h:
  • inspector/InspectorOverlayPage.html:
  • inspector/InspectorOverlayPage.js:

(updatePaintRects):
(reset):
(_drawShapeHighlight):

  • inspector/InspectorPageAgent.cpp:

(WebCore::InspectorPageAgent::setShowPaintRects):
(WebCore::InspectorPageAgent::didPaint):

Source/WebKit/ios:

  • WebCoreSupport/WebInspectorClientIOS.mm:

(WebInspectorClient::setShowPaintRects):
(WebInspectorClient::showPaintRect):

Source/WebKit/mac:

  • WebCoreSupport/WebInspectorClient.h:
  • WebCoreSupport/WebInspectorClient.mm:

(WebInspectorClient::WebInspectorClient):

Location:
trunk/Source
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r172868 r172869  
     12014-08-22  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Implement paint flashing in the WK1 InspectorOverlay page
     4        https://bugs.webkit.org/show_bug.cgi?id=136138
     5
     6        Reviewed by Sam Weinig, Joseph Pecoraro.
     7
     8        Implement paint flashing for the WebKit1 InspectorOverlay via a second canvas in the overlay page.
     9        We avoid allocating backing store for this canvas until we have paint rects.
     10       
     11        Because this overlay page is weird and doesn't know how to paint itself, InspectorOverlay manages
     12        an array of rects, and pushes them to the page when they change, before forcing a paint.
     13       
     14        Because iOS doesn't use the InspectorOverlay page, stub out setShowPaintRects on its
     15        WebKit WebInspectorClient, but don't yet implement paint flashing there.
     16
     17        * inspector/InspectorOverlay.cpp:
     18        (WebCore::InspectorOverlay::InspectorOverlay):
     19        (WebCore::InspectorOverlay::shouldShowOverlay):
     20        (WebCore::InspectorOverlay::update):
     21        (WebCore::buildObjectForRect):
     22        (WebCore::InspectorOverlay::setShowingPaintRects):
     23        (WebCore::InspectorOverlay::showPaintRect):
     24        (WebCore::InspectorOverlay::updatePaintRectsTimerFired):
     25        (WebCore::InspectorOverlay::drawPaintRects):
     26        (WebCore::InspectorOverlay::forcePaint):
     27        (WebCore::quadToPath): Deleted.
     28        (WebCore::drawOutlinedQuad): Deleted.
     29        (WebCore::InspectorOverlay::drawOutline): Deleted.
     30        * inspector/InspectorOverlay.h:
     31        * inspector/InspectorOverlayPage.html:
     32        * inspector/InspectorOverlayPage.js:
     33        (updatePaintRects):
     34        (reset):
     35        (_drawShapeHighlight):
     36        * inspector/InspectorPageAgent.cpp:
     37        (WebCore::InspectorPageAgent::setShowPaintRects):
     38        (WebCore::InspectorPageAgent::didPaint):
     39
    1402014-08-22  Eric Carlson  <eric.carlson@apple.com>
    241
  • trunk/Source/WebCore/inspector/InspectorOverlay.cpp

    r171951 r172869  
    6464namespace WebCore {
    6565
    66 static Path quadToPath(const FloatQuad& quad)
    67 {
    68     Path quadPath;
    69     quadPath.moveTo(quad.p1());
    70     quadPath.addLineTo(quad.p2());
    71     quadPath.addLineTo(quad.p3());
    72     quadPath.addLineTo(quad.p4());
    73     quadPath.closeSubpath();
    74     return quadPath;
    75 }
    76 
    77 static void drawOutlinedQuad(GraphicsContext* context, const FloatQuad& quad, const Color& fillColor, const Color& outlineColor)
    78 {
    79     static const int outlineThickness = 2;
    80 
    81     Path quadPath = quadToPath(quad);
    82 
    83     // Clip out the quad, then draw with a 2px stroke to get a pixel
    84     // of outline (because inflating a quad is hard)
    85     {
    86         context->save();
    87         context->clipOut(quadPath);
    88 
    89         context->setStrokeThickness(outlineThickness);
    90         context->setStrokeColor(outlineColor, ColorSpaceDeviceRGB);
    91         context->strokePath(quadPath);
    92 
    93         context->restore();
    94     }
    95 
    96     // Now do the fill
    97     context->setFillColor(fillColor, ColorSpaceDeviceRGB);
    98     context->fillPath(quadPath);
    99 }
    100 
    10166static void contentsQuadToCoordinateSystem(const FrameView* mainView, const FrameView* view, FloatQuad& quad, InspectorOverlay::CoordinateSystem coordinateSystem)
    10267{
     
    239204    : m_page(page)
    240205    , m_client(client)
     206    , m_paintRectUpdateTimer(this, &InspectorOverlay::updatePaintRectsTimerFired)
    241207    , m_indicating(false)
     208    , m_showingPaintRects(false)
    242209{
    243210}
     
    256223    view->updateLayoutAndStyleIfNeededRecursive();
    257224    view->paint(&context, IntRect(0, 0, view->width(), view->height()));
    258 }
    259 
    260 void InspectorOverlay::drawOutline(GraphicsContext* context, const LayoutRect& rect, const Color& color)
    261 {
    262     FloatRect outlineRect = rect;
    263     drawOutlinedQuad(context, outlineRect, Color(), color);
    264225}
    265226
     
    330291bool InspectorOverlay::shouldShowOverlay() const
    331292{
    332     return m_highlightNode || m_highlightNode || m_indicating || !m_pausedInDebuggerMessage.isNull();
     293    return m_highlightNode || m_highlightNode || m_indicating || m_showingPaintRects || !m_pausedInDebuggerMessage.isNull();
    333294}
    334295
     
    360321    drawQuadHighlight();
    361322    drawPausedInDebuggerMessage();
     323    drawPaintRects();
    362324
    363325    // Position DOM elements.
     
    366328        overlayView->layout();
    367329
    368     // Kick paint.
    369     m_client->highlight();
     330    forcePaint();
    370331}
    371332
     
    373334{
    374335    RefPtr<InspectorObject> object = InspectorObject::create();
    375     object->setNumber("x", point.x());
    376     object->setNumber("y", point.y());
     336    object->setNumber(ASCIILiteral("x"), point.x());
     337    object->setNumber(ASCIILiteral("y"), point.y());
     338    return object.release();
     339}
     340
     341static PassRefPtr<InspectorObject> buildObjectForRect(const FloatRect& rect)
     342{
     343    RefPtr<InspectorObject> object = InspectorObject::create();
     344    object->setNumber(ASCIILiteral("x"), rect.x());
     345    object->setNumber(ASCIILiteral("y"), rect.y());
     346    object->setNumber(ASCIILiteral("width"), rect.width());
     347    object->setNumber(ASCIILiteral("height"), rect.height());
    377348    return object.release();
    378349}
     
    500471}
    501472
     473void InspectorOverlay::setShowingPaintRects(bool showingPaintRects)
     474{
     475    if (m_showingPaintRects == showingPaintRects)
     476        return;
     477
     478    m_showingPaintRects = showingPaintRects;
     479    if (!m_showingPaintRects) {
     480        m_paintRects.clear();
     481        m_paintRectUpdateTimer.stop();
     482        drawPaintRects();
     483        forcePaint();
     484    }
     485}
     486
     487void InspectorOverlay::showPaintRect(const FloatRect& rect)
     488{
     489    if (!m_showingPaintRects)
     490        return;
     491
     492    IntRect rootRect = m_page.mainFrame().view()->contentsToRootView(enclosedIntRect(rect));
     493
     494    const constexpr std::chrono::milliseconds removeDelay = std::chrono::milliseconds(250);
     495
     496    std::chrono::steady_clock::time_point removeTime = std::chrono::steady_clock::now() + removeDelay;
     497    m_paintRects.append(TimeRectPair(removeTime, rootRect));
     498
     499    if (!m_paintRectUpdateTimer.isActive()) {
     500        const double paintRectsUpdateIntervalSeconds = 0.032;
     501        m_paintRectUpdateTimer.startRepeating(paintRectsUpdateIntervalSeconds);
     502    }
     503
     504    drawPaintRects();
     505    forcePaint();
     506}
     507
     508void InspectorOverlay::updatePaintRectsTimerFired(Timer<InspectorOverlay>&)
     509{
     510    std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
     511    bool rectsChanged = false;
     512    while (!m_paintRects.isEmpty() && m_paintRects.first().first < now) {
     513        m_paintRects.removeFirst();
     514        rectsChanged = true;
     515    }
     516   
     517    if (m_paintRects.isEmpty())
     518        m_paintRectUpdateTimer.stop();
     519
     520    if (rectsChanged) {
     521        drawPaintRects();
     522        forcePaint();
     523    }
     524}
     525
     526void InspectorOverlay::drawPaintRects()
     527{
     528    RefPtr<InspectorArray> fragmentsArray = InspectorArray::create();
     529    for (const auto& pair : m_paintRects)
     530        fragmentsArray->pushObject(buildObjectForRect(pair.second));
     531
     532    evaluateInOverlay(ASCIILiteral("updatePaintRects"), fragmentsArray.release());
     533}
     534
    502535void InspectorOverlay::drawGutter()
    503536{
    504     evaluateInOverlay("drawGutter");
     537    evaluateInOverlay(ASCIILiteral("drawGutter"));
    505538}
    506539
     
    818851}
    819852
     853void InspectorOverlay::forcePaint()
     854{
     855    // This overlay page is very weird and doesn't automatically paint. We have to force paints manually.
     856    m_client->highlight();
     857}
     858
    820859void InspectorOverlay::reset(const IntSize& viewportSize, const IntSize& frameViewFullSize)
    821860{
  • trunk/Source/WebCore/inspector/InspectorOverlay.h

    r170406 r172869  
    3333#include "FloatQuad.h"
    3434#include "LayoutRect.h"
     35#include "Timer.h"
     36#include <wtf/Deque.h>
    3537#include <wtf/RefPtr.h>
    3638#include <wtf/Vector.h>
     
    111113    void update();
    112114    void paint(GraphicsContext&);
    113     void drawOutline(GraphicsContext*, const LayoutRect&, const Color&);
    114115    void getHighlight(Highlight*, CoordinateSystem) const;
    115116
     
    119120    void highlightNode(Node*, const HighlightConfig&);
    120121    void highlightQuad(std::unique_ptr<FloatQuad>, const HighlightConfig&);
    121 
     122   
     123    void setShowingPaintRects(bool);
     124    void showPaintRect(const FloatRect&);
     125   
    122126    Node* highlightedNode() const;
    123127
     
    135139    void drawQuadHighlight();
    136140    void drawPausedInDebuggerMessage();
     141    void drawPaintRects();
     142    void updatePaintRectsTimerFired(Timer<InspectorOverlay>&);
     143
    137144    Page* overlayPage();
     145
     146    void forcePaint();
    138147    void reset(const IntSize& viewportSize, const IntSize& frameViewFullSize);
    139148    void evaluateInOverlay(const String& method);
     
    149158    std::unique_ptr<Page> m_overlayPage;
    150159    HighlightConfig m_quadHighlightConfig;
     160   
     161    typedef std::pair<std::chrono::steady_clock::time_point, FloatRect> TimeRectPair;
     162    Deque<TimeRectPair> m_paintRects;
     163    Timer<InspectorOverlay> m_paintRectUpdateTimer;
    151164    bool m_indicating;
     165    bool m_showingPaintRects;
    152166};
    153167
  • trunk/Source/WebCore/inspector/InspectorOverlayPage.html

    r165676 r172869  
    3535<div class="message-line"><span class="message-box" id="paused-in-debugger"></span></div>
    3636<canvas id="canvas" class="fill"></canvas>
     37<canvas id="paintrects-canvas" class="fill"></canvas>
    3738<div id="element-title-container"></div>
    3839<div id="right-gutter"></div>
  • trunk/Source/WebCore/inspector/InspectorOverlayPage.js

    r167086 r172869  
    2222const shapeHighlightColor = "rgba(96, 82, 127, 0.8)";
    2323const shapeMarginHighlightColor = "rgba(96, 82, 127, 0.6)";
     24
     25const paintRectFillColor = "rgba(255, 0, 0, 0.5)";
    2426
    2527function drawPausedInDebuggerMessage(message)
     
    164166}
    165167
     168var updatePaintRectsIntervalID;
     169
     170function updatePaintRects(paintRectList)
     171{
     172    var context = paintRectsCanvas.getContext("2d");
     173    context.save();
     174    context.scale(window.devicePixelRatio, window.devicePixelRatio);
     175
     176    context.clearRect(0, 0, paintRectsCanvas.width, paintRectsCanvas.height);
     177
     178    context.fillStyle = paintRectFillColor;
     179
     180    for (var rectObject of paintRectList)
     181        context.fillRect(rectObject.x, rectObject.y, rectObject.width, rectObject.height);
     182
     183    context.restore();
     184}
     185
    166186function reset(resetData)
    167187{
     
    171191
    172192    window.canvas = document.getElementById("canvas");
     193    window.paintRectsCanvas = document.getElementById("paintrects-canvas");
     194
    173195    window.context = canvas.getContext("2d");
    174196    window.rightGutter = document.getElementById("right-gutter");
     
    180202    canvas.style.height = viewportSize.height + "px";
    181203    context.scale(deviceScaleFactor, deviceScaleFactor);
     204
     205    // We avoid getting the the context for the paint rects canvas until we need to paint, to avoid backing store allocation.
     206    paintRectsCanvas.width = deviceScaleFactor * viewportSize.width;
     207    paintRectsCanvas.height = deviceScaleFactor * viewportSize.height;
     208    paintRectsCanvas.style.width = viewportSize.width + "px";
     209    paintRectsCanvas.style.height = viewportSize.height + "px";
    182210
    183211    document.getElementById("paused-in-debugger").style.visibility = "hidden";
     
    384412}
    385413
    386 function _drawShapeHighlight(shapeInfo) {
     414function _drawShapeHighlight(shapeInfo)
     415{
    387416    if (shapeInfo.marginShape)
    388417        drawPath(context, shapeInfo.marginShape, shapeMarginHighlightColor);
  • trunk/Source/WebCore/inspector/InspectorPageAgent.cpp

    r172864 r172869  
    653653    m_showPaintRects = show;
    654654    m_client->setShowPaintRects(show);
    655 
    656     if (!show && mainFrame() && mainFrame()->view())
    657         mainFrame()->view()->invalidate();
     655   
     656    if (m_client->overridesShowPaintRects())
     657        return;
     658
     659    m_overlay->setShowingPaintRects(show);
    658660}
    659661
     
    900902    }
    901903
    902     // FIXME: the overlay needs to accumulate paint rects and draw them itself.
     904    m_overlay->showPaintRect(rect);
    903905}
    904906
  • trunk/Source/WebKit/ios/ChangeLog

    r172719 r172869  
     12014-08-22  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Implement paint flashing in the WK1 InspectorOverlay page
     4        https://bugs.webkit.org/show_bug.cgi?id=136138
     5
     6        Reviewed by Sam Weinig, Joseph Pecoraro.
     7
     8        Implement paint flashing for the WebKit1 InspectorOverlay via a second canvas in the overlay page.
     9        We avoid allocating backing store for this canvas until we have paint rects.
     10       
     11        Because this overlay page is weird and doesn't know how to paint itself, InspectorOverlay manages
     12        an array of rects, and pushes them to the page when they change, before forcing a paint.
     13       
     14        Because iOS doesn't use the InspectorOverlay page, stub out setShowPaintRects on its
     15        WebKit WebInspectorClient, but don't yet implement paint flashing there.
     16
     17        * WebCoreSupport/WebInspectorClientIOS.mm:
     18        (WebInspectorClient::setShowPaintRects):
     19        (WebInspectorClient::showPaintRect):
     20
    1212014-08-18  Andy Estes  <aestes@apple.com>
    222
  • trunk/Source/WebKit/ios/WebCoreSupport/WebInspectorClientIOS.mm

    r170774 r172869  
    9898}
    9999
     100void WebInspectorClient::setShowPaintRects(bool)
     101{
     102    // FIXME: implement.
     103}
     104
     105void WebInspectorClient::showPaintRect(const FloatRect&)
     106{
     107    // FIXME: need to do CALayer-based highlighting of paint rects.
     108}
     109
    100110void WebInspectorClient::didSetSearchingForNode(bool enabled)
    101111{
  • trunk/Source/WebKit/mac/ChangeLog

    r172866 r172869  
     12014-08-22  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Implement paint flashing in the WK1 InspectorOverlay page
     4        https://bugs.webkit.org/show_bug.cgi?id=136138
     5
     6        Reviewed by Sam Weinig, Joseph Pecoraro.
     7
     8        Implement paint flashing for the WebKit1 InspectorOverlay via a second canvas in the overlay page.
     9        We avoid allocating backing store for this canvas until we have paint rects.
     10       
     11        Because this overlay page is weird and doesn't know how to paint itself, InspectorOverlay manages
     12        an array of rects, and pushes them to the page when they change, before forcing a paint.
     13       
     14        Because iOS doesn't use the InspectorOverlay page, stub out setShowPaintRects on its
     15        WebKit WebInspectorClient, but don't yet implement paint flashing there.
     16
     17        * WebCoreSupport/WebInspectorClient.h:
     18        * WebCoreSupport/WebInspectorClient.mm:
     19        (WebInspectorClient::WebInspectorClient):
     20
    1212014-08-20  Maciej Stachowiak  <mjs@apple.com>
    222
  • trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h

    r166257 r172869  
    7777    virtual void showInspectorIndication() override;
    7878    virtual void hideInspectorIndication() override;
     79
     80    virtual bool overridesShowPaintRects() const override { return true; }
     81    virtual void setShowPaintRects(bool) override;
     82    virtual void showPaintRect(const WebCore::FloatRect&) override;
    7983#endif
    8084
Note: See TracChangeset for help on using the changeset viewer.