summaryrefslogtreecommitdiff
path: root/chromium/media/gpu/android/surface_chooser_helper.h
blob: 5d77f8adb0861cda602e5051ab428ed8ae77d221 (plain)
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
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_GPU_ANDROID_SURFACE_CHOOSER_HELPER_H_
#define MEDIA_GPU_ANDROID_SURFACE_CHOOSER_HELPER_H_

#include <memory>

#include "base/macros.h"
#include "base/time/time.h"
#include "media/base/video_rotation.h"
#include "media/gpu/android/android_video_surface_chooser.h"
#include "media/gpu/android/promotion_hint_aggregator.h"
#include "media/gpu/media_gpu_export.h"

namespace base {
class TickClock;
}

namespace media {

// Helper class to manage state transitions for SurfaceChooser::State.  It's
// complicated and standalone enough not to be part of SurfaceChooser itself.
class MEDIA_GPU_EXPORT SurfaceChooserHelper {
 public:
  // |promotion_hint_aggregator| and |tick_clock| are for tests.  Normally, we
  // create the correct default implementations ourself.
  // |is_overlay_required| tells us to require overlays(!).
  // |promote_aggressively| causes us to use overlays whenever they're power-
  // efficient, which lets us catch fullscreen-div cases.
  // |always_use_texture_owner| forces us to always use a texture owner,
  // completely ignoring all other conditions.
  SurfaceChooserHelper(
      std::unique_ptr<AndroidVideoSurfaceChooser> surface_chooser,
      bool is_overlay_required,
      bool promote_aggressively,
      bool always_use_texture_owner,
      std::unique_ptr<PromotionHintAggregator> promotion_hint_aggregator =
          nullptr,
      const base::TickClock* tick_clock = nullptr);
  ~SurfaceChooserHelper();

  enum class SecureSurfaceMode {
    // The surface should not be secure.  This allows both overlays and
    // TextureOwner surfaces.
    kInsecure,

    // It is preferable to have a secure surface, but insecure
    // (TextureOwner) is better than failing.
    kRequested,

    // The surface must be a secure surface, and should fail otherwise.
    kRequired,
  };

  // Must match AVDAFrameInformation UMA enum.  Please do not remove or re-order
  // values, only append new ones.
  enum class FrameInformation {
    NON_OVERLAY_INSECURE = 0,
    NON_OVERLAY_L3 = 1,
    OVERLAY_L3 = 2,
    OVERLAY_L1 = 3,
    OVERLAY_INSECURE_PLAYER_ELEMENT_FULLSCREEN = 4,
    OVERLAY_INSECURE_NON_PLAYER_ELEMENT_FULLSCREEN = 5,

    // Max enum value.
    FRAME_INFORMATION_MAX = OVERLAY_INSECURE_NON_PLAYER_ELEMENT_FULLSCREEN
  };

  // The setters do not update the chooser state, since pre-M requires us to be
  // careful about the first update, since we can't change it later.

  // Notify us about the desired surface security.  Does not update the chooser
  // state.
  void SetSecureSurfaceMode(SecureSurfaceMode mode);

  // Notify us about the fullscreen state.  Does not update the chooser state.
  void SetIsFullscreen(bool is_fullscreen);

  // Notify us about the default rotation for the video.
  void SetVideoRotation(VideoRotation video_rotation);

  // Notify us about PIP state.
  void SetIsPersistentVideo(bool is_persistent_video);

  // Update the chooser state using the given factory.
  void UpdateChooserState(base::Optional<AndroidOverlayFactoryCB> new_factory);

  // Notify us about a promotion hint.  This will update the chooser state
  // if needed.
  void NotifyPromotionHintAndUpdateChooser(
      const PromotionHintAggregator::Hint& hint,
      bool is_using_overlay);

  AndroidVideoSurfaceChooser* chooser() const { return surface_chooser_.get(); }

  // Return the FrameInformation bucket number that the config reflects, given
  // that |is_using_overlay| reflects whether we're currently using an overlay
  // or not.
  FrameInformation ComputeFrameInformation(bool is_using_overlay);

 private:
  AndroidVideoSurfaceChooser::State surface_chooser_state_;
  std::unique_ptr<AndroidVideoSurfaceChooser> surface_chooser_;

  // Are overlays required by command-line options?
  bool is_overlay_required_ = false;

  // Do we require an overlay due to the surface mode?
  bool requires_secure_video_surface_ = false;

  std::unique_ptr<PromotionHintAggregator> promotion_hint_aggregator_;

  // Time since we last updated the chooser state.
  base::TimeTicks most_recent_chooser_retry_;

  const base::TickClock* tick_clock_;

  // Number of promotion hints that we need to receive before clearing the
  // "delay overlay promotion" flag in |surface_chooser_state_|.  We do this so
  // that the transition looks better, since it gives blink time to stabilize.
  // Since overlay positioning isn't synchronous, it's good to make sure that
  // blink isn't moving the quad around too.
  int hints_until_clear_relayout_flag_ = 0;

  DISALLOW_COPY_AND_ASSIGN(SurfaceChooserHelper);
};

}  // namespace media

#endif  // MEDIA_GPU_ANDROID_SURFACE_CHOOSER_HELPER_H_