File: layer_tree_frame_sink_holder.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 (174 lines) | stat: -rw-r--r-- 6,277 bytes parent folder | download | duplicates (3)
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
// Copyright 2016 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_EXO_LAYER_TREE_FRAME_SINK_HOLDER_H_
#define COMPONENTS_EXO_LAYER_TREE_FRAME_SINK_HOLDER_H_

#include <memory>
#include <optional>
#include <vector>

#include "base/containers/queue.h"
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
#include "components/exo/frame_sink_resource_manager.h"
#include "components/exo/frame_timing_history.h"
#include "components/exo/wm_helper.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/quads/compositor_frame.h"

namespace viz {
struct FrameTimingDetails;
}

namespace cc::mojo_embedder {
class AsyncLayerTreeFrameSink;
}

namespace exo {

class SurfaceTreeHost;

// This class talks to CompositorFrameSink and keeps track of references to
// the contents of Buffers.
class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient,
                                 public WMHelper::LifetimeManager::Observer,
                                 public viz::BeginFrameObserverBase {
 public:
  LayerTreeFrameSinkHolder(
      SurfaceTreeHost* surface_tree_host,
      std::unique_ptr<cc::mojo_embedder::AsyncLayerTreeFrameSink> frame_sink);

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

  ~LayerTreeFrameSinkHolder() override;

  // Delete frame sink after having reclaimed and called all resource
  // release callbacks.
  // TODO(reveman): Find a better way to handle deletion of in-flight resources.
  // crbug.com/765763
  static void DeleteWhenLastResourceHasBeenReclaimed(
      std::unique_ptr<LayerTreeFrameSinkHolder> holder);

  // If a frame is submitted "now" (meaning before returning to event loop)
  // via SubmitCompositorFrame(), whether it needs full damage.
  bool NeedsFullDamageForNextFrame() const { return cached_frame_.has_value(); }
  void SubmitCompositorFrame(viz::CompositorFrame frame,
                             bool submit_now = false);
  void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id);

  // Properties of the `frame` from the last `SubmitCompositorFrame()` call,
  // either from `cached_frame_`, or `frame_sink_`.
  float LastDeviceScaleFactor() const;
  const gfx::Size& LastSizeInPixels() const;

  // Returns true if owned LayerTreeFrameSink has been lost.
  bool is_lost() const { return is_lost_; }

  FrameSinkResourceManager* resource_manager() { return &resource_manager_; }

  // Overridden from cc::LayerTreeFrameSinkClient:
  void SetBeginFrameSource(viz::BeginFrameSource* source) override;
  std::optional<viz::HitTestRegionList> BuildHitTestData() override;
  void ReclaimResources(std::vector<viz::ReturnedResource> resources) override;
  void SetTreeActivationCallback(base::RepeatingClosure callback) override {}
  void DidReceiveCompositorFrameAck() override;
  void DidPresentCompositorFrame(
      uint32_t frame_token,
      const viz::FrameTimingDetails& details) override;
  void DidLoseLayerTreeFrameSink() override;
  void OnDraw(const gfx::Transform& transform,
              const gfx::Rect& viewport,
              bool resourceless_software_draw,
              bool skip_draw) override {}
  void SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override {}
  void SetExternalTilePriorityConstraints(
      const gfx::Rect& viewport_rect,
      const gfx::Transform& transform) override {}

  void ClearPendingBeginFramesForTesting();

  void DeleteFrameTimingHistory() { frame_timing_history_.reset(); }

 private:
  struct PendingBeginFrame {
    viz::BeginFrameAck begin_frame_ack;
    base::TimeTicks send_deadline_estimate;
  };

  void ScheduleDelete();

  // WMHelper::LifetimeManager::Observer:
  void OnDestroyed() override;

  // viz::BeginFrameObserverBase:
  bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override;
  void OnBeginFrameSourcePausedChanged(bool paused) override;

  void SubmitCompositorFrameToRemote(viz::CompositorFrame* frame);

  // Discards `cached_frame_`, reclaims resources and returns failure
  // presentation feedback.
  void DiscardCachedFrame(const viz::CompositorFrame* new_frame);
  void SendDiscardedFrameNotifications(uint32_t frame_token);

  void StopProcessingPendingFrames();

  void OnSendDeadlineExpired(bool update_timer);

  // Starts timer based on estimated deadline of the first pending BeginFrame
  // request; or stops timer if there is no pending BeginFrame request.
  void UpdateSubmitFrameTimer();

  void ProcessFirstPendingBeginFrame(viz::CompositorFrame* frame);

  bool ShouldSubmitFrameNow() const;

  void ObserveBeginFrameSource(bool start);

  // Returns true if the feature AutoNeedsBeginFrame is enabled, and currently
  // we are not receiving BeginFrame requests. In this case, it is allowed to
  // submit an unsolicited frame.
  bool UnsolicitedFrameAllowed() const;

  raw_ptr<SurfaceTreeHost> surface_tree_host_;
  std::unique_ptr<cc::mojo_embedder::AsyncLayerTreeFrameSink> frame_sink_;

  FrameSinkResourceManager resource_manager_;

  std::vector<viz::ResourceId> last_frame_resources_;

  std::optional<viz::CompositorFrame> cached_frame_;

  // Resources that are submitted and still in use by the remote side.
  std::set<viz::ResourceId> in_use_resources_;

  bool is_lost_ = false;
  bool delete_pending_ = false;

  raw_ptr<WMHelper::LifetimeManager> lifetime_manager_ = nullptr;

  raw_ptr<viz::BeginFrameSource> begin_frame_source_ = nullptr;
  bool observing_begin_frame_source_ = false;

  base::queue<PendingBeginFrame> pending_begin_frames_;

  // The number of frames submitted to the remote side for which acks haven't
  // been received.
  int pending_submit_frames_ = 0;

  // A queue of discarded frame tokens for which acks and presentation feedbacks
  // haven't been sent to `surface_tree_host_`.
  base::queue<uint32_t> pending_discarded_frame_notifications_;

  base::DeadlineTimer submit_frame_timer_;

  std::optional<FrameTimingHistory> frame_timing_history_;
};

}  // namespace exo

#endif  // COMPONENTS_EXO_LAYER_TREE_FRAME_SINK_HOLDER_H_