Title: [242995] trunk/Source
Revision
242995
Author
[email protected]
Date
2019-03-15 08:43:20 -0700 (Fri, 15 Mar 2019)

Log Message

Optimize Region for single rectangle case
https://bugs.webkit.org/show_bug.cgi?id=195743

Reviewed by Simon Fraser.

Source/WebCore:

Instrumentation shows vast majority of Region objects consist of a single rectangle. However it always allocates
the large Shape data structure. This makes it unsuitable to use as a member in any popular objects.

This patch optimizes the single rectangle case by using only the bounds rectangle to describe it.
Shape is allocated on demand. This makes it safe to use Region as a data member where a rectangle is the common case.

The patch also modernizes Region encoding/decoding support.

* platform/graphics/Region.cpp:
(WebCore::Region::Region):
(WebCore::Region::~Region):
(WebCore::Region::operator=):
(WebCore::Region::rects const):
(WebCore::Region::contains const):
(WebCore::Region::intersects const):
(WebCore::Region::Shape::Shape):
(WebCore::Region::Shape::appendSpan):
(WebCore::Region::dump const):
(WebCore::Region::intersect):
(WebCore::Region::unite):
(WebCore::Region::subtract):
(WebCore::Region::translate):
(WebCore::Region::setShape):
(WebCore::Region::Shape::isValid const): Deleted.
(WebCore::Region::Shape::swap): Deleted.
(WebCore::Region::updateBoundsFromShape): Deleted.

Remove some now unused function.

* platform/graphics/Region.h:
(WebCore::Region::isRect const):
(WebCore::Region::gridSize const):
(WebCore::Region::copyShape const):
(WebCore::operator==):
(WebCore::Region::Span::encode const):
(WebCore::Region::Span::decode):
(WebCore::Region::Shape::encode const):
(WebCore::Region::Shape::decode):
(WebCore::Region::encode const):
(WebCore::Region::decode):

This is now part of type.

(WebCore::Region::isValid const): Deleted.
(WebCore::Region::Span::Span): Deleted.
(WebCore::Region::shapeSegments const): Deleted.
(WebCore::Region::shapeSpans const): Deleted.
(WebCore::Region::setShapeSegments): Deleted.
(WebCore::Region::setShapeSpans): Deleted.
(WebCore::Region::Shape::segments const): Deleted.
(WebCore::Region::Shape::spans const): Deleted.
(WebCore::Region::Shape::setSegments): Deleted.
(WebCore::Region::Shape::setSpans): Deleted.

No need to expose these for encoding anymore.

Source/WebKit:

* Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::LayerProperties::decode):
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<EventTrackingRegions>::decode):
(IPC::ArgumentCoder<Region::Span>::encode): Deleted.
(IPC::ArgumentCoder<Region::Span>::decode): Deleted.
(IPC::ArgumentCoder<Region>::encode): Deleted.
(IPC::ArgumentCoder<Region>::decode): Deleted.
* Shared/WebCoreArgumentCoders.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (242994 => 242995)


--- trunk/Source/WebCore/ChangeLog	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebCore/ChangeLog	2019-03-15 15:43:20 UTC (rev 242995)
@@ -1,3 +1,66 @@
+2019-03-15  Antti Koivisto  <[email protected]>
+
+        Optimize Region for single rectangle case
+        https://bugs.webkit.org/show_bug.cgi?id=195743
+
+        Reviewed by Simon Fraser.
+
+        Instrumentation shows vast majority of Region objects consist of a single rectangle. However it always allocates
+        the large Shape data structure. This makes it unsuitable to use as a member in any popular objects.
+
+        This patch optimizes the single rectangle case by using only the bounds rectangle to describe it.
+        Shape is allocated on demand. This makes it safe to use Region as a data member where a rectangle is the common case.
+
+        The patch also modernizes Region encoding/decoding support.
+
+        * platform/graphics/Region.cpp:
+        (WebCore::Region::Region):
+        (WebCore::Region::~Region):
+        (WebCore::Region::operator=):
+        (WebCore::Region::rects const):
+        (WebCore::Region::contains const):
+        (WebCore::Region::intersects const):
+        (WebCore::Region::Shape::Shape):
+        (WebCore::Region::Shape::appendSpan):
+        (WebCore::Region::dump const):
+        (WebCore::Region::intersect):
+        (WebCore::Region::unite):
+        (WebCore::Region::subtract):
+        (WebCore::Region::translate):
+        (WebCore::Region::setShape):
+        (WebCore::Region::Shape::isValid const): Deleted.
+        (WebCore::Region::Shape::swap): Deleted.
+        (WebCore::Region::updateBoundsFromShape): Deleted.
+
+        Remove some now unused function.
+
+        * platform/graphics/Region.h:
+        (WebCore::Region::isRect const):
+        (WebCore::Region::gridSize const):
+        (WebCore::Region::copyShape const):
+        (WebCore::operator==):
+        (WebCore::Region::Span::encode const):
+        (WebCore::Region::Span::decode):
+        (WebCore::Region::Shape::encode const):
+        (WebCore::Region::Shape::decode):
+        (WebCore::Region::encode const):
+        (WebCore::Region::decode):
+
+        This is now part of type.
+
+        (WebCore::Region::isValid const): Deleted.
+        (WebCore::Region::Span::Span): Deleted.
+        (WebCore::Region::shapeSegments const): Deleted.
+        (WebCore::Region::shapeSpans const): Deleted.
+        (WebCore::Region::setShapeSegments): Deleted.
+        (WebCore::Region::setShapeSpans): Deleted.
+        (WebCore::Region::Shape::segments const): Deleted.
+        (WebCore::Region::Shape::spans const): Deleted.
+        (WebCore::Region::Shape::setSegments): Deleted.
+        (WebCore::Region::Shape::setSpans): Deleted.
+
+        No need to expose these for encoding anymore.
+
 2019-03-15  Devin Rousso  <[email protected]>
 
         Web Inspector: provide a way to capture a screenshot of a node from within the page

Modified: trunk/Source/WebCore/platform/graphics/Region.cpp (242994 => 242995)


--- trunk/Source/WebCore/platform/graphics/Region.cpp	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebCore/platform/graphics/Region.cpp	2019-03-15 15:43:20 UTC (rev 242995)
@@ -42,19 +42,54 @@
 
 Region::Region(const IntRect& rect)
     : m_bounds(rect)
-    , m_shape(rect)
 {
 }
 
-Vector<IntRect> Region::rects() const
+Region::Region(const Region& other)
+    : m_bounds(other.m_bounds)
+    , m_shape(other.copyShape())
 {
-    Vector<IntRect> rects;
+}
 
-    for (Shape::SpanIterator span = m_shape.spans_begin(), end = m_shape.spans_end(); span != end && span + 1 != end; ++span) {
+Region::Region(Region&& other)
+    : m_bounds(WTFMove(other.m_bounds))
+    , m_shape(WTFMove(other.m_shape))
+{
+}
+
+Region::~Region()
+{
+}
+
+Region& Region::operator=(const Region& other)
+{
+    m_bounds = other.m_bounds;
+    m_shape = other.copyShape();
+    return *this;
+}
+
+Region& Region::operator=(Region&& other)
+{
+    m_bounds = WTFMove(other.m_bounds);
+    m_shape = WTFMove(other.m_shape);
+    return *this;
+}
+
+Vector<IntRect, 1> Region::rects() const
+{
+    Vector<IntRect, 1> rects;
+
+    if (!m_shape) {
+        if (!m_bounds.isEmpty())
+            rects.uncheckedAppend(m_bounds);
+        return rects;
+    }
+
+    for (Shape::SpanIterator span = m_shape->spans_begin(), end = m_shape->spans_end(); span != end && span + 1 != end; ++span) {
         int y = span->y;
         int height = (span + 1)->y - y;
 
-        for (Shape::SegmentIterator segment = m_shape.segments_begin(span), end = m_shape.segments_end(span); segment != end && segment + 1 != end; segment += 2) {
+        for (Shape::SegmentIterator segment = m_shape->segments_begin(span), end = m_shape->segments_end(span); segment != end && segment + 1 != end; segment += 2) {
             int x = *segment;
             int width = *(segment + 1) - x;
 
@@ -70,7 +105,10 @@
     if (!m_bounds.contains(region.m_bounds))
         return false;
 
-    return Shape::compareShapes<Shape::CompareContainsOperation>(m_shape, region.m_shape);
+    if (!m_shape)
+        return true;
+
+    return Shape::compareShapes<Shape::CompareContainsOperation>(*m_shape, region.m_shape ? *region.m_shape : Shape(region.m_bounds));
 }
 
 bool Region::contains(const IntPoint& point) const
@@ -78,7 +116,10 @@
     if (!m_bounds.contains(point))
         return false;
 
-    for (Shape::SpanIterator span = m_shape.spans_begin(), end = m_shape.spans_end(); span != end && span + 1 != end; ++span) {
+    if (!m_shape)
+        return true;
+
+    for (Shape::SpanIterator span = m_shape->spans_begin(), end = m_shape->spans_end(); span != end && span + 1 != end; ++span) {
         int y = span->y;
         int maxY = (span + 1)->y;
 
@@ -87,7 +128,7 @@
         if (maxY <= point.y())
             continue;
 
-        for (Shape::SegmentIterator segment = m_shape.segments_begin(span), end = m_shape.segments_end(span); segment != end && segment + 1 != end; segment += 2) {
+        for (Shape::SegmentIterator segment = m_shape->segments_begin(span), end = m_shape->segments_end(span); segment != end && segment + 1 != end; segment += 2) {
             int x = *segment;
             int maxX = *(segment + 1);
 
@@ -106,19 +147,18 @@
     if (!m_bounds.intersects(region.m_bounds))
         return false;
 
-    return Shape::compareShapes<Shape::CompareIntersectsOperation>(m_shape, region.m_shape);
+    if (!m_shape && !region.m_shape)
+        return true;
+
+    return Shape::compareShapes<Shape::CompareIntersectsOperation>(m_shape ? *m_shape : m_bounds, region.m_shape ? *region.m_shape : region.m_bounds);
 }
 
-unsigned Region::totalArea() const
+uint64_t Region::totalArea() const
 {
-    Vector<IntRect> rects = this->rects();
-    size_t size = rects.size();
-    unsigned totalArea = 0;
+    uint64_t totalArea = 0;
 
-    for (size_t i = 0; i < size; ++i) {
-        IntRect rect = rects[i];
+    for (auto& rect : rects())
         totalArea += (rect.width() * rect.height());
-    }
 
     return totalArea;
 }
@@ -221,21 +261,15 @@
     inline static bool aOverlapsB(bool& result) { result = true; return true; }
 };
 
-Region::Shape::Shape()
-{
-}
-
 Region::Shape::Shape(const IntRect& rect)
+    : m_segments({ rect.x(), rect.maxX() })
+    , m_spans({ { rect.y(), 0 }, { rect.maxY(), 2 } })
 {
-    appendSpan(rect.y());
-    appendSegment(rect.x());
-    appendSegment(rect.maxX());
-    appendSpan(rect.maxY());
 }
 
 void Region::Shape::appendSpan(int y)
 {
-    m_spans.append(Span(y, m_segments.size()));
+    m_spans.append({ y, m_segments.size() });
 }
 
 bool Region::Shape::canCoalesce(SegmentIterator begin, SegmentIterator end)
@@ -331,27 +365,6 @@
 }
 #endif
 
-bool Region::Shape::isValid() const
-{
-    for (auto span = spans_begin(), end = spans_end(); span != end && span + 1 != end; ++span) {
-        int y = span->y;
-        int height = (span + 1)->y - y;
-        
-        if (height < 0)
-            return false;
-
-        for (auto segment = segments_begin(span), end = segments_end(span); segment != end && segment + 1 != end; segment += 2) {
-            int x = *segment;
-            int width = *(segment + 1) - x;
-            
-            if (width < 0)
-                return false;
-        }
-    }
-
-    return true;
-}
-
 IntRect Region::Shape::bounds() const
 {
     if (isEmpty())
@@ -397,12 +410,6 @@
         m_spans[i].y += offset.height();
 }
 
-void Region::Shape::swap(Shape& other)
-{
-    m_segments.swap(other.m_segments);
-    m_spans.swap(other.m_spans);
-}
-
 enum {
     Shape1,
     Shape2,
@@ -567,29 +574,26 @@
 {
     printf("Bounds: (%d, %d, %d, %d)\n",
            m_bounds.x(), m_bounds.y(), m_bounds.width(), m_bounds.height());
-    m_shape.dump();
+    if (m_shape)
+        m_shape->dump();
 }
 #endif
 
-void Region::updateBoundsFromShape()
-{
-    m_bounds = m_shape.bounds();
-}
-
 void Region::intersect(const Region& region)
 {
     if (m_bounds.isEmpty())
         return;
     if (!m_bounds.intersects(region.m_bounds)) {
-        m_shape = Shape();
+        m_shape = nullptr;
         m_bounds = IntRect();
         return;
     }
+    if (!m_shape && !region.m_shape) {
+        m_bounds = intersection(m_bounds, region.m_bounds);
+        return;
+    }
 
-    Shape intersectedShape = Shape::intersectShapes(m_shape, region.m_shape);
-
-    m_shape.swap(intersectedShape);
-    m_bounds = m_shape.bounds();
+    setShape(Shape::intersectShapes(m_shape ? *m_shape : m_bounds, region.m_shape ? *region.m_shape : region.m_bounds));
 }
 
 void Region::unite(const Region& region)
@@ -596,26 +600,25 @@
 {
     if (region.isEmpty())
         return;
-    if (isRect() && m_bounds.contains(region.m_bounds))
+    if (isEmpty()) {
+        m_bounds = region.m_bounds;
+        m_shape = region.copyShape();
         return;
+    }
     if (region.isRect() && region.m_bounds.contains(m_bounds)) {
-        m_shape = region.m_shape;
         m_bounds = region.m_bounds;
+        m_shape = nullptr;
         return;
     }
-    // FIXME: We may want another way to construct a Region without doing this test when we expect it to be false.
-    if (!isRect() && contains(region))
+    if (contains(region))
         return;
 
-    Shape unitedShape = Shape::unionShapes(m_shape, region.m_shape);
-
-    m_shape.swap(unitedShape);
-    m_bounds.unite(region.m_bounds);
+    setShape(Shape::unionShapes(m_shape ? *m_shape : m_bounds, region.m_shape ? *region.m_shape : region.m_bounds));
 }
 
 void Region::subtract(const Region& region)
 {
-    if (m_bounds.isEmpty())
+    if (isEmpty())
         return;
     if (region.isEmpty())
         return;
@@ -622,16 +625,30 @@
     if (!m_bounds.intersects(region.m_bounds))
         return;
 
-    Shape subtractedShape = Shape::subtractShapes(m_shape, region.m_shape);
-
-    m_shape.swap(subtractedShape);
-    m_bounds = m_shape.bounds();
+    setShape(Shape::subtractShapes(m_shape ? *m_shape : m_bounds, region.m_shape ? *region.m_shape : region.m_bounds));
 }
 
 void Region::translate(const IntSize& offset)
 {
     m_bounds.move(offset);
-    m_shape.translate(offset);
+    if (m_shape)
+        m_shape->translate(offset);
 }
 
+void Region::setShape(Shape&& shape)
+{
+    m_bounds = shape.bounds();
+
+    if (shape.isRect()) {
+        m_shape = nullptr;
+        return;
+    }
+
+    if (!m_shape)
+        m_shape = std::make_unique<Shape>(WTFMove(shape));
+    else
+        *m_shape = WTFMove(shape);
+}
+
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/Region.h (242994 => 242995)


--- trunk/Source/WebCore/platform/graphics/Region.h	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebCore/platform/graphics/Region.h	2019-03-15 15:43:20 UTC (rev 242995)
@@ -27,6 +27,8 @@
 #define Region_h
 
 #include "IntRect.h"
+#include <wtf/Optional.h>
+#include <wtf/PointerComparison.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
@@ -38,11 +40,19 @@
     WEBCORE_EXPORT Region();
     WEBCORE_EXPORT Region(const IntRect&);
 
+    WEBCORE_EXPORT Region(const Region&);
+    WEBCORE_EXPORT Region(Region&&);
+
+    WEBCORE_EXPORT ~Region();
+
+    WEBCORE_EXPORT Region& operator=(const Region&);
+    WEBCORE_EXPORT Region& operator=(Region&&);
+
     IntRect bounds() const { return m_bounds; }
     bool isEmpty() const { return m_bounds.isEmpty(); }
-    bool isRect() const { return m_shape.isRect(); }
+    bool isRect() const { return !m_shape; }
 
-    WEBCORE_EXPORT Vector<IntRect> rects() const;
+    WEBCORE_EXPORT Vector<IntRect, 1> rects() const;
 
     WEBCORE_EXPORT void unite(const Region&);
     WEBCORE_EXPORT void intersect(const Region&);
@@ -58,48 +68,31 @@
     // Returns true if the query region intersects any part of this region.
     WEBCORE_EXPORT bool intersects(const Region&) const;
 
-    WEBCORE_EXPORT unsigned totalArea() const;
+    WEBCORE_EXPORT uint64_t totalArea() const;
 
-    unsigned gridSize() const { return m_shape.gridSize(); }
+    unsigned gridSize() const { return m_shape ? m_shape->gridSize() : 0; }
 
 #ifndef NDEBUG
     void dump() const;
 #endif
 
-    bool isValid() const { return m_shape.isValid(); }
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static Optional<Region> decode(Decoder&);
+    // FIXME: Remove legacy decode.
+    template<class Decoder> static bool decode(Decoder&, Region&);
 
-    // This is internal to Region, but exposed just for encoding.
-    // FIXME: figure out a better way to encode WebCore classes.
+private:
     struct Span {
-        Span()
-            : y(0)
-            , segmentIndex(0)
-        {
-        }
+        int y { 0 };
+        size_t segmentIndex { 0 };
 
-        Span(int y, size_t segmentIndex)
-            : y(y)
-            , segmentIndex(segmentIndex)
-        {
-        }
-
-        int y;
-        size_t segmentIndex;
+        template<class Encoder> void encode(Encoder&) const;
+        template<class Decoder> static Optional<Span> decode(Decoder&);
     };
 
-    // For encoding/decoding only.
-    const Vector<int, 32>& shapeSegments() const { return m_shape.segments(); }
-    const Vector<Span, 16>& shapeSpans() const { return m_shape.spans(); }
-
-    void setShapeSegments(const Vector<int>& segments) { m_shape.setSegments(segments); }
-    void setShapeSpans(const Vector<Span>& spans) { m_shape.setSpans(spans); }
-    WEBCORE_EXPORT void updateBoundsFromShape();
-
-private:
-
     class Shape {
     public:
-        Shape();
+        Shape() = default;
         Shape(const IntRect&);
 
         IntRect bounds() const;
@@ -120,7 +113,6 @@
         static Shape subtractShapes(const Shape& shape1, const Shape& shape2);
 
         WEBCORE_EXPORT void translate(const IntSize&);
-        void swap(Shape&);
 
         struct CompareContainsOperation;
         struct CompareIntersectsOperation;
@@ -127,16 +119,10 @@
 
         template<typename CompareOperation>
         static bool compareShapes(const Shape& shape1, const Shape& shape2);
-        
-        WEBCORE_EXPORT bool isValid() const;
 
-        // For encoding/decoding only.
-        const Vector<int, 32>& segments() const { return m_segments; }
-        const Vector<Span, 16>& spans() const { return m_spans; }
+        template<class Encoder> void encode(Encoder&) const;
+        template<class Decoder> static Optional<Shape> decode(Decoder&);
 
-        void setSegments(const Vector<int>& segments) { m_segments = segments; }
-        void setSpans(const Vector<Span>& spans) { m_spans = spans; }
-
 #ifndef NDEBUG
         void dump() const;
 #endif
@@ -162,12 +148,16 @@
         friend bool operator==(const Shape&, const Shape&);
     };
 
+    std::unique_ptr<Shape> copyShape() const { return m_shape ? std::make_unique<Shape>(*m_shape) : nullptr; }
+    void setShape(Shape&&);
+
     IntRect m_bounds;
-    Shape m_shape;
+    std::unique_ptr<Shape> m_shape;
 
     friend bool operator==(const Region&, const Region&);
     friend bool operator==(const Shape&, const Shape&);
     friend bool operator==(const Span&, const Span&);
+    friend bool operator!=(const Span&, const Span&);
 };
 
 static inline Region intersect(const Region& a, const Region& b)
@@ -177,7 +167,7 @@
 
     return result;
 }
-    
+
 static inline Region subtract(const Region& a, const Region& b)
 {
     Region result(a);
@@ -196,7 +186,7 @@
 
 inline bool operator==(const Region& a, const Region& b)
 {
-    return a.m_bounds == b.m_bounds && a.m_shape == b.m_shape;
+    return a.m_bounds == b.m_bounds && arePointingToEqualData(a.m_shape, b.m_shape);
 }
 inline bool operator!=(const Region& a, const Region& b)
 {
@@ -212,11 +202,108 @@
 {
     return a.y == b.y && a.segmentIndex == b.segmentIndex;
 }
+
 inline bool operator!=(const Region::Span& a, const Region::Span& b)
 {
     return !(a == b);
 }
 
+template<class Encoder>
+void Region::Span::encode(Encoder& encoder) const
+{
+    encoder << y << static_cast<uint64_t>(segmentIndex);
+}
+
+template<class Decoder>
+Optional<Region::Span> Region::Span::decode(Decoder& decoder)
+{
+    Optional<int> y;
+    decoder >> y;
+    if (!y)
+        return { };
+
+    Optional<uint64_t> segmentIndex;
+    decoder >> segmentIndex;
+    if (!segmentIndex)
+        return { };
+
+    return { { *y, *segmentIndex } };
+}
+
+template<class Encoder>
+void Region::Shape::encode(Encoder& encoder) const
+{
+    encoder << m_segments;
+    encoder << m_spans;
+}
+
+template<class Decoder>
+Optional<Region::Shape> Region::Shape::decode(Decoder& decoder)
+{
+    Optional<Vector<int>> segments;
+    decoder >> segments;
+    if (!segments)
+        return WTF::nullopt;
+
+    Optional<Vector<Region::Span>> spans;
+    decoder >> spans;
+    if (!spans)
+        return WTF::nullopt;
+
+    Shape shape;
+    shape.m_segments = WTFMove(*segments);
+    shape.m_spans = WTFMove(*spans);
+
+    return { shape };
+}
+
+template<class Encoder>
+void Region::encode(Encoder& encoder) const
+{
+    encoder << m_bounds;
+    bool hasShape = !!m_shape;
+    encoder << hasShape;
+    if (hasShape)
+        encoder << *m_shape;
+}
+
+template<class Decoder>
+Optional<Region> Region::decode(Decoder& decoder)
+{
+    Optional<IntRect> bounds;
+    decoder >> bounds;
+    if (!bounds)
+        return WTF::nullopt;
+
+    Optional<bool> hasShape;
+    decoder >> hasShape;
+    if (!hasShape)
+        return WTF::nullopt;
+
+    Region region = { *bounds };
+
+    if (*hasShape) {
+        Optional<Shape> shape;
+        decoder >> shape;
+        if (!shape)
+            return WTF::nullopt;
+        region.m_shape = std::make_unique<Shape>(WTFMove(*shape));
+    }
+
+    return { region };
+}
+
+template<class Decoder>
+bool Region::decode(Decoder& decoder, Region& region)
+{
+    Optional<Region> decodedRegion;
+    decoder >> decodedRegion;
+    if (!decodedRegion)
+        return false;
+    region = WTFMove(*decodedRegion);
+    return true;
+}
+
 } // namespace WebCore
 
 #endif // Region_h

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp (242994 => 242995)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp	2019-03-15 15:43:20 UTC (rev 242995)
@@ -335,7 +335,7 @@
     }
 
     nonOverlapRegion.translate(options.offset);
-    Vector<IntRect> rects = nonOverlapRegion.rects();
+    auto rects = nonOverlapRegion.rects();
 
     for (auto& rect : rects) {
         if (!rect.intersects(options.textureMapper.clipBounds()))

Modified: trunk/Source/WebKit/ChangeLog (242994 => 242995)


--- trunk/Source/WebKit/ChangeLog	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebKit/ChangeLog	2019-03-15 15:43:20 UTC (rev 242995)
@@ -1,3 +1,20 @@
+2019-03-15  Antti Koivisto  <[email protected]>
+
+        Optimize Region for single rectangle case
+        https://bugs.webkit.org/show_bug.cgi?id=195743
+
+        Reviewed by Simon Fraser.
+
+        * Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::decode):
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<EventTrackingRegions>::decode):
+        (IPC::ArgumentCoder<Region::Span>::encode): Deleted.
+        (IPC::ArgumentCoder<Region::Span>::decode): Deleted.
+        (IPC::ArgumentCoder<Region>::encode): Deleted.
+        (IPC::ArgumentCoder<Region>::decode): Deleted.
+        * Shared/WebCoreArgumentCoders.h:
+
 2019-03-14  Per Arne Vollan  <[email protected]>
 
         [iOS] WebKit crashes when opening pages documents

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm (242994 => 242995)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm	2019-03-15 15:43:20 UTC (rev 242995)
@@ -298,7 +298,7 @@
     // Otherwise, repaint the entire bounding box of the dirty region.
     WebCore::IntRect dirtyBounds = m_dirtyRegion.bounds();
 
-    Vector<WebCore::IntRect> dirtyRects = m_dirtyRegion.rects();
+    auto dirtyRects = m_dirtyRegion.rects();
     if (dirtyRects.size() > WebCore::PlatformCALayer::webLayerMaxRectsToPaint || m_dirtyRegion.totalArea() > WebCore::PlatformCALayer::webLayerWastedSpaceThreshold * dirtyBounds.width() * dirtyBounds.height()) {
         dirtyRects.clear();
         dirtyRects.append(dirtyBounds);

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm (242994 => 242995)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm	2019-03-15 15:43:20 UTC (rev 242995)
@@ -515,10 +515,11 @@
         if (!decoder.decode(hasEventRegion))
             return false;
         if (hasEventRegion) {
-            auto eventRegion = std::make_unique<WebCore::Region>();
-            if (!decoder.decode(*eventRegion))
+            Optional<WebCore::Region> eventRegion;
+            decoder >> eventRegion;
+            if (!eventRegion)
                 return false;
-            result.eventRegion = WTFMove(eventRegion);
+            result.eventRegion = std::make_unique<Region>(WTFMove(*eventRegion));
         }
     }
 

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (242994 => 242995)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2019-03-15 15:43:20 UTC (rev 242995)
@@ -367,8 +367,9 @@
 
 bool ArgumentCoder<EventTrackingRegions>::decode(Decoder& decoder, EventTrackingRegions& eventTrackingRegions)
 {
-    Region asynchronousDispatchRegion;
-    if (!decoder.decode(asynchronousDispatchRegion))
+    Optional<Region> asynchronousDispatchRegion;
+    decoder >> asynchronousDispatchRegion;
+    if (!asynchronousDispatchRegion)
         return false;
     HashMap<String, Region> eventSpecificSynchronousDispatchRegions;
     if (!decoder.decode(eventSpecificSynchronousDispatchRegions))
@@ -378,7 +379,7 @@
     if (!decoder.decode(touchActionData))
         return false;
 #endif
-    eventTrackingRegions.asynchronousDispatchRegion = WTFMove(asynchronousDispatchRegion);
+    eventTrackingRegions.asynchronousDispatchRegion = WTFMove(*asynchronousDispatchRegion);
     eventTrackingRegions.eventSpecificSynchronousDispatchRegions = WTFMove(eventSpecificSynchronousDispatchRegions);
 #if ENABLE(POINTER_EVENTS)
     eventTrackingRegions.touchActionData = WTFMove(touchActionData);
@@ -902,66 +903,6 @@
     return {{ WTFMove(*string), WTFMove(*time) }};
 }
 
-template<> struct ArgumentCoder<Region::Span> {
-    static void encode(Encoder&, const Region::Span&);
-    static Optional<Region::Span> decode(Decoder&);
-};
-
-void ArgumentCoder<Region::Span>::encode(Encoder& encoder, const Region::Span& span)
-{
-    encoder << span.y;
-    encoder << (uint64_t)span.segmentIndex;
-}
-
-Optional<Region::Span> ArgumentCoder<Region::Span>::decode(Decoder& decoder)
-{
-    Region::Span span;
-    if (!decoder.decode(span.y))
-        return WTF::nullopt;
-    
-    uint64_t segmentIndex;
-    if (!decoder.decode(segmentIndex))
-        return WTF::nullopt;
-    
-    span.segmentIndex = segmentIndex;
-    return WTFMove(span);
-}
-
-void ArgumentCoder<Region>::encode(Encoder& encoder, const Region& region)
-{
-    encoder.encode(region.shapeSegments());
-    encoder.encode(region.shapeSpans());
-}
-
-bool ArgumentCoder<Region>::decode(Decoder& decoder, Region& region)
-{
-    Vector<int> segments;
-    if (!decoder.decode(segments))
-        return false;
-
-    Vector<Region::Span> spans;
-    if (!decoder.decode(spans))
-        return false;
-    
-    region.setShapeSegments(segments);
-    region.setShapeSpans(spans);
-    region.updateBoundsFromShape();
-    
-    if (!region.isValid())
-        return false;
-
-    return true;
-}
-
-Optional<Region> ArgumentCoder<Region>::decode(Decoder& decoder)
-{
-    Region region;
-    if (!decode(decoder, region))
-        return WTF::nullopt;
-
-    return region;
-}
-
 void ArgumentCoder<Length>::encode(Encoder& encoder, const Length& length)
 {
     SimpleArgumentCoder<Length>::encode(encoder, length);
@@ -972,7 +913,6 @@
     return SimpleArgumentCoder<Length>::decode(decoder, length);
 }
 
-
 void ArgumentCoder<ViewportAttributes>::encode(Encoder& encoder, const ViewportAttributes& viewportAttributes)
 {
     SimpleArgumentCoder<ViewportAttributes>::encode(encoder, viewportAttributes);

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h (242994 => 242995)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2019-03-15 15:43:20 UTC (rev 242995)
@@ -324,12 +324,6 @@
     static Optional<WebCore::Path> decode(Decoder&);
 };
 
-template<> struct ArgumentCoder<WebCore::Region> {
-    static void encode(Encoder&, const WebCore::Region&);
-    static bool decode(Decoder&, WebCore::Region&);
-    static Optional<WebCore::Region> decode(Decoder&);
-};
-
 template<> struct ArgumentCoder<WebCore::Length> {
     static void encode(Encoder&, const WebCore::Length&);
     static bool decode(Decoder&, WebCore::Length&);

Modified: trunk/Source/WebKit/UIProcess/win/WebView.cpp (242994 => 242995)


--- trunk/Source/WebKit/UIProcess/win/WebView.cpp	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebKit/UIProcess/win/WebView.cpp	2019-03-15 15:43:20 UTC (rev 242995)
@@ -474,7 +474,7 @@
         cairo_destroy(context);
         cairo_surface_destroy(surface);
 
-        Vector<IntRect> unpaintedRects = unpaintedRegion.rects();
+        auto unpaintedRects = unpaintedRegion.rects();
         for (auto& rect : unpaintedRects)
             drawPageBackground(hdc, m_page.get(), rect);
     } else

Modified: trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp (242994 => 242995)


--- trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp	2019-03-15 11:25:19 UTC (rev 242994)
+++ trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp	2019-03-15 15:43:20 UTC (rev 242995)
@@ -676,7 +676,7 @@
     m_isWaitingForDidUpdate = true;
 }
 
-static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>& rects)
+static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect, 1>& rects)
 {
     const size_t rectThreshold = 10;
     const double wastedSpaceThreshold = 0.75;
@@ -728,7 +728,7 @@
     if (!bitmap->createHandle(updateInfo.bitmapHandle))
         return;
 
-    Vector<IntRect> rects = m_dirtyRegion.rects();
+    auto rects = m_dirtyRegion.rects();
     if (shouldPaintBoundsRect(bounds, rects)) {
         rects.clear();
         rects.append(bounds);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to