File: paint_chunk.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (214 lines) | stat: -rw-r--r-- 8,148 bytes parent folder | download | duplicates (7)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
// Copyright 2015 The Chromium Authors
// 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_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNK_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNK_H_

#include <iosfwd>
#include <memory>
#include <optional>

#include "base/check_op.h"
#include "base/dcheck_is_on.h"
#include "cc/input/hit_test_opaqueness.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/hit_test_data.h"
#include "third_party/blink/renderer/platform/graphics/paint/layer_selection_data.h"
#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h"
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h"
#include "third_party/blink/renderer/platform/graphics/paint/region_capture_data.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/rect.h"

namespace blink {

constexpr float kMinBackgroundColorCoverageRatio = 0.5;

// A contiguous sequence of drawings with common paint properties.
//
// This is expected to be owned by the paint artifact which also owns the
// related drawings.
struct PLATFORM_EXPORT PaintChunk {
  DISALLOW_NEW();

  using Id = DisplayItem::Id;
  PaintChunk(wtf_size_t begin,
             wtf_size_t end,
             const DisplayItemClient& client,
             const Id& id,
             const PropertyTreeStateOrAlias& properties,
             bool effectively_invisible = false)
      : begin_index(begin),
        end_index(end),
        id(id),
        properties(properties),
        text_known_to_be_on_opaque_background(true),
        has_text(false),
        is_cacheable(client.IsCacheable()),
        client_is_just_created(client.IsJustCreated()),
        is_moved_from_cached_subsequence(false),
        effectively_invisible(effectively_invisible) {}

  // Move a paint chunk from a cached subsequence.
  PaintChunk(wtf_size_t begin, PaintChunk&& other)
      : begin_index(begin),
        end_index(begin + other.size()),
        id(other.id),
        background_color(other.background_color),
        properties(other.properties),
        hit_test_data(std::move(other.hit_test_data)),
        region_capture_data(std::move(other.region_capture_data)),
        layer_selection_data(std::move(other.layer_selection_data)),
        bounds(other.bounds),
        drawable_bounds(other.drawable_bounds),
        rect_known_to_be_opaque(other.rect_known_to_be_opaque),
        raster_effect_outset(other.raster_effect_outset),
        hit_test_opaqueness(other.hit_test_opaqueness),
        text_known_to_be_on_opaque_background(
            other.text_known_to_be_on_opaque_background),
        has_text(other.has_text),
        is_cacheable(other.is_cacheable),
        client_is_just_created(false),
        is_moved_from_cached_subsequence(true),
        effectively_invisible(other.effectively_invisible) {}

  void Trace(Visitor* visitor) const {
    visitor->Trace(properties);
    visitor->Trace(hit_test_data);
    visitor->Trace(region_capture_data);
    visitor->Trace(layer_selection_data);
  }

  wtf_size_t size() const {
    DCHECK_GE(end_index, begin_index);
    return end_index - begin_index;
  }

  // Check if a new PaintChunk (this) created in the latest paint matches an old
  // PaintChunk created in the previous paint.
  bool Matches(const PaintChunk& old) const {
    return old.is_cacheable && Matches(old.id);
  }

  bool CanMatchOldChunk() const {
    if (!is_cacheable)
      return false;
    // A chunk whose client is just created should not match any cached chunk,
    // even if it's id equals the old chunk's id (which may happen if this
    // chunk's client is just created at the same address of the old chunk's
    // deleted client).
    return !client_is_just_created;
  }

  bool Matches(const Id& other_id) const {
    return CanMatchOldChunk() && id == other_id;
  }

  bool EqualsForUnderInvalidationChecking(const PaintChunk& other) const;

  HitTestData& EnsureHitTestData() {
    if (!hit_test_data) {
      hit_test_data = MakeGarbageCollected<HitTestData>();
    }
    return *hit_test_data;
  }

  LayerSelectionData& EnsureLayerSelectionData() {
    if (!layer_selection_data) {
      layer_selection_data = MakeGarbageCollected<LayerSelectionData>();
    }
    return *layer_selection_data;
  }

  bool DrawsContent() const {
    return !effectively_invisible && !drawable_bounds.IsEmpty();
  }

  size_t MemoryUsageInBytes() const;

  // The no-argument version is for operator<< which is used in DCHECK and unit
  // tests. It doesn't output the debug name of the client.
  String ToString(bool concise = false) const;
  String ToString(const PaintArtifact& paint_artifact,
                  bool concise = false) const;

  // Index of the first drawing in this chunk.
  wtf_size_t begin_index;

  // Index of the first drawing not in this chunk, so that there are
  // |endIndex - beginIndex| drawings in the chunk.
  wtf_size_t end_index;

  // Identifier of this chunk. It should be unique if |is_cacheable| is true.
  // This is used to match a new chunk to a cached old chunk to track changes
  // of chunk contents, so the id should be stable across document cycles.
  Id id;

  // Color to use for checkerboarding, derived from display item's in this
  // chunk; or Color::kTransparent if no such display item exists.
  using BackgroundColorInfo = DrawingDisplayItem::BackgroundColorInfo;
  BackgroundColorInfo background_color;

  // The paint properties which apply to this chunk.
  TraceablePropertyTreeStateOrAlias properties;

  Member<HitTestData> hit_test_data;
  Member<RegionCaptureData> region_capture_data;
  Member<LayerSelectionData> layer_selection_data;

  // The following fields depend on the display items in this chunk.
  // They are updated when a display item is added into the chunk.

  // The total bounds of visual rects of all display items in this paint chunk,
  // and extra bounds that are not from display items for e.g. hit test.
  // It's in the coordinate space of the containing transform node. This can be
  // larger than |drawble_bounds|, because of non-drawable display items and
  // extra bounds.
  gfx::Rect bounds;

  // The total bounds of visual rects of drawable display items in this paint
  // chunk.
  gfx::Rect drawable_bounds;

  gfx::Rect rect_known_to_be_opaque;

  // Some raster effects can exceed |bounds| in the rasterization space. This
  // is the maximum DisplayItemClient::VisualRectOutsetForRasterEffects() of
  // all clients of items in this chunk.
  RasterEffectOutset raster_effect_outset = RasterEffectOutset::kNone;

  cc::HitTestOpaqueness hit_test_opaqueness =
      cc::HitTestOpaqueness::kTransparent;

  // True if all text is known to be on top of opaque backgrounds or there is
  // not text. Though in theory the value doesn't matter when there is no text,
  // being true can simplify code.
  bool text_known_to_be_on_opaque_background : 1;
  bool has_text : 1;

  // End of derived data.
  // The following fields are put here to avoid memory gap.
  bool is_cacheable : 1;
  bool client_is_just_created : 1;
  bool is_moved_from_cached_subsequence : 1;
  bool effectively_invisible : 1;
};

using PaintChunks = HeapVector<PaintChunk>;

PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const PaintChunk&);

static_assert(std::is_trivially_destructible_v<PaintChunk>);

}  // namespace blink

WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::PaintChunk)

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNK_H_