1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "core/rendering/PaintInvalidationState.h"
8 #include "core/rendering/RenderInline.h"
9 #include "core/rendering/RenderLayer.h"
10 #include "core/rendering/RenderView.h"
11 #include "core/rendering/svg/RenderSVGModelObject.h"
12 #include "platform/Partitions.h"
16 PaintInvalidationState::PaintInvalidationState(const RenderView& renderView)
18 , m_cachedOffsetsEnabled(true)
19 , m_forceCheckForPaintInvalidation(false)
20 , m_paintInvalidationContainer(*renderView.containerForPaintInvalidation())
22 bool establishesPaintInvalidationContainer = renderView == m_paintInvalidationContainer;
23 if (!establishesPaintInvalidationContainer) {
24 if (!renderView.supportsPaintInvalidationStateCachedOffsets()) {
25 m_cachedOffsetsEnabled = false;
28 FloatPoint point = renderView.localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries);
29 m_paintOffset = LayoutSize(point.x(), point.y());
31 m_clipRect = renderView.viewRect();
32 m_clipRect.move(m_paintOffset);
36 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& next, RenderLayerModelObject& renderer, const RenderLayerModelObject& paintInvalidationContainer)
38 , m_cachedOffsetsEnabled(true)
39 , m_forceCheckForPaintInvalidation(next.m_forceCheckForPaintInvalidation)
40 , m_paintInvalidationContainer(paintInvalidationContainer)
42 // FIXME: SVG could probably benefit from a stack-based optimization like html does. crbug.com/391054
43 bool establishesPaintInvalidationContainer = renderer == m_paintInvalidationContainer;
44 bool fixed = renderer.style()->position() == FixedPosition;
46 if (establishesPaintInvalidationContainer) {
47 // When we hit a new paint invalidation container, we don't need to
48 // continue forcing a check for paint invalidation because movement
49 // from our parents will just move the whole invalidation container.
50 m_forceCheckForPaintInvalidation = false;
52 if (!renderer.supportsPaintInvalidationStateCachedOffsets() || !next.m_cachedOffsetsEnabled) {
53 m_cachedOffsetsEnabled = false;
56 FloatPoint fixedOffset = renderer.localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries);
57 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y());
59 LayoutSize offset = renderer.isBox() && !renderer.isTableRow() ? toRenderBox(renderer).locationOffset() : LayoutSize();
60 m_paintOffset = next.m_paintOffset + offset;
63 if (renderer.isOutOfFlowPositioned() && !fixed) {
64 if (RenderObject* container = renderer.container()) {
65 if (container->style()->hasInFlowPosition() && container->isRenderInline())
66 m_paintOffset += toRenderInline(container)->offsetForInFlowPositionedInline(toRenderBox(renderer));
70 if (renderer.style()->hasInFlowPosition() && renderer.hasLayer())
71 m_paintOffset += renderer.layer()->offsetForInFlowPosition();
74 m_clipped = !fixed && next.m_clipped;
76 m_clipRect = next.m_clipRect;
79 applyClipIfNeeded(renderer);
81 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
84 void PaintInvalidationState::applyClipIfNeeded(const RenderObject& renderer)
86 if (!renderer.hasOverflowClip())
89 const RenderBox& box = toRenderBox(renderer);
91 // Do not clip scroll layer contents because the compositor expects the whole layer
92 // to be always invalidated in-time.
93 if (box.usesCompositedScrolling()) {
94 ASSERT(!m_clipped); // The box should establish paint invalidation container, so no m_clipped inherited.
96 LayoutRect clipRect(toPoint(m_paintOffset), box.layer()->size());
98 m_clipRect.intersect(clipRect);
100 m_clipRect = clipRect;
105 m_paintOffset -= box.scrolledContentOffset();