File: reclaimable_codec.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 (148 lines) | stat: -rw-r--r-- 4,913 bytes parent folder | download | duplicates (6)
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
// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_RECLAIMABLE_CODEC_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_RECLAIMABLE_CODEC_H_

#include <memory>

#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/prefinalizer.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/timer.h"

namespace base {
class TickClock;
}  // namespace base

namespace blink {

class CodecPressureManager;
class DOMException;
class ExecutionContext;

class MODULES_EXPORT ReclaimableCodec
    : public ExecutionContextLifecycleObserver {
  USING_PRE_FINALIZER(ReclaimableCodec, Dispose);

 public:
  // Use 1.5 minutes since some RDP clients are only ticking at 1 FPM.
  static constexpr base::TimeDelta kInactivityReclamationThreshold =
      base::Seconds(90);

  enum class CodecType {
    kDecoder,
    kEncoder,
  };

  ReclaimableCodec(CodecType, ExecutionContext*);
  ~ReclaimableCodec() override = default;

  // GarbageCollectedMixin override.
  void Trace(Visitor*) const override;

  // Apply or release pressure, if this codec is holding on to constrained
  // resources.
  void ApplyCodecPressure();
  void ReleaseCodecPressure();

  // Pre-finalizer.
  void Dispose();

  // Called by PressureManger() when we cross the pressure threshold at which
  // we should start/stop reclamation attempts.
  void SetGlobalPressureExceededFlag(bool global_pressure_exceeded);

  // Notified when throttling state is changed. May be called consecutively
  // with the same value.
  void OnLifecycleStateChanged(scheduler::SchedulingLifecycleState);

  bool is_applying_codec_pressure() const { return is_applying_pressure_; }

  // Test support.
  void SimulateCodecReclaimedForTesting();
  void SimulateActivityTimerFiredForTesting();
  void SimulateLifecycleStateForTesting(scheduler::SchedulingLifecycleState);

  bool IsReclamationTimerActiveForTesting() {
    return activity_timer_.IsActive();
  }

  bool is_backgrounded_for_testing() { return is_backgrounded_; }

  void set_tick_clock_for_testing(const base::TickClock* clock) {
    tick_clock_ = clock;
  }

 protected:
  // Pushes back the time at which |this| can be reclaimed due to inactivity.
  void MarkCodecActive();

  virtual void OnCodecReclaimed(DOMException*) = 0;

  CodecPressureManager* get_manager_for_testing() { return PressureManager(); }

  base::TimeTicks last_activity_for_testing() const { return last_activity_; }

  bool global_pressure_exceeded_for_testing() const {
    return global_pressure_exceeded_;
  }

 private:
  CodecPressureManager* PressureManager();

  // Starts the idle reclamation timer if all preconditions are met, or stops it
  // otherwise. Called when any of the following criteria change:
  //   - Global codec pressure exceeds a threshold or falls back under it.
  //   - |this| applies/releases codec pressure.
  //   - |this|'s background status changes.
  void OnReclamationPreconditionsUpdated();

  bool AreReclamationPreconditionsMet();

  void StartIdleReclamationTimer();
  void StopIdleReclamationTimer();

  void OnActivityTimerFired(TimerBase*);

  // This is used to make sure that there are two consecutive ticks of the
  // timer, before we reclaim for inactivity. This prevents immediately
  // reclaiming otherwise active codecs, right after a page suspended/resumed.
  bool last_tick_was_inactive_ = false;

  // Used to distinguish between encoder and decoder pressure.
  CodecType codec_type_;

  // Whether this codec is holding on to platform resources.
  bool is_applying_pressure_ = false;

  raw_ptr<const base::TickClock> tick_clock_;

  // Period of time after which a codec is considered to be inactive.
  base::TimeDelta inactivity_threshold_;

  base::TimeTicks last_activity_;
  HeapTaskRunnerTimer<ReclaimableCodec> activity_timer_;

  // Flag indicating if there are too many codecs according to PressureManger(),
  // and whether we should attempt to reclaim codecs.
  bool global_pressure_exceeded_ = false;

  // True iff document.visibilityState of the associated page is "hidden".
  // This includes being in bg of tab strip, minimized, or (depending on OS)
  // covered by other windows.
  bool is_backgrounded_ = false;

  // Handle to unhook from FrameOrWorkerScheduler upon destruction.
  std::unique_ptr<FrameOrWorkerScheduler::LifecycleObserverHandle>
      observer_handle_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_RECLAIMABLE_CODEC_H_