summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
blob: 245e629d4ecbba7a0a06fa729ae07270c068216b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_INVALIDATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_INVALIDATOR_H_

#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_shift_tracker.h"
#include "third_party/blink/renderer/core/paint/paint_property_tree_builder.h"
#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

struct CORE_EXPORT PaintInvalidatorContext {
  STACK_ALLOCATED();

 public:
  PaintInvalidatorContext() = default;

  explicit PaintInvalidatorContext(const PaintInvalidatorContext& parent)
      : parent_context(&parent),
        subtree_flags(parent.subtree_flags),
        directly_composited_container(parent.directly_composited_container),
        directly_composited_container_for_stacked_contents(
            parent.directly_composited_container_for_stacked_contents),
        painting_layer(parent.painting_layer) {}

  bool NeedsSubtreeWalk() const {
    return subtree_flags &
           (kSubtreeInvalidationChecking | kSubtreeFullInvalidation |
            kSubtreeFullInvalidationForStackedContents);
  }

  // TODO(pdr): Remove this accessor.
  const PaintInvalidatorContext* ParentContext() const {
    return parent_context;
  }
  const PaintInvalidatorContext* parent_context = nullptr;

  // When adding new subtree flags, ensure |NeedsSubtreeWalk| is updated.
  enum SubtreeFlag {
    kSubtreeInvalidationChecking = 1 << 0,
    kSubtreeFullInvalidation = 1 << 1,
    kSubtreeFullInvalidationForStackedContents = 1 << 2,

    // When this flag is set, no paint or raster invalidation will be issued
    // for the subtree.
    //
    // Context: some objects in this paint walk, for example SVG resource
    // container subtrees, always paint onto temporary PaintControllers which
    // don't have cache, and don't actually have any raster regions, so they
    // don't need any invalidation. They are used as "painting subroutines"
    // for one or more other locations in SVG.
    kSubtreeNoInvalidation = 1 << 6,
  };
  unsigned subtree_flags = 0;

  // The following fields can be null only before
  // PaintInvalidator::updateContext().

  // The current directly composited  container for normal flow objects.
  // It is the enclosing composited object.
  const LayoutBoxModelObject* directly_composited_container = nullptr;

  // The current directly composited container for stacked contents (stacking
  // contexts or positioned objects). It is the nearest ancestor composited
  // object which establishes a stacking context. For more information, see:
  // https://chromium.googlesource.com/chromium/src.git/+/master/third_party/blink/renderer/core/paint/README.md#Stacked-elements-and-stacking-contexts
  const LayoutBoxModelObject*
      directly_composited_container_for_stacked_contents = nullptr;

  PaintLayer* painting_layer = nullptr;

  // The previous PaintOffset of FragmentData.
  PhysicalOffset old_paint_offset;

  const FragmentData* fragment_data = nullptr;

 private:
  friend class PaintInvalidator;

  absl::optional<LayoutShiftTracker::ContainingBlockScope>
      containing_block_scope_;
  const TransformPaintPropertyNodeOrAlias* transform_ = nullptr;
};

class PaintInvalidator final {
  STACK_ALLOCATED();

 public:
  // Returns true if the object is invalidated.
  bool InvalidatePaint(const LayoutObject&,
                       const NGPrePaintInfo*,
                       const PaintPropertyTreeBuilderContext*,
                       PaintInvalidatorContext&);

  // Process objects needing paint invalidation on the next frame.
  // See the definition of PaintInvalidationDelayedFull for more details.
  void ProcessPendingDelayedPaintInvalidations();

 private:
  friend struct PaintInvalidatorContext;

  ALWAYS_INLINE void UpdatePaintingLayer(const LayoutObject&,
                                         PaintInvalidatorContext&,
                                         bool is_ng_painting);
  ALWAYS_INLINE void UpdateDirectlyCompositedContainer(const LayoutObject&,
                                                       PaintInvalidatorContext&,
                                                       bool is_ng_painting);
  ALWAYS_INLINE void UpdateFromTreeBuilderContext(
      const PaintPropertyTreeBuilderFragmentContext&,
      PaintInvalidatorContext&);
  ALWAYS_INLINE void UpdateLayoutShiftTracking(
      const LayoutObject&,
      const PaintPropertyTreeBuilderFragmentContext&,
      PaintInvalidatorContext&);

  Vector<const LayoutObject*> pending_delayed_paint_invalidations_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_INVALIDATOR_H_