From cb7d2bffec33ecc6e0eae9ae2500d755d3cccca9 Mon Sep 17 00:00:00 2001 From: "chrishtr@chromium.org" Date: Thu, 21 Aug 2014 21:27:51 +0000 Subject: [PATCH] Allow paint invalidation containers to cross frame boundaries. (re-land #2) The previous commit was rolled out because it did not make the required changes to PaintInvalidationState in order to teach it how to cross frame boundaries. Previously, the *actual* paint invalidation container, meaning the enclosing compositing layer / root RenderView, could already have been across a frame boundary. The logic to do this correctly was done via special code in RenderView. Instead, generalize the existing mechanisms to find a paint invalidation container and map rects to repaint container coordinate space to cross frame boundaries. This simplifies the code, and also causes paint invalidation rects to always be stored in the coordinate space of their graphics layer backing. The latter is important if we want to use these rects for determining which parts of a graphics layer need to be painted. BUG= Review URL: https://codereview.chromium.org/482063005 git-svn-id: svn://svn.chromium.org/blink/trunk@180736 bbb929c8-8fbe-4397-9dbb-9b2b20218538 --- ...t-for-fixed-pos-inside-iframe-expected.txt | 14 +++++ ...ate-paint-for-fixed-pos-inside-iframe.html | 21 +++++++ ...in-iframe-in-composited-layer-expected.txt | 22 +++++++ ...e-paint-in-iframe-in-composited-layer.html | 23 ++++++++ .../repaint/repaint-in-iframe-expected.txt | 2 +- .../fast/repaint/repaint-in-iframe.html | 2 +- Source/core/frame/FrameView.cpp | 12 ++-- .../core/rendering/PaintInvalidationState.cpp | 34 ++++------- .../core/rendering/PaintInvalidationState.h | 7 ++- .../core/rendering/RenderLayerRepainter.cpp | 18 +----- Source/core/rendering/RenderObject.cpp | 32 ++++++---- Source/core/rendering/RenderObject.h | 5 +- Source/core/rendering/RenderView.cpp | 59 ++++++++++--------- Source/core/rendering/RenderView.h | 2 +- 14 files changed, 160 insertions(+), 93 deletions(-) create mode 100644 LayoutTests/fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe-expected.txt create mode 100644 LayoutTests/fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe.html create mode 100644 LayoutTests/fast/repaint/invalidate-paint-in-iframe-in-composited-layer-expected.txt create mode 100644 LayoutTests/fast/repaint/invalidate-paint-in-iframe-in-composited-layer.html diff --git a/LayoutTests/fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe-expected.txt b/LayoutTests/fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe-expected.txt new file mode 100644 index 00000000000..9e173047fea --- /dev/null +++ b/LayoutTests/fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe-expected.txt @@ -0,0 +1,14 @@ +{ + "bounds": [800, 600], + "children": [ + { + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "repaintRects": [ + [18, 418, 50, 50] + ] + } + ] +} + diff --git a/LayoutTests/fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe.html b/LayoutTests/fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe.html new file mode 100644 index 00000000000..9b53f96ec1a --- /dev/null +++ b/LayoutTests/fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe.html @@ -0,0 +1,21 @@ + + + + + + + +
+ diff --git a/LayoutTests/fast/repaint/invalidate-paint-in-iframe-in-composited-layer-expected.txt b/LayoutTests/fast/repaint/invalidate-paint-in-iframe-in-composited-layer-expected.txt new file mode 100644 index 00000000000..e0b97835b53 --- /dev/null +++ b/LayoutTests/fast/repaint/invalidate-paint-in-iframe-in-composited-layer-expected.txt @@ -0,0 +1,22 @@ +{ + "bounds": [785, 616], + "children": [ + { + "bounds": [785, 616], + "contentsOpaque": true, + "drawsContent": true, + "children": [ + { + "position": [8, 408], + "transformOrigin": [100, 100], + "bounds": [304, 200], + "drawsContent": true, + "repaintRects": [ + [10, 10, 50, 50] + ] + } + ] + } + ] +} + diff --git a/LayoutTests/fast/repaint/invalidate-paint-in-iframe-in-composited-layer.html b/LayoutTests/fast/repaint/invalidate-paint-in-iframe-in-composited-layer.html new file mode 100644 index 00000000000..3f07dff91d6 --- /dev/null +++ b/LayoutTests/fast/repaint/invalidate-paint-in-iframe-in-composited-layer.html @@ -0,0 +1,23 @@ + + + + + + + +
+
+ +
diff --git a/LayoutTests/fast/repaint/repaint-in-iframe-expected.txt b/LayoutTests/fast/repaint/repaint-in-iframe-expected.txt index e40490720ef..9e173047fea 100644 --- a/LayoutTests/fast/repaint/repaint-in-iframe-expected.txt +++ b/LayoutTests/fast/repaint/repaint-in-iframe-expected.txt @@ -6,7 +6,7 @@ "contentsOpaque": true, "drawsContent": true, "repaintRects": [ - [18, 418, 284, 50] + [18, 418, 50, 50] ] } ] diff --git a/LayoutTests/fast/repaint/repaint-in-iframe.html b/LayoutTests/fast/repaint/repaint-in-iframe.html index 9141495ff16..0cc28dceac9 100644 --- a/LayoutTests/fast/repaint/repaint-in-iframe.html +++ b/LayoutTests/fast/repaint/repaint-in-iframe.html @@ -18,4 +18,4 @@
- + diff --git a/Source/core/frame/FrameView.cpp b/Source/core/frame/FrameView.cpp index 05659b0f631..6d6e8ef1c20 100644 --- a/Source/core/frame/FrameView.cpp +++ b/Source/core/frame/FrameView.cpp @@ -965,14 +965,14 @@ void FrameView::layout(bool allowSubtree) // See http://crbug.com/306706 void FrameView::invalidateTreeIfNeeded() { - RenderObject* rootForPaintInvalidation = renderView(); - ASSERT(!rootForPaintInvalidation->needsLayout()); + RenderView& rootForPaintInvalidation = *renderView(); + ASSERT(!rootForPaintInvalidation.needsLayout()); - TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInvalidation->debugName().ascii()); + TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInvalidation.debugName().ascii()); - PaintInvalidationState rootPaintInvalidationState(*rootForPaintInvalidation); + PaintInvalidationState rootPaintInvalidationState(rootForPaintInvalidation); - rootForPaintInvalidation->invalidateTreeIfNeeded(rootPaintInvalidationState); + rootForPaintInvalidation.invalidateTreeIfNeeded(rootPaintInvalidationState); // Invalidate the paint of the frameviews scrollbars if needed if (hasVerticalBarDamage()) @@ -1604,7 +1604,7 @@ HostWindow* FrameView::hostWindow() const void FrameView::contentRectangleForPaintInvalidation(const IntRect& r) { ASSERT(paintInvalidationIsAllowed()); - ASSERT(!m_frame->owner()); + ASSERT(!m_frame->ownerRenderer()); if (m_isTrackingPaintInvalidations) { IntRect paintInvalidationRect = r; diff --git a/Source/core/rendering/PaintInvalidationState.cpp b/Source/core/rendering/PaintInvalidationState.cpp index 12753da0aa2..c5287961dc8 100644 --- a/Source/core/rendering/PaintInvalidationState.cpp +++ b/Source/core/rendering/PaintInvalidationState.cpp @@ -13,32 +13,25 @@ namespace blink { -PaintInvalidationState::PaintInvalidationState(RenderObject& renderer) +PaintInvalidationState::PaintInvalidationState(const RenderView& renderView) : m_clipped(false) , m_cachedOffsetsEnabled(true) , m_forceCheckForPaintInvalidation(false) - , m_paintInvalidationContainer(*renderer.containerForPaintInvalidation()) - , m_renderer(renderer) + , m_paintInvalidationContainer(*renderView.containerForPaintInvalidation()) + , m_renderer(renderView) { bool establishesPaintInvalidationContainer = &m_renderer == &m_paintInvalidationContainer; if (!establishesPaintInvalidationContainer) { - if (!renderer.supportsPaintInvalidationStateCachedOffsets()) { + if (!renderView.supportsPaintInvalidationStateCachedOffsets()) { m_cachedOffsetsEnabled = false; return; } - bool invalidationContainerSkipped; - RenderObject* container = renderer.container(&m_paintInvalidationContainer, &invalidationContainerSkipped); - if (container && !invalidationContainerSkipped) { - FloatPoint point = container->localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer); - if (container->isTableRow()) - point = FloatPoint(point.x() - toRenderBox(container)->x().toFloat(), point.y() - toRenderBox(container)->y().toFloat()); - m_paintOffset = LayoutSize(point.x(), point.y()); - - applyClipIfNeeded(*container); - } - } else { - applyClipIfNeeded(m_renderer); + FloatPoint point = renderView.localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries); + m_paintOffset = LayoutSize(point.x(), point.y()); } + m_clipRect = renderView.viewRect(); + m_clipRect.move(m_paintOffset); + m_clipped = true; } PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& next, RenderLayerModelObject& renderer, const RenderLayerModelObject& paintInvalidationContainer) @@ -50,7 +43,7 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& nex { // FIXME: SVG could probably benefit from a stack-based optimization like html does. crbug.com/391054 bool establishesPaintInvalidationContainer = &m_renderer == &m_paintInvalidationContainer; - bool fixed = m_renderer.isOutOfFlowPositioned() && m_renderer.style()->position() == FixedPosition; + bool fixed = m_renderer.style()->position() == FixedPosition; if (establishesPaintInvalidationContainer) { // When we hit a new paint invalidation container, we don't need to @@ -61,12 +54,11 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& nex if (!renderer.supportsPaintInvalidationStateCachedOffsets() || !next.m_cachedOffsetsEnabled) { m_cachedOffsetsEnabled = false; } else { - LayoutSize offset = m_renderer.isBox() && !m_renderer.isTableRow() ? toRenderBox(renderer).locationOffset() : LayoutSize(); if (fixed) { - // FIXME: This doesn't work correctly with transforms. - FloatPoint fixedOffset = m_renderer.view()->localToAbsolute(FloatPoint(), IsFixed); - m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset; + FloatPoint fixedOffset = m_renderer.localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries); + m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()); } else { + LayoutSize offset = m_renderer.isBox() && !m_renderer.isTableRow() ? toRenderBox(renderer).locationOffset() : LayoutSize(); m_paintOffset = next.m_paintOffset + offset; } diff --git a/Source/core/rendering/PaintInvalidationState.h b/Source/core/rendering/PaintInvalidationState.h index 8f0765857de..d7dcd2ec013 100644 --- a/Source/core/rendering/PaintInvalidationState.h +++ b/Source/core/rendering/PaintInvalidationState.h @@ -14,6 +14,7 @@ class RenderBox; class RenderInline; class RenderLayerModelObject; class RenderObject; +class RenderView; class RenderSVGModelObject; class PaintInvalidationState { @@ -21,7 +22,7 @@ class PaintInvalidationState { public: PaintInvalidationState(const PaintInvalidationState& next, RenderLayerModelObject& renderer, const RenderLayerModelObject& paintInvalidationContainer); - explicit PaintInvalidationState(RenderObject&); + explicit PaintInvalidationState(const RenderView&); const LayoutRect& clipRect() const { return m_clipRect; } const LayoutSize& paintOffset() const { return m_paintOffset; } @@ -33,7 +34,7 @@ class PaintInvalidationState { void setForceCheckForPaintInvalidation() { m_forceCheckForPaintInvalidation = true; } const RenderLayerModelObject& paintInvalidationContainer() const { return m_paintInvalidationContainer; } - RenderObject& renderer() const { return m_renderer; } + const RenderObject& renderer() const { return m_renderer; } bool canMapToContainer(const RenderLayerModelObject* container) const { @@ -55,7 +56,7 @@ class PaintInvalidationState { const RenderLayerModelObject& m_paintInvalidationContainer; - RenderObject& m_renderer; + const RenderObject& m_renderer; }; } // namespace blink diff --git a/Source/core/rendering/RenderLayerRepainter.cpp b/Source/core/rendering/RenderLayerRepainter.cpp index 29e712e8e91..62336f56365 100644 --- a/Source/core/rendering/RenderLayerRepainter.cpp +++ b/Source/core/rendering/RenderLayerRepainter.cpp @@ -110,23 +110,7 @@ void RenderLayerRepainter::setBackingNeedsPaintInvalidationInRect(const LayoutRe // https://bugs.webkit.org/show_bug.cgi?id=61159 describes an unreproducible crash here, // so assert but check that the layer is composited. ASSERT(m_renderer.compositingState() != NotComposited); - if (m_renderer.compositingState() == NotComposited) { - // If we're trying to issue paint invalidations of the placeholder document layer, propagate the - // paint invalidation to the native view system. - LayoutRect absRect(r); - LayoutPoint delta; - m_renderer.layer()->convertToLayerCoords(m_renderer.layer()->root(), delta); - absRect.moveBy(delta); - - if (absRect.isEmpty()) - return; - - RenderView* view = m_renderer.view(); - if (view) - view->invalidatePaintForRectangle(absRect); - return; - } - // FIXME: generalize accessors to backing GraphicsLayers so that this code is squasphing-agnostic. + // FIXME: generalize accessors to backing GraphicsLayers so that this code is squashing-agnostic. if (m_renderer.layer()->groupedMapping()) { LayoutRect paintInvalidationRect = r; paintInvalidationRect.move(m_renderer.layer()->subpixelAccumulation()); diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp index c976c3aee3d..0186feb8cbc 100644 --- a/Source/core/rendering/RenderObject.cpp +++ b/Source/core/rendering/RenderObject.cpp @@ -66,6 +66,7 @@ #include "core/rendering/RenderListItem.h" #include "core/rendering/RenderMarquee.h" #include "core/rendering/RenderObjectInlines.h" +#include "core/rendering/RenderPart.h" #include "core/rendering/RenderScrollbarPart.h" #include "core/rendering/RenderTableCaption.h" #include "core/rendering/RenderTableCell.h" @@ -1445,13 +1446,11 @@ const RenderLayerModelObject* RenderObject::containerForPaintInvalidation() cons const RenderLayerModelObject* RenderObject::enclosingCompositedContainer() const { RenderLayerModelObject* container = 0; - if (view()->usesCompositing()) { - // FIXME: CompositingState is not necessarily up to date for many callers of this function. - DisableCompositingQueryAsserts disabler; + // FIXME: CompositingState is not necessarily up to date for many callers of this function. + DisableCompositingQueryAsserts disabler; - if (RenderLayer* compositingLayer = enclosingLayer()->enclosingLayerForPaintInvalidation()) - container = compositingLayer->renderer(); - } + if (RenderLayer* compositingLayer = enclosingLayer()->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()) + container = compositingLayer->renderer(); return container; } @@ -1466,7 +1465,14 @@ const RenderLayerModelObject* RenderObject::adjustCompositedContainerForSpecialA if (!paintInvalidationContainer || paintInvalidationContainer->flowThreadContainingBlock() != parentRenderFlowThread) paintInvalidationContainer = parentRenderFlowThread; } - return paintInvalidationContainer ? paintInvalidationContainer : view(); + + if (paintInvalidationContainer) + return paintInvalidationContainer; + + RenderView* renderView = view(); + while (renderView->frame()->ownerRenderer()) + renderView = renderView->frame()->ownerRenderer()->view(); + return renderView; } bool RenderObject::isPaintInvalidationContainer() const @@ -1525,14 +1531,11 @@ void RenderObject::invalidatePaintUsingContainer(const RenderLayerModelObject* p return; } - RenderView* v = view(); if (paintInvalidationContainer->isRenderView()) { - ASSERT(paintInvalidationContainer == v); - v->invalidatePaintForRectangle(r); + toRenderView(paintInvalidationContainer)->invalidatePaintForRectangle(r); return; } - - if (v->usesCompositing()) { + if (paintInvalidationContainer->view()->usesCompositing()) { ASSERT(paintInvalidationContainer->hasLayer() && (paintInvalidationContainer->layer()->compositingState() == PaintsIntoOwnBacking || paintInvalidationContainer->layer()->compositingState() == PaintsIntoGroupedBacking)); paintInvalidationContainer->layer()->paintInvalidator().setBackingNeedsPaintInvalidationInRect(r); } @@ -1763,6 +1766,11 @@ LayoutRect RenderObject::rectWithOutlineForPaintInvalidation(const RenderLayerMo return r; } +LayoutRect RenderObject::absoluteClippedOverflowRect() const +{ + return clippedOverflowRectForPaintInvalidation(view()); +} + LayoutRect RenderObject::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject*, const PaintInvalidationState*) const { ASSERT_NOT_REACHED(); diff --git a/Source/core/rendering/RenderObject.h b/Source/core/rendering/RenderObject.h index 6759aed9f69..61543211182 100644 --- a/Source/core/rendering/RenderObject.h +++ b/Source/core/rendering/RenderObject.h @@ -890,10 +890,7 @@ class RenderObject : public NoBaseWillBeGarbageCollectedFinalized, // Returns the rect that should have paint invalidated whenever this object changes. The rect is in the view's // coordinate space. This method deals with outlines and overflow. - LayoutRect absoluteClippedOverflowRect() const - { - return clippedOverflowRectForPaintInvalidation(0); - } + LayoutRect absoluteClippedOverflowRect() const; IntRect pixelSnappedAbsoluteClippedOverflowRect() const; virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* = 0) const; virtual LayoutRect rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth, const PaintInvalidationState* = 0) const; diff --git a/Source/core/rendering/RenderView.cpp b/Source/core/rendering/RenderView.cpp index 36d94d166d7..8e8549ff5f0 100644 --- a/Source/core/rendering/RenderView.cpp +++ b/Source/core/rendering/RenderView.cpp @@ -294,10 +294,6 @@ void RenderView::mapLocalToContainer(const RenderLayerModelObject* paintInvalida return; } } - - // If a container was specified, and was not 0 or the RenderView, - // then we should have found it by now. - ASSERT_ARG(paintInvalidationContainer, !paintInvalidationContainer); } const RenderObject* RenderView::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const @@ -438,9 +434,12 @@ void RenderView::invalidateTreeIfNeeded(const PaintInvalidationState& paintInval // We specifically need to issue paint invalidations for the viewRect since other renderers // short-circuit on full-paint invalidation. - if (doingFullPaintInvalidation() && !viewRect().isEmpty()) - invalidatePaintForRectangle(viewRect()); - + LayoutRect dirtyRect = viewRect(); + if (doingFullPaintInvalidation() && !dirtyRect.isEmpty()) { + const RenderLayerModelObject* paintInvalidationContainer = &paintInvalidationState.paintInvalidationContainer(); + mapRectToPaintInvalidationBacking(paintInvalidationContainer, dirtyRect, IsNotFixedPosition, &paintInvalidationState); + invalidatePaintUsingContainer(paintInvalidationContainer, dirtyRect, InvalidationFull); + } RenderBlock::invalidateTreeIfNeeded(paintInvalidationState); } @@ -451,24 +450,12 @@ void RenderView::invalidatePaintForRectangle(const LayoutRect& paintInvalidation if (document().printing() || !m_frameView) return; - // We always just invalidate the root view, since we could be an iframe that is clipped out - // or even invisible. - HTMLFrameOwnerElement* owner = document().ownerElement(); + ASSERT(layer()->compositingState() == PaintsIntoOwnBacking || !frame()->ownerRenderer()); + if (layer()->compositingState() == PaintsIntoOwnBacking) { layer()->paintInvalidator().setBackingNeedsPaintInvalidationInRect(paintInvalidationRect); - } else if (!owner) { + } else { m_frameView->contentRectangleForPaintInvalidation(pixelSnappedIntRect(paintInvalidationRect)); - } else if (RenderBox* obj = owner->renderBox()) { - // Intersect the viewport with the paint invalidation rect. - LayoutRect viewRectangle = viewRect(); - LayoutRect rectToInvalidate = intersection(paintInvalidationRect, viewRectangle); - - // Adjust for scroll offset of the view. - rectToInvalidate.moveBy(-viewRectangle.location()); - - // Adjust for frame border. - rectToInvalidate.moveBy(obj->contentBoxRect().location()); - obj->invalidatePaintRectangle(rectToInvalidate); } } @@ -483,12 +470,8 @@ void RenderView::invalidatePaintForViewAndCompositedLayers() compositor()->fullyInvalidatePaint(); } -void RenderView::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, ViewportConstrainedPosition viewportConstraint, const PaintInvalidationState*) const +void RenderView::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, ViewportConstrainedPosition viewportConstraint, const PaintInvalidationState* state) const { - // If a container was specified, and was not 0 or the RenderView, - // then we should have found it by now. - ASSERT_ARG(paintInvalidationContainer, !paintInvalidationContainer || paintInvalidationContainer == this); - if (document().printing()) return; @@ -513,8 +496,30 @@ void RenderView::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* // Apply our transform if we have one (because of full page zooming). if (!paintInvalidationContainer && layer() && layer()->transform()) rect = layer()->transform()->mapRect(rect); + + ASSERT(paintInvalidationContainer); + if (paintInvalidationContainer == this) + return; + + Element* owner = document().ownerElement(); + if (!owner) + return; + + if (RenderBox* obj = owner->renderBox()) { + // Intersect the viewport with the paint invalidation rect. + LayoutRect viewRectangle = viewRect(); + rect.intersect(viewRectangle); + + // Adjust for scroll offset of the view. + rect.moveBy(-viewRectangle.location()); + + // Adjust for frame border. + rect.moveBy(obj->contentBoxRect().location()); + obj->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, IsNotFixedPosition, 0); + } } + void RenderView::absoluteRects(Vector& rects, const LayoutPoint& accumulatedOffset) const { rects.append(pixelSnappedIntRect(accumulatedOffset, layer()->size())); diff --git a/Source/core/rendering/RenderView.h b/Source/core/rendering/RenderView.h index 352a73d43b0..00ddd9ca4c1 100644 --- a/Source/core/rendering/RenderView.h +++ b/Source/core/rendering/RenderView.h @@ -156,6 +156,7 @@ class RenderView FINAL : public RenderBlockFlow { void pushLayoutState(LayoutState&); void popLayoutState(); + virtual void invalidateTreeIfNeeded(const PaintInvalidationState&) OVERRIDE FINAL; private: virtual void mapLocalToContainer(const RenderLayerModelObject* paintInvalidationContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0, const PaintInvalidationState* = 0) const OVERRIDE; @@ -163,7 +164,6 @@ class RenderView FINAL : public RenderBlockFlow { virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE; virtual void computeSelfHitTestRects(Vector&, const LayoutPoint& layerOffset) const OVERRIDE; - virtual void invalidateTreeIfNeeded(const PaintInvalidationState&) OVERRIDE FINAL; bool shouldInvalidatePaint(const LayoutRect&) const;