File: overlay_processor_using_strategy.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 (306 lines) | stat: -rw-r--r-- 12,945 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
// Copyright 2019 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_OVERLAY_PROCESSOR_USING_STRATEGY_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_USING_STRATEGY_H_

#include <map>
#include <memory>
#include <optional>
#include <unordered_map>
#include <vector>

#include "base/hash/hash.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/viz/common/quads/aggregated_render_pass.h"
#include "components/viz/common/quads/quad_list.h"
#include "components/viz/service/display/aggregated_frame.h"
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/display/overlay_candidate.h"
#include "components/viz/service/display/overlay_candidate_temporal_tracker.h"
#include "components/viz/service/display/overlay_combination_cache.h"
#include "components/viz/service/display/overlay_processor_interface.h"
#include "components/viz/service/display/overlay_processor_strategy.h"
#include "components/viz/service/display/overlay_proposed_candidate.h"
#include "components/viz/service/viz_service_export.h"
#include "gpu/ipc/common/surface_handle.h"
#include "third_party/skia/include/core/SkM44.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/overlay_transform.h"

#if BUILDFLAG(IS_CHROMEOS)
// TODO(b/181974042):  Remove when color space is plumbed.
#include "ui/gfx/color_space.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

namespace viz {

class DisplayResourceProvider;

// OverlayProcessor subclass that goes through a list of strategies to determine
// overlay candidates. This is used by Android and Ozone platforms.
class VIZ_SERVICE_EXPORT OverlayProcessorUsingStrategy
    : public OverlayProcessorInterface {
 public:
  using CandidateList = OverlayCandidateList;

  OverlayProcessorUsingStrategy(const OverlayProcessorUsingStrategy&) = delete;
  OverlayProcessorUsingStrategy& operator=(
      const OverlayProcessorUsingStrategy&) = delete;

  ~OverlayProcessorUsingStrategy() override;

  gfx::Rect GetAndResetOverlayDamage() final;

  // Override OverlayProcessor.
  void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
  void SetViewportSize(const gfx::Size& size) override {}
  void SetFrameSequenceNumber(uint64_t frame_sequence_number_) override;
  // Attempts to replace quads from the specified root render pass with
  // overlays. This must be called every frame.
  void ProcessForOverlays(
      DisplayResourceProvider* resource_provider,
      AggregatedRenderPassList* render_passes,
      const SkM44& output_color_matrix,
      const FilterOperationsMap& render_pass_filters,
      const FilterOperationsMap& render_pass_backdrop_filters,
      SurfaceDamageRectList surface_damage_rect_list,
      OutputSurfaceOverlayPlane* output_surface_plane,
      CandidateList* overlay_candidates,
      gfx::Rect* damage_rect,
      std::vector<gfx::Rect>* content_bounds)
      // TODO(petermcneeley) : Restore to "final" once
      // |OverlayProcessorDelegated| has been reintegrated into
      // |OverlayProcessorOzone|.
      override;

  // This function takes a pointer to the std::optional instance so the
  // instance can be reset. When overlay strategy covers the entire output
  // surface, we no longer need the output surface as a separate overlay. This
  // is also used by SurfaceControl to adjust rotation.
  // TODO(weiliangc): Internalize the |output_surface_plane| inside the overlay
  // processor.
  void AdjustOutputSurfaceOverlay(
      std::optional<OutputSurfaceOverlayPlane>* output_surface_plane) override;

  OverlayProcessorUsingStrategy();

  // A list of possible overlay candidates is presented to this function.
  // The expected result is that those candidates that can be in a separate
  // plane are marked with |overlay_handled| set to true, otherwise they are
  // to be traditionally composited. Candidates with |overlay_handled| set to
  // true must also have their |display_rect| converted to integer
  // coordinates if necessary.
  void CheckOverlaySupport(
      const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
      OverlayCandidateList* candidate_list);

  // Clears the cache of attempted overlay combinations and their results.
  void ClearOverlayCombinationCache();

  // This should be called during overlay processing to register whether or not
  // there is a candidate that requires an overlay so that the manager can allow
  // the overlay on the display with the requirement only.
  virtual void RegisterOverlayRequirement(bool requires_overlay) {}

  // Disable overlay if there has been a copy request in the last 10 frames
  // 10 was chosen because worst case the copy request might be 15 fps and
  // we might have display with 120 Hz.
  static const int kCopyRequestSkipOverlayFrames = 10;

  const std::unordered_map<ProposedCandidateKey,
                           OverlayCandidateTemporalTracker,
                           ProposedCandidateKeyHasher>&
  GetTrackedCandidatesForTesting() const {
    return tracked_candidates_;
  }

 protected:
  virtual gfx::Rect GetOverlayDamageRectForOutputSurface(
      const OverlayCandidate& overlay) const;

  std::vector<std::unique_ptr<OverlayProcessorStrategy>> strategies_;
  raw_ptr<OverlayProcessorStrategy> last_successful_strategy_ = nullptr;

  gfx::Rect overlay_damage_rect_;
  gfx::Rect previous_frame_overlay_rect_;

  struct OverlayPrioritizationConfig {
    // Threshold criteria required for a proposed candidate to be considered for
    // overlay promotion
    bool changing_threshold = true;
    bool damage_rate_threshold = true;

    // Sorting criteria that determines the relative order of consideration for
    // a overlay candidate.
    bool power_gain_sort = true;
  };

  OverlayPrioritizationConfig prioritization_config_;
  OverlayCandidateTemporalTracker::Config tracker_config_;

  // This is controlled by the "UseMultipleOverlays" feature's "max_overlays"
  // param.
  const int max_overlays_config_;
  // This will remain 1 until hardware support for more than one overlay is
  // confirmed in `OverlayProcessorOzone::ReceiveHardwareCapabilities`.
  int max_overlays_considered_ = 1;

#if BUILDFLAG(IS_CHROMEOS)
 protected:
  // TODO(b/181974042):  Remove when color space is plumbed.
  gfx::ColorSpace primary_plane_color_space_;
#endif

 private:
  // Keeps track of overlay information needed to update damage correctly.
  struct OverlayStatus;
  using OverlayStatusMap = std::map<gfx::Rect, OverlayStatus>;

  struct OverlayStatus {
    OverlayStatus() = delete;
    OverlayStatus(const OverlayCandidate& candidate,
                  const gfx::Rect& key,
                  const OverlayStatusMap& prev_overlays);
    OverlayStatus(const OverlayStatus&);
    OverlayStatus& operator=(const OverlayStatus&);
    ~OverlayStatus();

    gfx::Rect overlay_rect;
    gfx::RectF damage_rect;
    uint32_t damage_index;
    float damage_area_estimate;
    bool has_mask_filter;
    int plane_z_order;
    bool is_underlay;
    bool is_opaque;
    bool is_new;
    bool prev_was_opaque;
    bool prev_was_underlay;
    bool prev_has_mask_filter;
  };

  // The platform specific implementation to check overlay support that will be
  // called by `CheckOverlaySupport()`.
  virtual void CheckOverlaySupportImpl(
      const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
      OverlayCandidateList* candidate_list) = 0;

  // Updates |damage_rect| by removing damage caused by overlays.
  void UpdateDamageRect(const SurfaceDamageRectList& surface_damage_rect_list,
                        gfx::Rect& damage_rect);
  gfx::Rect ComputeDamageExcludingOverlays(
      const SurfaceDamageRectList& surface_damage_rect_list,
      const gfx::Rect& existing_damage);

  // Iterates through a list of strategies and attempts to overlay with each.
  // Returns true if one of the attempts is successful. Has to be called after
  // InitializeStrategies(). A |primary_plane| represents the output surface's
  // buffer that comes from |BufferQueue|. It is passed in here so it could be
  // pass through to hardware through CheckOverlaySupport. It is not passed
  // through as a const member because the underlay strategy changes the
  // |primary_plane|'s blending setting.
  bool AttemptWithStrategies(
      const SkM44& output_color_matrix,
      const OverlayProcessorInterface::FilterOperationsMap& render_pass_filters,
      const OverlayProcessorInterface::FilterOperationsMap&
          render_pass_backdrop_filters,
      const DisplayResourceProvider* resource_provider,
      AggregatedRenderPassList* render_pass_list,
      SurfaceDamageRectList* surface_damage_rect_list,
      OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
      OverlayCandidateList* candidates,
      std::vector<gfx::Rect>* content_bounds,
      gfx::Rect* incoming_damage);

  // Skips overlay when we have recently had copy output requests
  // on root render pass to avoid flickering during screen capture
  bool BlockForCopyRequests(const AggregatedRenderPass* root_render_pass);

  // Determines if we should attempt multiple overlays. This is based on
  // `max_overlays_considered_`, the strategies proposed, and if any of the
  // candidates require an overlay.
  bool ShouldAttemptMultipleOverlays(
      const std::vector<OverlayProposedCandidate>& sorted_candidates);

  // Attempts to promote multiple candidates to overlays. Returns a boolean
  // indicating if any of the attempted candidates were successfully promoted to
  // overlays.
  //
  // TODO(khaslett): Write unit tests for this function before launching
  // UseMultipleOverlays feature.
  bool AttemptMultipleOverlays(
      const std::vector<OverlayProposedCandidate>& sorted_candidates,
      OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
      AggregatedRenderPass* render_pass,
      OverlayCandidateList& candidates);

  // Assigns `plane_z_order`s to the proposed underlay candidates based on their
  // DrawQuad orderings.
  //
  // TODO(khaslett): Write unit tests for this function before launching
  // UseMultipleOverlays feature.
  void AssignUnderlayZOrders(
      std::vector<std::vector<OverlayProposedCandidate>::iterator>&
          underlay_iters);

  // This function reorders and removes |proposed_candidates| based on a
  // heuristic designed to maximize the effectiveness of the limited number
  // of Hardware overlays. Effectiveness here is primarily about power and
  // secondarily about of performance.
  virtual void SortProposedOverlayCandidates(
      std::vector<OverlayProposedCandidate>* proposed_candidates);

  // Used by Android pre-SurfaceControl to notify promotion hints, and by
  // Ozone to notify overlay manager what overlays are actually promoted.
  virtual void NotifyOverlayPromotion(
      DisplayResourceProvider* display_resource_provider,
      const OverlayCandidateList& candidate_list,
      const QuadList& quad_list);

  // Used to update |min_working_scale_| and |max_failed_scale_|. |scale_factor|
  // should be the src->dst scaling amount that is < 1.0f and |success| should
  // be whether that scaling worked or not.
  void UpdateDownscalingCapabilities(float scale_factor, bool success);

  // Moves `curr_overlays` into `prev_overlays`, and updates `curr_overlays` to
  // reflect the overlays that will be promoted this frame in `candidates`.
  void UpdateOverlayStatusMap(const OverlayCandidateList& candidates);

  std::unordered_map<ProposedCandidateKey,
                     OverlayCandidateTemporalTracker,
                     ProposedCandidateKeyHasher>
      tracked_candidates_;

  // These variables are used only for UMA purposes.
  void OnOverlaySwitchUMA(ProposedCandidateKey overlay_tracking_key);
  base::TimeTicks last_time_interval_switch_overlay_tick_;
  ProposedCandidateKey prev_overlay_tracking_id_;
  uint64_t frame_sequence_number_ = 0;

  // These values are used for tracking how much we can downscale with overlays
  // and is used for when we require an overlay so we can determine how much we
  // can downscale without failing.
  float min_working_scale_ = 1.0f;
  float max_failed_scale_ = 0.0f;

  // These keep track of the status of promoted overlays from one frame to the
  // next. These maps are updated by calling UpdateOverlayStatusMap(), and are
  // used by UpdateDamageRect() to update damage properly.
  OverlayStatusMap prev_overlays_;
  OverlayStatusMap curr_overlays_;

  OverlayCombinationCache overlay_combination_cache_;

  // Used to count the number of frames we should wait until enabling overlay
  // again.
  int copy_request_counter_ = 0;
};

}  // namespace viz

#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_USING_STRATEGY_H_