File: resolved_frame_data.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (405 lines) | stat: -rw-r--r-- 16,113 bytes parent folder | download | duplicates (5)
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_RESOLVED_FRAME_DATA_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_RESOLVED_FRAME_DATA_H_

#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/functional/function_ref.h"
#include "base/memory/raw_ptr.h"
#include "components/viz/common/quads/aggregated_render_pass.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "components/viz/common/quads/compositor_render_pass.h"
#include "components/viz/common/quads/draw_quad.h"
#include "components/viz/common/quads/offset_tag.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/service/display/display_resource_provider.h"
#include "components/viz/service/surfaces/frame_index_constants.h"
#include "components/viz/service/viz_service_export.h"

namespace viz {

class Surface;

// Returns |damage_rect| field from the DrawQuad if it exists otherwise returns
// an empty optional.
const std::optional<gfx::Rect>& GetOptionalDamageRectFromQuad(
    const DrawQuad* quad);

// Data associated with a DrawQuad in a resolved frame.
struct VIZ_SERVICE_EXPORT ResolvedQuadData {
  explicit ResolvedQuadData(const DrawQuad& quad);

  // Remapped display ResourceId.
  ResourceId remapped_resource_id;
};

// Render pass data that is fixed for the lifetime of ResolvedPassData.
struct VIZ_SERVICE_EXPORT FixedPassData {
  FixedPassData();
  FixedPassData(FixedPassData&& other);
  FixedPassData& operator=(FixedPassData&& other);
  ~FixedPassData();

  // Only valid during aggregation: set at the beginning a new round of
  // aggregation and reset to null at the end of each aggregation.
  //
  // This shouldn't be dangling anymore because CompositorFrames are never
  // destroyed during aggregation so the pointer will remain valid for the
  // duration of aggregation (until it's set to null).
  raw_ptr<CompositorRenderPass> render_pass = nullptr;

  // How many times this render pass is embedded by another render pass in the
  // same frame.
  int embed_count = 0;

  AggregatedRenderPassId remapped_id;
  CompositorRenderPassId render_pass_id;
  bool is_root = false;
  std::vector<ResolvedQuadData> draw_quads;
};

class ResolvedPassData;

// Render pass data that must be recomputed each aggregation. Unlike
// FixedPassData this changes each aggregation depending on what other
// Surfaces/CompositorFrames are part of the draw tree.
struct VIZ_SERVICE_EXPORT AggregationPassData {
  AggregationPassData();
  AggregationPassData(AggregationPassData&& other);
  AggregationPassData& operator=(AggregationPassData&& other);
  ~AggregationPassData();

  // Resets to default constructed state.
  void Reset();

  // Embedded render passes that contribute pixels to this render pass.
  base::flat_set<raw_ptr<ResolvedPassData, CtnExperimental>> embedded_passes;

  // True if the render pass is drawn to fulfil part of a copy request. This
  // property is transitive from parent pass to embedded passes.
  bool in_copy_request_pass = false;

  // True if the render pass is be impacted by a pixel moving foreground filter.
  // This property is transitive from parent pass to embedded passes.
  bool in_pixel_moving_filter_pass = false;

  // True if the render pass will be stored as part of a cached render pass.
  // This property is transitive from parent pass to embedded passes.
  bool in_cached_render_pass = false;

  // True if there is accumulated damage in the render pass or from contributing
  // render passes or surfaces. This bit indicates whether the render pass needs
  // to be redrawn since its content has changed from the previous frame or if
  // the cached content from the previous frame can be reused.
  //
  // Note: This is different than checking render pass damage_rect.IsEmpty(). cc
  // resets any non-root render pass damage_rects and aggregates non-root damage
  // into the root render pass damage_rect. cc already plumbs a separate bool
  // `has_damage_from_contributing_content` with each CompositorRenderPass to
  // say if the render pass has damage. Ideally cc would just plumb the correct
  // damage_rect and no bool. `has_damage` also takes into account if there is
  // added damage from embedded content or filters that the client submitting
  // the CompositorFrame didn't know about.
  bool has_damage = false;

  // Indicates that the render pass is embedded from the root surface root
  // render pass and will contribute pixels to framebuffer. Render passes this
  // is false for may still be drawn but they won't contribute pixels to
  // framebuffer.
  bool will_draw = false;

  // The damage added from its descandant surfaces during aggregation. This is
  // not part of the original render_pass->damage_rect from CC.
  gfx::Rect added_damage;

  // |true| to if this pass should embedded and not merged. This is to support
  // |kDelegatedCompositingLimitToUi| on Windows to keep the web contents
  // surface in a swap chain instead of delegating its quads.
  // TODO(crbug.com/324460866): Used for partially delegated compositing.
  bool prevent_merge = false;
};

// Render pass data that must be recomputed each aggregation and needs to be
// persisted to next aggregation.
struct PersistentPassData {
  PersistentPassData();
  PersistentPassData(PersistentPassData&& other);
  PersistentPassData& operator=(PersistentPassData& other);
  PersistentPassData& operator=(const PersistentPassData& other);
  PersistentPassData& operator=(PersistentPassData&& other);
  ~PersistentPassData();

  enum MergeState { kInitState, kNotMerged, kAlwaysMerged, kSomeTimesMerged };

  // The intersection of all render pass output rects, RenderPassDrawQuad rect,
  // SurfaceDrawQuad rect, and clip rects from its ancestor render passes and
  // surface. This is the max size this render pass can be rendered into the
  // root surface. |parent_clip_rect| is in the dest root target space.
  gfx::Rect parent_clip_rect;

  // Whether the render passes is merged with its parent render pass. The render
  // mighe be embedded multiple times and has different status each time.
  MergeState merge_state = kInitState;
};

// Data associated with a CompositorRenderPass in a resolved frame. Has fixed
// portion that does not change and an aggregation portion that does change.
class VIZ_SERVICE_EXPORT ResolvedPassData {
 public:
  explicit ResolvedPassData(FixedPassData fixed_data);
  ~ResolvedPassData();
  ResolvedPassData(ResolvedPassData&& other);
  ResolvedPassData& operator=(ResolvedPassData&& other);

  const CompositorRenderPass& render_pass() const;
  AggregatedRenderPassId remapped_id() const { return fixed_.remapped_id; }
  CompositorRenderPassId render_pass_id() const {
    return fixed_.render_pass_id;
  }
  bool is_root() const { return fixed_.is_root; }
  const std::vector<ResolvedQuadData>& draw_quads() const {
    return fixed_.draw_quads;
  }

  // Returns true if the render pass is not embedded by another render pass and
  // is not the root render pass.
  bool IsUnembedded() const {
    return !fixed_.is_root && fixed_.embed_count == 0;
  }

  AggregationPassData& aggregation() { return aggregation_; }
  const AggregationPassData& aggregation() const { return aggregation_; }

  PersistentPassData& current_persistent_data() {
    return current_persistent_data_;
  }

  PersistentPassData& previous_persistent_data() {
    return previous_persistent_data_;
  }

  const PersistentPassData& previous_persistent_data() const {
    return previous_persistent_data_;
  }

  void CopyAndResetPersistentPassData();

  // Set `fixed_.render_pass` to `pass`. Should be called at the beginning of an
  // aggregation.
  void SetCompositorRenderPass(CompositorRenderPass* pass);

  // Set `fixed_.render_pass` back to null, to avoid the dangling pointer
  // after aggregation. Should be called at the end of an aggregation.
  void ResetCompositorRenderPass();

 private:
  friend class ResolvedFrameData;

  // Data that is constant for the life of the resolved pass.
  FixedPassData fixed_;

  // Data that will change each aggregation.
  AggregationPassData aggregation_;

  PersistentPassData current_persistent_data_;
  PersistentPassData previous_persistent_data_;
};

enum FrameDamageType {
  // The CompositorFrame should be considered fully damaged. This could be the
  // first CompositorFrame from the client, an intermediate CompositorFrame was
  // skipped so the damage is unknown or there is synthetic damage.
  kFull,
  // The damage contained in the CompositorFrame should be used.
  kFrame,
  // The CompositorFrame is the same as last aggregation and has no damage.
  kNone
};

// Holds computed information for a particular Surface+CompositorFrame. The
// CompositorFrame computed information will be updated whenever the active
// frame for the surface has changed. On destruction any resources registered
// with DisplayResourceProvider will be released.
//
// The first time a resolved frame is needed during aggregation
// UpdateForAggregation() then UpdateOffsetTags() must be called. That will
// populate all of the internal data. During aggregation the fixed data is
// viewed and aggregation data can be modified. After aggregation is over
// ResetAfterAggregation() will be called which resets aggregation data.
class VIZ_SERVICE_EXPORT ResolvedFrameData {
 public:
  using OffsetTagLookupFn =
      base::FunctionRef<gfx::Vector2dF(const OffsetTagDefinition&)>;

  ResolvedFrameData(DisplayResourceProvider* resource_provider,
                    Surface* surface,
                    uint64_t prev_frame_index,
                    AggregatedRenderPassId prev_root_pass_id);
  ~ResolvedFrameData();
  ResolvedFrameData(ResolvedFrameData&& other) = delete;
  ResolvedFrameData& operator=(ResolvedFrameData&& other) = delete;

  const SurfaceId& surface_id() const { return surface_id_; }
  Surface* surface() const { return surface_; }
  bool is_valid() const { return valid_; }
  uint64_t previous_frame_index() const { return previous_frame_index_; }

  gfx::Size size_in_pixels() const;
  float device_scale_factor() const;

  // Returns namespace ID for the client that submitted this frame. This is used
  // to deduplicate layer IDs from different clients.
  std::pair<uint32_t, uint32_t> GetClientNamespaceId() const;

  void SetFullDamageForNextAggregation();

  // Force release all resources registered with display resource provider. Note
  // there must be a new CompositorFrame available that doesn't use any existing
  // resources since resources (might) be missing on next draw.
  void ForceReleaseResource();

  // This must be called once before using ResolvedFrameData during aggregation.
  // If there is a new active CompositorFrame data will be fully updated, see
  // UpdatedActiveFrame() for details, otherwise previous data will be reused.
  void UpdateForAggregation(
      AggregatedRenderPassId::Generator& render_pass_id_generator);

  // This should be called each aggregation after UpdateForAggregation() to
  // update resolved frame for OffsetTags. If the active CompositorFrame defines
  // any tags, the tag values will be found and the resolved frame will be
  // modified.
  void UpdateOffsetTags(OffsetTagLookupFn lookup_value);

  // Sets frame index and marks as invalid. This also clears any existing
  // resolved pass data.
  void SetInvalid();

  bool WasUsedInAggregation() const;

  // Resets aggregation data and WasUsedInAggregation() will now return false.
  void ResetAfterAggregation();

  // All functions after this point are accessors for the resolved frame and
  // should only be called if is_valid() returns true.

  const CompositorFrameMetadata& GetMetadata() const;

  // Returns true if the root render pass is embedded from the the root surface
  // root render pass.
  bool WillDraw() const;

  // RenderPassData accessors.
  ResolvedPassData& GetRenderPassDataById(
      CompositorRenderPassId render_pass_id);
  const ResolvedPassData& GetRenderPassDataById(
      CompositorRenderPassId render_pass_id) const;

  ResolvedPassData& GetRootRenderPassData();
  const ResolvedPassData& GetRootRenderPassData() const;

  std::vector<ResolvedPassData>& GetResolvedPasses() {
    return resolved_passes_;
  }
  const std::vector<ResolvedPassData>& GetResolvedPasses() const {
    return resolved_passes_;
  }

  // See `FrameDamageType` definition for what each status means.
  FrameDamageType GetFrameDamageType() const;

  // Returns surface damage rect. This is based on changes from the
  // CompositorFrame aggregated last frame. This limited to the root render
  // passes damage_rect and does not include individual quads that add damage.
  gfx::Rect GetSurfaceDamage() const;

  // Returns the root render pass output_rect.
  const gfx::Rect& GetOutputRect() const;

 private:
  friend class ResolvedFrameDataTestHelper;

  // Data for a specific `OffsetTag`.
  struct OffsetTagData {
    // The offset value that is used.
    gfx::Vector2dF last_offset;
    gfx::Vector2dF current_offset;
    // The containing rect is the union of all tagged quad visible rects in
    // root render pass coordinate space before applying any offsets.
    gfx::Rect last_containing_rect;
    gfx::Rect current_containing_rect;
    bool defined_in_frame = false;
  };

  // Updates ResolvedPassData for a new active frame. It also updates surface
  // client and display resource provider with resources used in the new active
  // frame.
  //
  // This performs the following validation on the active CompositorFrame.
  // 1. Checks each ResourceId was registered with DisplayResourceProvider and
  //    is in |child_to_parent_map|.
  // 2. Checks that CompositorRenderPasses have unique ids.
  // 3. Checks that CompositorRenderPassDrawQuads only embed render passes that
  //    are drawn before. This has the side effect of disallowing any cycles.
  //
  // If validation fails then ResolvedPassData will be cleared and is_valid()
  // will return false.
  void UpdateActiveFrame(
      AggregatedRenderPassId::Generator& render_pass_id_generator);

  // Set `CompositorRenderPass` for all `resolved_passes_`. Each
  // `ResolvedPassData` must have been aggregated before.
  void ReuseActiveFrame();

  void RegisterWithResourceProvider();
  void MovePersistentPassDataFromPreviousFrame(
      const std::vector<ResolvedPassData>& previoius_resolved_passes);

  void ComputeOffsetTagContainingRects();
  void RebuildRenderPassesForOffsetTags();
  void RecomputeOffsetTagDamage();

  const raw_ptr<DisplayResourceProvider> resource_provider_;
  const SurfaceId surface_id_;
  const raw_ptr<Surface> surface_;

  // Child resource ID assigned by `resource_provider_`.
  int child_resource_id_ = 0;

  // Data associated with CompositorFrame with |frame_index_|.
  bool valid_ = false;
  uint64_t frame_index_ = kInvalidFrameIndex;
  uint64_t previous_frame_index_ = kInvalidFrameIndex;

  base::flat_map<OffsetTag, OffsetTagData> offset_tag_data_;
  // Additional damage that is due to OffsetTag changes between aggregations
  // that is unioned into the surface damage.
  gfx::Rect offset_tag_added_damage_;
  bool has_non_zero_offset_tag_value_ = false;

  // Holds a modified copy of render passes from current active CompositorFrame.
  std::vector<std::unique_ptr<CompositorRenderPass>> offset_tag_render_passes_;

  std::vector<ResolvedPassData> resolved_passes_;
  base::flat_map<CompositorRenderPassId,
                 raw_ptr<ResolvedPassData, CtnExperimental>>
      render_pass_id_map_;
  base::flat_map<CompositorRenderPassId, AggregatedRenderPassId>
      aggregated_id_map_;

  const AggregatedRenderPassId prev_root_pass_id_;

  // Track if the this resolved frame was used this aggregation.
  bool used_in_aggregation_ = false;
};

}  // namespace viz

#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_RESOLVED_FRAME_DATA_H_