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

media / gpu / android / surface_chooser_helper.h [blame]

// Copyright 2017 The Chromium Authors
// 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 <optional>

#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "media/base/video_transformation.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_secure_only| causes us to use overlays only if required for secure
  // video playback.
  // |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_secure_only,
      bool always_use_texture_owner,
      std::unique_ptr<PromotionHintAggregator> promotion_hint_aggregator =
          nullptr,
      const base::TickClock* tick_clock = nullptr);

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

  ~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(std::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_;

  raw_ptr<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;
};

}  // namespace media

#endif  // MEDIA_GPU_ANDROID_SURFACE_CHOOSER_HELPER_H_