Changeset 109843 in webkit


Ignore:
Timestamp:
Mar 5, 2012 8:33:16 PM (12 years ago)
Author:
andersca@apple.com
Message:

pinch-to-zoom and double-tap flicker when using the new scrolling model
https://bugs.webkit.org/show_bug.cgi?id=80368
<rdar://problem/10866221>

Reviewed by Sam Weinig.

Source/WebCore:

In order to work better with zooming, make the tile cache undo the scale transformation
and handle the scaling manually. This avoids creating huge tile backing stores when zoomed in.

  • platform/graphics/ca/mac/TileCache.mm:

(WebCore::TileCache::TileCache):
Initialize m_scale to 1.

(WebCore::TileCache::setNeedsDisplayInRect):
Scale the given rect appropriately.

(WebCore::TileCache::drawLayer):
Apply a scale context transform.

(WebCore::TileCache::setScale):
No longer set the contents scale. Instead, update the scale and revalidate the tiles.

(WebCore::TileCache::revalidateTiles):
Return early if the bounds are empty. This avoids showing a single tile if that happens due to a race condition.

(WebCore::TileCache::getTileIndexRangeForRect):
Apply the scale to the bounds.

(WebCore::TileCache::createTileLayer):
Don't set the contents scale.

  • platform/graphics/ca/mac/WebTileCacheLayer.mm:

(-[WebTileCacheLayer setContentsScale:]):
Call TileCache::setScale.

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateCompositedBounds):
Make sure to give the tile cache layer sane composited bounds, even if the page has absolutely positioned
elements that are outside of the page.

Source/WebKit2:

Add a way for drawing areas to respond to callback based force repaint requests asynchronously.
This is currently needed for the tiled drawing area when there might be outstanding scroll updates
that are sent from the scrolling thread to the main thread and we need to ensure that they're processed
before sending a message back.

  • WebProcess/WebPage/DrawingArea.h:

(WebKit::DrawingArea::forceRepaintAsync):
Add new member function.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::forceRepaint):
Try forceRepaintAsync first.

  • WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:

(WebKit::forceRepaintAndSendMessage):
Force the repaint and send the message.

(WebKit::dispatchBackToMainThread):
Dispatch a call to forceRepaintAndSendMessage to the main thread.

(WebKit::TiledCoreAnimationDrawingArea::forceRepaintAsync):
Dispatch a function on the scrolling thread. Its sole purpose is to dispatch a function back to the
main thread, ensuring that all previously dispatched functions have been executed.

Location:
trunk/Source
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r109841 r109843  
     12012-03-05  Anders Carlsson  <andersca@apple.com>
     2
     3        pinch-to-zoom and double-tap flicker when using the new scrolling model
     4        https://bugs.webkit.org/show_bug.cgi?id=80368
     5        <rdar://problem/10866221>
     6
     7        Reviewed by Sam Weinig.
     8
     9        In order to work better with zooming, make the tile cache undo the scale transformation
     10        and handle the scaling manually. This avoids creating huge tile backing stores when zoomed in.
     11
     12        * platform/graphics/ca/mac/TileCache.mm:
     13        (WebCore::TileCache::TileCache):
     14        Initialize m_scale to 1.
     15
     16        (WebCore::TileCache::setNeedsDisplayInRect):
     17        Scale the given rect appropriately.
     18
     19        (WebCore::TileCache::drawLayer):
     20        Apply a scale context transform.
     21
     22        (WebCore::TileCache::setScale):
     23        No longer set the contents scale. Instead, update the scale and revalidate the tiles.
     24
     25        (WebCore::TileCache::revalidateTiles):
     26        Return early if the bounds are empty. This avoids showing a single tile if that happens due to a race condition.
     27
     28        (WebCore::TileCache::getTileIndexRangeForRect):
     29        Apply the scale to the bounds.
     30
     31        (WebCore::TileCache::createTileLayer):
     32        Don't set the contents scale.
     33
     34        * platform/graphics/ca/mac/WebTileCacheLayer.mm:
     35        (-[WebTileCacheLayer setContentsScale:]):
     36        Call TileCache::setScale.
     37
     38        * rendering/RenderLayerBacking.cpp:
     39        (WebCore::RenderLayerBacking::updateCompositedBounds):
     40        Make sure to give the tile cache layer sane composited bounds, even if the page has absolutely positioned
     41        elements that are outside of the page.
     42
    1432012-03-05  Leo Yang  <leo.yang@torchmobile.com.cn>
    244
  • trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.h

    r109788 r109843  
    5757    void setNeedsDisplayInRect(const IntRect&);
    5858    void drawLayer(WebTileLayer*, CGContextRef);
    59     void setContentsScale(CGFloat);
     59
     60    void setScale(CGFloat);
    6061
    6162    bool acceleratesDrawing() const { return m_acceleratesDrawing; }
     
    100101    IntRect m_tileCoverageRect;
    101102
     103    CGFloat m_scale;
     104
    102105    bool m_acceleratesDrawing;
    103106
  • trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.mm

    r109788 r109843  
    5555    , m_tileSize(tileSize)
    5656    , m_tileRevalidationTimer(this, &TileCache::tileRevalidationTimerFired)
     57    , m_scale(1)
    5758    , m_acceleratesDrawing(false)
    5859    , m_tileDebugBorderWidth(0)
     
    9192        return;
    9293
     94    IntRect scaledRect = rect;
     95    scaledRect.scale(m_scale);
     96
    9397    // Find the tiles that need to be invalidated.
    9498    TileIndex topLeft;
    9599    TileIndex bottomRight;
    96     getTileIndexRangeForRect(intersection(rect, m_tileCoverageRect), topLeft, bottomRight);
     100    getTileIndexRangeForRect(intersection(scaledRect, m_tileCoverageRect), topLeft, bottomRight);
    97101
    98102    for (int y = topLeft.y(); y <= bottomRight.y(); ++y) {
     
    127131    CGPoint layerOrigin = [layer frame].origin;
    128132    CGContextTranslateCTM(context, -layerOrigin.x, -layerOrigin.y);
     133    CGContextScaleCTM(context, m_scale, m_scale);
    129134    drawLayerContents(context, layer, platformLayer);
    130135
     
    163168}
    164169
    165 void TileCache::setContentsScale(CGFloat contentsScale)
    166 {
     170void TileCache::setScale(CGFloat scale)
     171{
     172    if (m_scale == scale)
     173        return;
     174
    167175#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    168     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    169         [it->second.get() setContentsScale:contentsScale];
     176    m_scale = scale;
     177    [m_tileContainerLayer.get() setTransform:CATransform3DMakeScale(1 / m_scale, 1 / m_scale, 1)];
     178
     179    revalidateTiles();
     180
     181    for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    170182        [it->second.get() setNeedsDisplay];
    171     }
    172183
    173184    PlatformCALayer* platformLayer = PlatformCALayer::platformCALayer(m_tileCacheLayer);
    174185    platformLayer->owner()->platformCALayerDidCreateTiles();
    175     revalidateTiles();
    176186#else
    177187    UNUSED_PARAM(contentsScale);
     
    235245void TileCache::getTileIndexRangeForRect(const IntRect& rect, TileIndex& topLeft, TileIndex& bottomRight)
    236246{
    237     IntRect clampedRect = intersection(rect, bounds());
     247    IntRect clampedRect = bounds();
     248    clampedRect.scale(m_scale);
     249    clampedRect.intersect(rect);
    238250
    239251    topLeft.setX(max(clampedRect.x() / m_tileSize.width(), 0));
     
    264276        return;
    265277
    266     if (m_visibleRect.isEmpty())
     278    if (m_visibleRect.isEmpty() || bounds().isEmpty())
    267279        return;
    268280
     
    352364
    353365#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    354     [layer.get() setContentsScale:[m_tileCacheLayer contentsScale]];
    355366    [layer.get() setAcceleratesDrawing:m_acceleratesDrawing];
    356367#endif
  • trunk/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm

    r109788 r109843  
    104104- (void)setContentsScale:(CGFloat)contentsScale
    105105{
    106 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    107     CGFloat oldContentsScale = [self contentsScale];
    108 
    109     [super setContentsScale:contentsScale];
    110 
    111     if (contentsScale != oldContentsScale)
    112         _tileCache->setContentsScale(contentsScale);
    113 #else
    114     UNUSED_PARAM(contentsScale);
    115 #endif
     106    _tileCache->setScale(contentsScale);
    116107}
    117108
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r108422 r109843  
    237237    // is a fullscreen renderer, don't clip to the viewport, as the renderer will be asked to
    238238    // display outside of the viewport bounds.
    239     if (compositor()->compositingConsultsOverlap() && !layerOrAncestorIsTransformed(m_owningLayer)
     239    if (compositor()->compositingConsultsOverlap() && (!layerOrAncestorIsTransformed(m_owningLayer) || m_usingTiledCacheLayer)
    240240#if ENABLE(FULLSCREEN_API)
    241241        && !layerOrAncestorIsFullScreen(m_owningLayer)
  • trunk/Source/WebKit2/ChangeLog

    r109826 r109843  
     12012-03-05  Anders Carlsson  <andersca@apple.com>
     2
     3        pinch-to-zoom and double-tap flicker when using the new scrolling model
     4        https://bugs.webkit.org/show_bug.cgi?id=80368
     5        <rdar://problem/10866221>
     6
     7        Reviewed by Sam Weinig.
     8
     9        Add a way for drawing areas to respond to callback based force repaint requests asynchronously.
     10        This is currently needed for the tiled drawing area when there might be outstanding scroll updates
     11        that are sent from the scrolling thread to the main thread and we need to ensure that they're processed
     12        before sending a message back.
     13
     14        * WebProcess/WebPage/DrawingArea.h:
     15        (WebKit::DrawingArea::forceRepaintAsync):
     16        Add new member function.
     17
     18        * WebProcess/WebPage/WebPage.cpp:
     19        (WebKit::WebPage::forceRepaint):
     20        Try forceRepaintAsync first.
     21
     22        * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
     23        (WebKit::forceRepaintAndSendMessage):
     24        Force the repaint and send the message.
     25
     26        (WebKit::dispatchBackToMainThread):
     27        Dispatch a call to forceRepaintAndSendMessage to the main thread.
     28
     29        (WebKit::TiledCoreAnimationDrawingArea::forceRepaintAsync):
     30        Dispatch a function on the scrolling thread. Its sole purpose is to dispatch a function back to the
     31        main thread, ensuring that all previously dispatched functions have been executed.
     32
    1332012-03-05  Enrica Casucci  <enrica@apple.com>
    234
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h

    r109804 r109843  
    6767    virtual void pageBackgroundTransparencyChanged() { }
    6868    virtual void forceRepaint() { }
     69    virtual bool forceRepaintAsync(uint64_t callbackID) { return false; }
    6970    virtual void setLayerTreeStateIsFrozen(bool) { }
    7071    virtual bool layerTreeStateIsFrozen() const { return false; }
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r109548 r109843  
    18221822void WebPage::forceRepaint(uint64_t callbackID)
    18231823{
     1824    if (m_drawingArea->forceRepaintAsync(callbackID))
     1825        return;
     1826
    18241827    forceRepaintWithoutCallback();
    18251828    send(Messages::WebPageProxy::VoidCallback(callbackID));
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h

    r109812 r109843  
    5454
    5555    virtual void forceRepaint() OVERRIDE;
     56    virtual bool forceRepaintAsync(uint64_t callbackID) OVERRIDE;
    5657    virtual void setLayerTreeStateIsFrozen(bool) OVERRIDE;
    5758    virtual bool layerTreeStateIsFrozen() const OVERRIDE;
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm

    r109812 r109843  
    3232#import "LayerTreeContext.h"
    3333#import "WebPage.h"
     34#import "WebPageProxyMessages.h"
    3435#import "WebProcess.h"
    3536#import <QuartzCore/QuartzCore.h>
     
    4142#import <WebCore/RenderView.h>
    4243#import <WebCore/ScrollingCoordinator.h>
     44#import <WebCore/ScrollingThread.h>
    4345#import <WebCore/Settings.h>
     46#import <wtf/MainThread.h>
    4447
    4548@interface CATransaction (Details)
     
    124127    [CATransaction flush];
    125128    [CATransaction synchronize];
     129}
     130
     131#if ENABLE(THREADED_SCROLLING)
     132static void forceRepaintAndSendMessage(uint64_t webPageID, uint64_t callbackID)
     133{
     134    WebPage* webPage = WebProcess::shared().webPage(webPageID);
     135    if (!webPage)
     136        return;
     137
     138    webPage->drawingArea()->forceRepaint();
     139    webPage->send(Messages::WebPageProxy::VoidCallback(callbackID));
     140}
     141
     142static void dispatchBackToMainThread(uint64_t webPageID, uint64_t callbackID)
     143{
     144    callOnMainThread(bind(forceRepaintAndSendMessage, webPageID, callbackID));
     145}
     146#endif
     147
     148bool TiledCoreAnimationDrawingArea::forceRepaintAsync(uint64_t callbackID)
     149{
     150#if ENABLE(THREADED_SCROLLING)
     151    if (m_layerTreeStateIsFrozen)
     152        return false;
     153
     154    ScrollingThread::dispatch(bind(dispatchBackToMainThread, m_webPage->pageID(), callbackID));
     155    return true;
     156#else
     157    return false;
     158#endif
    126159}
    127160
Note: See TracChangeset for help on using the changeset viewer.