Title: [158982] trunk/Source
Revision
158982
Author
[email protected]
Date
2013-11-08 17:43:45 -0800 (Fri, 08 Nov 2013)

Log Message

Remote Layer Tree: RemoteLayerBackingStore partial repaint is broken for the tile cache
https://bugs.webkit.org/show_bug.cgi?id=123944

Reviewed by Simon Fraser.

Ensure that the tile cache retrieves repaint rects from the tile layer,
not from the tiled backing layer.

Rework RemoteLayerBackingStore painting to fix some rounding issues
that would cause pixel cracks upon repaint, and to speed it up a bit.

* Shared/mac/RemoteLayerBackingStore.h:
Redefine RepaintRectList because we can't include WebLayer.h here yet.
Remove createBackingStore, which was never implemented.
Remove mapToContentCoordinates, because we don't need it on Mac.

(WebKit::RemoteLayerBackingStore::paintingRects): Added.

* Shared/mac/RemoteLayerBackingStore.mm:
(RemoteLayerBackingStore::setNeedsDisplay):
(RemoteLayerBackingStore::display):
Stop using mapToContentCoordinates.

(RemoteLayerBackingStore::drawInContext):
Use clipping instead of painting the image multiple times.
Never repaint more than the dirty region's bounds.
Don't waste time with all of the drawNativeImage code, just use CG.
Unindent the switch's cases.
Store the rects we're painting so that enumerateRectsBeingDrawn can get them.
Pixel-snap the rects we're painting.
Clip the context before going to paint.

* WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
(PlatformCALayerRemote::enumerateRectsBeingDrawn):
* WebProcess/WebPage/mac/PlatformCALayerRemote.h:
Retrieve the rects currently being painted from our backing store, and
transform them (mostly) according to the CTM, to match the transformation
that will have occurred underneath wkCALayerEnumerateRectsBeingDrawnWithBlock.

* platform/graphics/ca/PlatformCALayer.h:
* platform/graphics/ca/mac/PlatformCALayerMac.h:
* platform/graphics/ca/mac/PlatformCALayerMac.mm:
(PlatformCALayerMac::enumerateRectsBeingDrawn):
Allow the PlatformCALayer to decide how to enumerate rects to paint.

* WebCore.exp.in:
* platform/graphics/mac/WebLayer.h:
Add RepaintRectList, remove some unnecessary WebCore::s.

* platform/graphics/mac/WebLayer.mm:
(WebCore::collectRectsToPaint):
Factor collectRectsToPaint out; it just grabs the rects from
the layer and makes the decision whether to repaint the bounds
of the dirty region or just the subregions.

Move calls to collectRectsToPaint() to callers of drawLayerContents(),
so that TileController can collect rects from the appropriate source
(the Tile layer) and other layers just continue grabbing them from
their relevant layers.

Make sure that the list that comes from collectRectsToPaint() always
has at least one rect in it (appending the clip bounds if we don't
want to repaint subregions) so we can simplify logic in drawLayerContents.

(WebCore::drawLayerContents):
Remove code to support CompositingCoordinatesBottomUp, as it's only
used on Windows, so this Mac-specific code doesn't need to support it.

Simplify logic given that dirtyRects will always be non-empty.

(-[WebLayer drawInContext:]):
(-[WebSimpleLayer setNeedsDisplayInRect:]):
* platform/graphics/ca/mac/TileController.mm:
(WebCore::TileController::platformCALayerPaintContents):
Adopt collectRectsToPaint.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (158981 => 158982)


--- trunk/Source/WebCore/ChangeLog	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebCore/ChangeLog	2013-11-09 01:43:45 UTC (rev 158982)
@@ -1,3 +1,50 @@
+2013-11-08  Tim Horton  <[email protected]>
+
+        Remote Layer Tree: RemoteLayerBackingStore partial repaint is broken for the tile cache
+        https://bugs.webkit.org/show_bug.cgi?id=123944
+
+        Reviewed by Simon Fraser.
+
+        Ensure that the tile cache retrieves repaint rects from the tile layer,
+        not from the tiled backing layer.
+
+        * platform/graphics/ca/PlatformCALayer.h:
+        * platform/graphics/ca/mac/PlatformCALayerMac.h:
+        * platform/graphics/ca/mac/PlatformCALayerMac.mm:
+        (PlatformCALayerMac::enumerateRectsBeingDrawn):
+        Allow the PlatformCALayer to decide how to enumerate rects to paint.
+
+        * WebCore.exp.in:
+        * platform/graphics/mac/WebLayer.h:
+        Add RepaintRectList, remove some unnecessary WebCore::s.
+
+        * platform/graphics/mac/WebLayer.mm:
+        (WebCore::collectRectsToPaint):
+        Factor collectRectsToPaint out; it just grabs the rects from
+        the layer and makes the decision whether to repaint the bounds
+        of the dirty region or just the subregions.
+
+        Move calls to collectRectsToPaint() to callers of drawLayerContents(),
+        so that TileController can collect rects from the appropriate source
+        (the Tile layer) and other layers just continue grabbing them from
+        their relevant layers.
+
+        Make sure that the list that comes from collectRectsToPaint() always
+        has at least one rect in it (appending the clip bounds if we don't
+        want to repaint subregions) so we can simplify logic in drawLayerContents.
+
+        (WebCore::drawLayerContents):
+        Remove code to support CompositingCoordinatesBottomUp, as it's only
+        used on Windows, so this Mac-specific code doesn't need to support it.
+
+        Simplify logic given that dirtyRects will always be non-empty.
+
+        (-[WebLayer drawInContext:]):
+        (-[WebSimpleLayer setNeedsDisplayInRect:]):
+        * platform/graphics/ca/mac/TileController.mm:
+        (WebCore::TileController::platformCALayerPaintContents):
+        Adopt collectRectsToPaint.
+
 2013-11-08  Anders Carlsson  <[email protected]>
 
         Implement more KeyedEncoder functionality

Modified: trunk/Source/WebCore/WebCore.exp.in (158981 => 158982)


--- trunk/Source/WebCore/WebCore.exp.in	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebCore/WebCore.exp.in	2013-11-09 01:43:45 UTC (rev 158982)
@@ -691,7 +691,7 @@
 __ZN7WebCore17SQLiteTransactionD1Ev
 __ZN7WebCore17SubresourceLoader6createEPNS_5FrameEPNS_14CachedResourceERKNS_15ResourceRequestERKNS_21ResourceLoaderOptionsE
 __ZN7WebCore17cacheDOMStructureEPNS_17JSDOMGlobalObjectEPN3JSC9StructureEPKNS2_9ClassInfoE
-__ZN7WebCore17drawLayerContentsEP9CGContextPNS_15PlatformCALayerEN3WTF6VectorINS_9FloatRectELm5ENS4_15CrashOnOverflowEEE
+__ZN7WebCore17drawLayerContentsEP9CGContextPNS_15PlatformCALayerERN3WTF6VectorINS_9FloatRectELm5ENS4_15CrashOnOverflowEEE
 __ZN7WebCore17languageDidChangeEv
 __ZN7WebCore17openTemporaryFileERKN3WTF6StringERi
 __ZN7WebCore17setCookiesFromDOMERKNS_21NetworkStorageSessionERKNS_3URLES5_RKN3WTF6StringE

Modified: trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h (158981 => 158982)


--- trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h	2013-11-09 01:43:45 UTC (rev 158982)
@@ -200,6 +200,10 @@
 
     virtual PassRefPtr<PlatformCALayer> createCompatibleLayer(LayerType, PlatformCALayerClient*) const = 0;
 
+#if PLATFORM(MAC)
+    virtual void enumerateRectsBeingDrawn(CGContextRef, void (^block)(CGRect)) = 0;
+#endif
+
 protected:
     PlatformCALayer(LayerType layerType, PlatformCALayerClient* owner)
         : m_layerType(layerType)

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.h (158981 => 158982)


--- trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.h	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.h	2013-11-09 01:43:45 UTC (rev 158982)
@@ -141,6 +141,8 @@
 
     virtual PassRefPtr<PlatformCALayer> createCompatibleLayer(PlatformCALayer::LayerType, PlatformCALayerClient*) const OVERRIDE;
 
+    virtual void enumerateRectsBeingDrawn(CGContextRef, void (^block)(CGRect)) OVERRIDE;
+
 private:
     PlatformCALayerMac(LayerType, PlatformLayer*, PlatformCALayerClient* owner);
 

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm (158981 => 158982)


--- trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm	2013-11-09 01:43:45 UTC (rev 158982)
@@ -736,4 +736,9 @@
     return PlatformCALayerMac::create(layerType, client);
 }
 
+void PlatformCALayerMac::enumerateRectsBeingDrawn(CGContextRef context, void (^block)(CGRect))
+{
+    wkCALayerEnumerateRectsBeingDrawnWithBlock(m_layer.get(), context, block);
+}
+
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/TileController.mm (158981 => 158982)


--- trunk/Source/WebCore/platform/graphics/ca/mac/TileController.mm	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/TileController.mm	2013-11-09 01:43:45 UTC (rev 158982)
@@ -172,7 +172,8 @@
         context.translate(-layerOrigin.x(), -layerOrigin.y());
         context.scale(FloatSize(m_scale, m_scale));
 
-        drawLayerContents(context.platformContext(), m_tileCacheLayer);
+        RepaintRectList dirtyRects = collectRectsToPaint(context.platformContext(), platformCALayer);
+        drawLayerContents(context.platformContext(), m_tileCacheLayer, dirtyRects);
     }
 
     int repaintCount = platformCALayerIncrementRepaintCount(platformCALayer);

Modified: trunk/Source/WebCore/platform/graphics/mac/WebLayer.h (158981 => 158982)


--- trunk/Source/WebCore/platform/graphics/mac/WebLayer.h	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebCore/platform/graphics/mac/WebLayer.h	2013-11-09 01:43:45 UTC (rev 158982)
@@ -46,10 +46,12 @@
 class PlatformCALayer;
 class PlatformCALayerClient;
 
+typedef Vector<FloatRect, webLayerMaxRectsToPaint> RepaintRectList;
+
 // Functions allows us to share implementation across WebTiledLayer and WebLayer
-void drawLayerContents(CGContextRef, WebCore::PlatformCALayer*);
-void drawLayerContents(CGContextRef, WebCore::PlatformCALayer*, Vector<WebCore::FloatRect, webLayerMaxRectsToPaint> dirtyRects);
-void drawRepaintIndicator(CGContextRef, WebCore::PlatformCALayer*, int repaintCount, CGColorRef customBackgroundColor);
+RepaintRectList collectRectsToPaint(CGContextRef, PlatformCALayer*);
+void drawLayerContents(CGContextRef, PlatformCALayer*, RepaintRectList& dirtyRects);
+void drawRepaintIndicator(CGContextRef, PlatformCALayer*, int repaintCount, CGColorRef customBackgroundColor);
 }
 
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebCore/platform/graphics/mac/WebLayer.mm (158981 => 158982)


--- trunk/Source/WebCore/platform/graphics/mac/WebLayer.mm	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebCore/platform/graphics/mac/WebLayer.mm	2013-11-09 01:43:45 UTC (rev 158982)
@@ -33,8 +33,6 @@
 #import "GraphicsLayerCA.h"
 #import "PlatformCALayer.h"
 #import "ThemeMac.h"
-#import "WebCoreSystemInterface.h"
-#import <objc/runtime.h>
 #import <QuartzCore/QuartzCore.h>
 
 @interface CALayer(WebCoreCALayerPrivate)
@@ -45,32 +43,32 @@
 
 namespace WebCore {
 
-void drawLayerContents(CGContextRef context, WebCore::PlatformCALayer* platformCALayer)
+RepaintRectList collectRectsToPaint(CGContextRef context, PlatformCALayer* platformCALayer)
 {
     __block double totalRectArea = 0;
     __block unsigned rectCount = 0;
-    __block Vector<FloatRect, webLayerMaxRectsToPaint> dirtyRects;
+    __block RepaintRectList dirtyRects;
 
-    if (PlatformLayer *platformLayer = platformCALayer->platformLayer()) {
-        wkCALayerEnumerateRectsBeingDrawnWithBlock(platformLayer, context, ^(CGRect rect) {
-            if (++rectCount > webLayerMaxRectsToPaint)
-                return;
+    platformCALayer->enumerateRectsBeingDrawn(context, ^(CGRect rect) {
+        if (++rectCount > webLayerMaxRectsToPaint)
+            return;
 
-            totalRectArea += rect.size.width * rect.size.height;
-            dirtyRects.append(rect);
-        });
-    }
+        totalRectArea += rect.size.width * rect.size.height;
+        dirtyRects.append(rect);
+    });
 
     FloatRect clipBounds = CGContextGetClipBoundingBox(context);
     double clipArea = clipBounds.width() * clipBounds.height();
 
-    if (rectCount >= webLayerMaxRectsToPaint || totalRectArea >= clipArea * webLayerWastedSpaceThreshold)
+    if (rectCount >= webLayerMaxRectsToPaint || totalRectArea >= clipArea * webLayerWastedSpaceThreshold) {
         dirtyRects.clear();
+        dirtyRects.append(clipBounds);
+    }
 
-    drawLayerContents(context, platformCALayer, dirtyRects);
+    return dirtyRects;
 }
 
-void drawLayerContents(CGContextRef context, WebCore::PlatformCALayer* platformCALayer, Vector<FloatRect, webLayerMaxRectsToPaint> dirtyRects)
+void drawLayerContents(CGContextRef context, WebCore::PlatformCALayer* platformCALayer, RepaintRectList& dirtyRects)
 {
     WebCore::PlatformCALayerClient* layerContents = platformCALayer->owner();
     if (!layerContents)
@@ -78,11 +76,8 @@
 
     CGContextSaveGState(context);
 
-    if (layerContents->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp) {
-        FloatRect layerBounds = platformCALayer->bounds();
-        CGContextScaleCTM(context, 1, -1);
-        CGContextTranslateCTM(context, 0, -layerBounds.height());
-    }
+    // We never use CompositingCoordinatesBottomUp on Mac.
+    ASSERT(layerContents->platformCALayerContentsOrientation() == GraphicsLayer::CompositingCoordinatesTopDown);
 
     [NSGraphicsContext saveGraphicsState];
 
@@ -112,20 +107,11 @@
 #endif
     ThemeMac::setFocusRingClipRect(focusRingClipRect);
 
-    // If we have no dirty rects, repaint the whole layer.
-    if (dirtyRects.isEmpty()) {
-        // CGContextGetClipBoundingBox() gives us the bounds of the dirty region, so clipBounds
-        // encompasses all the dirty rects.
-        layerContents->platformCALayerPaintContents(platformCALayer, graphicsContext, enclosingIntRect(clipBounds));
-    } else {
-        for (unsigned i = 0; i < dirtyRects.size(); ++i) {
-            const FloatRect& currentRect = dirtyRects[i];
-            
-            GraphicsContextStateSaver stateSaver(graphicsContext);
-            graphicsContext.clip(currentRect);
-            
-            layerContents->platformCALayerPaintContents(platformCALayer, graphicsContext, enclosingIntRect(currentRect));
-        }
+    for (auto rect : dirtyRects) {
+        GraphicsContextStateSaver stateSaver(graphicsContext);
+        graphicsContext.clip(rect);
+
+        layerContents->platformCALayerPaintContents(platformCALayer, graphicsContext, enclosingIntRect(rect));
     }
 
     ThemeMac::setFocusRingClipRect(FloatRect());
@@ -189,8 +175,10 @@
 - (void)drawInContext:(CGContextRef)context
 {
     PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
-    if (layer)
-        drawLayerContents(context, layer);
+    if (layer) {
+        RepaintRectList rectsToPaint = collectRectsToPaint(context, layer);
+        drawLayerContents(context, layer, rectsToPaint);
+    }
 }
 
 @end // implementation WebLayer
@@ -223,17 +211,11 @@
 
     if (PlatformCALayerClient* layerOwner = platformLayer->owner()) {
         if (layerOwner->platformCALayerDrawsContent()) {
-            if (layerOwner->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
-                dirtyRect.origin.y = [self bounds].size.height - dirtyRect.origin.y - dirtyRect.size.height;
-
             [super setNeedsDisplayInRect:dirtyRect];
 
             if (layerOwner->platformCALayerShowRepaintCounter(platformLayer)) {
                 CGRect bounds = [self bounds];
                 CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 52, 27);
-                if (layerOwner->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
-                    indicatorRect.origin.y = [self bounds].size.height - indicatorRect.origin.y - indicatorRect.size.height;
-
                 [super setNeedsDisplayInRect:indicatorRect];
             }
         }

Modified: trunk/Source/WebKit2/ChangeLog (158981 => 158982)


--- trunk/Source/WebKit2/ChangeLog	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebKit2/ChangeLog	2013-11-09 01:43:45 UTC (rev 158982)
@@ -1,3 +1,41 @@
+2013-11-08  Tim Horton  <[email protected]>
+
+        Remote Layer Tree: RemoteLayerBackingStore partial repaint is broken for the tile cache
+        https://bugs.webkit.org/show_bug.cgi?id=123944
+
+        Reviewed by Simon Fraser.
+
+        Rework RemoteLayerBackingStore painting to fix some rounding issues
+        that would cause pixel cracks upon repaint, and to speed it up a bit.
+
+        * Shared/mac/RemoteLayerBackingStore.h:
+        Redefine RepaintRectList because we can't include WebLayer.h here yet.
+        Remove createBackingStore, which was never implemented.
+        Remove mapToContentCoordinates, because we don't need it on Mac.
+
+        (WebKit::RemoteLayerBackingStore::paintingRects): Added.
+
+        * Shared/mac/RemoteLayerBackingStore.mm:
+        (RemoteLayerBackingStore::setNeedsDisplay):
+        (RemoteLayerBackingStore::display):
+        Stop using mapToContentCoordinates.
+
+        (RemoteLayerBackingStore::drawInContext):
+        Use clipping instead of painting the image multiple times.
+        Never repaint more than the dirty region's bounds.
+        Don't waste time with all of the drawNativeImage code, just use CG.
+        Unindent the switch's cases.
+        Store the rects we're painting so that enumerateRectsBeingDrawn can get them.
+        Pixel-snap the rects we're painting.
+        Clip the context before going to paint.
+
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
+        (PlatformCALayerRemote::enumerateRectsBeingDrawn):
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+        Retrieve the rects currently being painted from our backing store, and
+        transform them (mostly) according to the CTM, to match the transformation
+        that will have occurred underneath wkCALayerEnumerateRectsBeingDrawnWithBlock.
+
 2013-11-08  Anders Carlsson  <[email protected]>
 
         Implement more KeyedEncoder functionality

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h (158981 => 158982)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h	2013-11-09 01:43:45 UTC (rev 158982)
@@ -32,6 +32,11 @@
 #include <WebCore/FloatRect.h>
 #include <WebCore/Region.h>
 
+// FIXME: Make PlatformCALayerRemote.cpp Objective-C so we can include WebLayer.h here and share the typedef.
+namespace WebCore {
+typedef Vector<WebCore::FloatRect, 5> RepaintRectList;
+}
+
 namespace WebKit {
 
 class PlatformCALayerRemote;
@@ -58,12 +63,11 @@
     void encode(CoreIPC::ArgumentEncoder&) const;
     static bool decode(CoreIPC::ArgumentDecoder&, RemoteLayerBackingStore&);
 
+    void enumerateRectsBeingDrawn(CGContextRef, void (^)(CGRect));
+
 private:
-    WebCore::IntRect mapToContentCoordinates(const WebCore::IntRect) const;
-
     bool hasFrontBuffer() { return m_acceleratesDrawing ? !!m_frontSurface : !!m_frontBuffer; }
 
-    std::unique_ptr<WebCore::GraphicsContext> createBackingStore();
     void drawInContext(WebCore::GraphicsContext&, CGImageRef frontImage);
 
     PlatformCALayerRemote* m_layer;
@@ -77,6 +81,8 @@
     RetainPtr<IOSurfaceRef> m_frontSurface;
 
     bool m_acceleratesDrawing;
+
+    WebCore::RepaintRectList m_paintingRects;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm (158981 => 158982)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm	2013-11-09 01:43:45 UTC (rev 158982)
@@ -110,18 +110,9 @@
     return true;
 }
 
-IntRect RemoteLayerBackingStore::mapToContentCoordinates(const IntRect rect) const
-{
-    IntRect flippedRect = rect;
-    if (m_layer->owner()->platformCALayerContentsOrientation() == GraphicsLayer::CompositingCoordinatesBottomUp)
-        flippedRect.setY(m_size.height() - rect.y() - rect.height());
-    return flippedRect;
-}
-
 void RemoteLayerBackingStore::setNeedsDisplay(const IntRect rect)
 {
-    IntRect flippedRect = mapToContentCoordinates(rect);
-    m_dirtyRegion.unite(flippedRect);
+    m_dirtyRegion.unite(rect);
 }
 
 void RemoteLayerBackingStore::setNeedsDisplay()
@@ -197,7 +188,7 @@
         m_dirtyRegion.unite(IntRect(IntPoint(), m_size));
 
     if (m_layer->owner()->platformCALayerShowRepaintCounter(m_layer)) {
-        IntRect indicatorRect = mapToContentCoordinates(IntRect(0, 0, 52, 27));
+        IntRect indicatorRect(0, 0, 52, 27);
         m_dirtyRegion.unite(indicatorRect);
     }
 
@@ -232,7 +223,7 @@
         }
     } else {
         RetainPtr<CGImageRef> frontImage = image();
-        m_frontBuffer = ShareableBitmap::createShareable(expandedIntSize(scaledSize), ShareableBitmap::SupportsAlpha);
+        m_frontBuffer = ShareableBitmap::createShareable(expandedScaledSize, ShareableBitmap::SupportsAlpha);
         std::unique_ptr<GraphicsContext> context = m_frontBuffer->createGraphicsContext();
         drawInContext(*context, frontImage.get());
     }
@@ -242,58 +233,93 @@
 
 void RemoteLayerBackingStore::drawInContext(GraphicsContext& context, CGImageRef frontImage)
 {
-    Vector<IntRect> dirtyRects = m_dirtyRegion.rects();
+    IntRect layerBounds(IntPoint(), m_size);
+    IntRect scaledLayerBounds(IntPoint(), expandedIntSize(m_size * m_scale));
 
+    CGContextRef cgContext = context.platformContext();
+
     // If we have less than webLayerMaxRectsToPaint rects to paint and they cover less
-    // than webLayerWastedSpaceThreshold of the area, we'll do a partial repaint.
+    // than webLayerWastedSpaceThreshold of the total dirty area, we'll repaint each rect separately.
+    // Otherwise, repaint the entire bounding box of the dirty region.
+    IntRect dirtyBounds = m_dirtyRegion.bounds();
+    Vector<IntRect> dirtyRects = m_dirtyRegion.rects();
+    if (dirtyRects.size() > webLayerMaxRectsToPaint && m_dirtyRegion.totalArea() > webLayerWastedSpaceThreshold * dirtyBounds.width() * dirtyBounds.height()) {
+        dirtyRects.clear();
+        dirtyRects.append(dirtyBounds);
+    }
 
-    Vector<FloatRect, webLayerMaxRectsToPaint> rectsToPaint;
-    if (dirtyRects.size() <= webLayerMaxRectsToPaint && m_dirtyRegion.totalArea() <= webLayerWastedSpaceThreshold * m_size.width() * m_size.height()) {
-        // Copy over the parts of the front buffer that we're not going to repaint.
-        if (frontImage) {
-            Region cleanRegion(IntRect(IntPoint(), m_size));
-            cleanRegion.subtract(m_dirtyRegion);
+    for (const auto& rect : dirtyRects) {
+        FloatRect scaledRect(rect);
+        scaledRect.scale(m_scale, m_scale);
+        scaledRect = enclosingIntRect(scaledRect);
+        scaledRect.scale(1 / m_scale, 1 / m_scale);
+        m_paintingRects.append(scaledRect);
+    }
 
-            for (const auto& rect : cleanRegion.rects()) {
-                FloatRect scaledRect = rect;
-                scaledRect.scale(m_scale);
-                FloatSize imageSize(CGImageGetWidth(frontImage), CGImageGetHeight(frontImage));
-                context.drawNativeImage(frontImage, imageSize, ColorSpaceDeviceRGB, scaledRect, scaledRect);
-            }
-        }
+    CGRect cgPaintingRects[webLayerMaxRectsToPaint];
+    for (size_t i = 0, dirtyRectCount = m_paintingRects.size(); i < dirtyRectCount; ++i) {
+        FloatRect scaledPaintingRect = m_paintingRects[i];
+        scaledPaintingRect.scale(m_scale);
+        cgPaintingRects[i] = enclosingIntRect(scaledPaintingRect);
+    }
 
-        for (const auto& rect : dirtyRects)
-            rectsToPaint.append(rect);
+    if (frontImage) {
+        CGContextSaveGState(cgContext);
+        CGContextSetBlendMode(cgContext, kCGBlendModeCopy);
+
+        CGContextAddRect(cgContext, CGRectInfinite);
+        CGContextAddRects(cgContext, cgPaintingRects, m_paintingRects.size());
+        CGContextEOClip(cgContext);
+
+        CGContextTranslateCTM(cgContext, 0, scaledLayerBounds.height());
+        CGContextScaleCTM(cgContext, 1, -1);
+        CGContextDrawImage(cgContext, scaledLayerBounds, frontImage);
+        CGContextRestoreGState(cgContext);
     }
 
+    CGContextClipToRects(cgContext, cgPaintingRects, m_paintingRects.size());
+
     context.scale(FloatSize(m_scale, m_scale));
 
     switch (m_layer->layerType()) {
-        case PlatformCALayer::LayerTypeSimpleLayer:
-        case PlatformCALayer::LayerTypeTiledBackingTileLayer:
-            if (rectsToPaint.isEmpty())
-                rectsToPaint.append(IntRect(IntPoint(), m_size));
-            for (const auto& rect : rectsToPaint)
-                m_layer->owner()->platformCALayerPaintContents(m_layer, context, enclosingIntRect(rect));
-            break;
-        case PlatformCALayer::LayerTypeWebLayer:
-            drawLayerContents(context.platformContext(), m_layer, rectsToPaint);
-            break;
-        case PlatformCALayer::LayerTypeLayer:
-        case PlatformCALayer::LayerTypeTransformLayer:
-        case PlatformCALayer::LayerTypeWebTiledLayer:
-        case PlatformCALayer::LayerTypeTiledBackingLayer:
-        case PlatformCALayer::LayerTypePageTiledBackingLayer:
-        case PlatformCALayer::LayerTypeRootLayer:
-        case PlatformCALayer::LayerTypeAVPlayerLayer:
-        case PlatformCALayer::LayerTypeCustom:
-            ASSERT_NOT_REACHED();
-            break;
+    case PlatformCALayer::LayerTypeSimpleLayer:
+    case PlatformCALayer::LayerTypeTiledBackingTileLayer:
+        m_layer->owner()->platformCALayerPaintContents(m_layer, context, dirtyBounds);
+        break;
+    case PlatformCALayer::LayerTypeWebLayer:
+        drawLayerContents(cgContext, m_layer, m_paintingRects);
+        break;
+    case PlatformCALayer::LayerTypeLayer:
+    case PlatformCALayer::LayerTypeTransformLayer:
+    case PlatformCALayer::LayerTypeWebTiledLayer:
+    case PlatformCALayer::LayerTypeTiledBackingLayer:
+    case PlatformCALayer::LayerTypePageTiledBackingLayer:
+    case PlatformCALayer::LayerTypeRootLayer:
+    case PlatformCALayer::LayerTypeAVPlayerLayer:
+    case PlatformCALayer::LayerTypeCustom:
+        ASSERT_NOT_REACHED();
+        break;
     };
 
     m_dirtyRegion = Region();
+    m_paintingRects.clear();
 
     CGContextFlush(context.platformContext());
 }
 
+void RemoteLayerBackingStore::enumerateRectsBeingDrawn(CGContextRef context, void (^block)(CGRect))
+{
+    CGAffineTransform inverseTransform = CGAffineTransformInvert(CGContextGetCTM(context));
+
+    // We don't want to un-apply the flipping or contentsScale,
+    // because they're not applied to repaint rects.
+    inverseTransform = CGAffineTransformScale(inverseTransform, m_scale, -m_scale);
+    inverseTransform = CGAffineTransformTranslate(inverseTransform, 0, -m_size.height());
+
+    for (auto rect : m_paintingRects) {
+        CGRect rectToDraw = CGRectApplyAffineTransform(rect, inverseTransform);
+        block(rectToDraw);
+    }
+}
+
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp (158981 => 158982)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp	2013-11-09 01:43:45 UTC (rev 158982)
@@ -502,6 +502,11 @@
     return PlatformCALayerRemote::create(layerType, client, m_context);
 }
 
+void PlatformCALayerRemote::enumerateRectsBeingDrawn(CGContextRef context, void (^block)(CGRect))
+{
+    m_properties.backingStore.enumerateRectsBeingDrawn(context, block);
+}
+
 uint32_t PlatformCALayerRemote::hostingContextID()
 {
     ASSERT_NOT_REACHED();

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h (158981 => 158982)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h	2013-11-09 01:29:30 UTC (rev 158981)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h	2013-11-09 01:43:45 UTC (rev 158982)
@@ -146,6 +146,8 @@
 
     virtual PassRefPtr<PlatformCALayer> createCompatibleLayer(WebCore::PlatformCALayer::LayerType, WebCore::PlatformCALayerClient*) const OVERRIDE;
 
+    virtual void enumerateRectsBeingDrawn(CGContextRef, void (^block)(CGRect)) OVERRIDE;
+
     virtual uint32_t hostingContextID();
 
 protected:
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to