/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
#define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_

#include <vector>

#include "webrtc/base/criticalsection.h"
#include "webrtc/modules/desktop_capture/desktop_frame.h"
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
#include "webrtc/modules/desktop_capture/desktop_region.h"
#include "webrtc/modules/desktop_capture/win/d3d_device.h"
#include "webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h"

namespace webrtc {

// A controller for all the objects we need to call Windows DirectX capture APIs
// It's a singleton because, only one IDXGIOutputDuplication instance per
// monitor is allowed per application.
//
// Consumers should create a DxgiDuplicatorController::Context and keep it
// throughout their lifetime, and pass it when calling Duplicate(). Consumers
// can also call IsSupported() to determine whether the system supports DXGI
// duplicator or not. If a previous IsSupported() function call returns true,
// but a later Duplicate() returns false, this usually means the display mode is
// changing. Consumers should retry after a while. (Typically 50 milliseconds,
// but according to hardware performance, this time may vary.)
//
// This class is normally used with double buffering, e.g. as in
// ScreenCapturerWinDirectx, but it should work with consumers with one buffer,
// i.e. consumers can always send nullptr for |last_frame|. Some minor changes
// in DxgiOutputDuplicator class are nice to have to reduce size of data to copy
// (Commented in dxgi_output_duplicator.cc). But this class won't work
// with three or more buffers, the updated region merging logic will be broken
// in such scenarios. If a consumer does have this requirement, one can always
// send a new Context instance to Duplicate() function to force duplicator to
// treat it as a new consumer.
class DxgiDuplicatorController {
 public:
  // A context to store the status of a single consumer of
  // DxgiDuplicatorController.
  class Context {
   public:
    // Unregister this Context instance from all Dxgi duplicators during
    // destructing.
    ~Context();

   private:
    friend class DxgiDuplicatorController;

    // A Context will have an exactly same |identity_| as
    // DxgiDuplicatorController, to ensure it has been correctly setted up after
    // each DxgiDuplicatorController::Initialize().
    int identity_ = 0;

    // Child DxgiAdapterDuplicator::Context belongs to this Context.
    std::vector<DxgiAdapterDuplicator::Context> contexts_;
  };

  // Returns the singleton instance of DxgiDuplicatorController.
  static DxgiDuplicatorController* Instance();

  // Destructs current instance. We need to make sure COM components and their
  // containers are destructed in correct order.
  ~DxgiDuplicatorController();

  // Detects whether the system supports DXGI based capturer.
  bool IsSupported();

  // Captures current screen and writes into target. Since we are using double
  // buffering, |last_frame|.updated_region() is used to represent the not
  // updated regions in current |target| frame, which should also be copied this
  // time.
  // TODO(zijiehe): Windows cannot guarantee the frames returned by each
  // IDXGIOutputDuplication are synchronized. But we are using a totally
  // different threading model than the way Windows suggested, it's hard to
  // synchronize them manually. But we should find a way to do it.
  bool Duplicate(Context* context,
                 const DesktopFrame* last_frame,
                 DesktopFrame* target);

  // Captures one monitor and writes into target. |monitor_id| should >= 0. If
  // |monitor_id| is greater than the total screen count of all the Duplicators,
  // this function returns false.
  bool DuplicateMonitor(Context* context,
                        int monitor_id,
                        const DesktopFrame* last_frame,
                        DesktopFrame* target);

  // Returns dpi of current system. Returns an empty DesktopVector if system
  // does not support DXGI based capturer.
  DesktopVector dpi();

  // Returns entire desktop size. Returns an empty DesktopRect if system does
  // not support DXGI based capturer.
  DesktopRect desktop_rect();

  // Returns a DesktopSize to cover entire desktop_rect. This may be different
  // than desktop_rect().size(), since top-left screen does not need to start
  // from (0, 0).
  DesktopSize desktop_size();

  // Returns the size of one screen. |monitor_id| should be >= 0. If system does
  // not support DXGI based capturer, or |monitor_id| is greater than the total
  // screen count of all the Duplicators, this function returns an empty
  // DesktopRect.
  DesktopRect ScreenRect(int id);

  // Returns the count of screens on the system. These screens can be retrieved
  // by an integer in the range of [0, ScreenCount()). If system does not
  // support DXGI based capturer, this function returns 0.
  int ScreenCount();

 private:
  // Context calls private Unregister(Context*) function during
  // destructing.
  friend class Context;

  // A private constructor to ensure consumers to use
  // DxgiDuplicatorController::Instance().
  DxgiDuplicatorController();

  // Unregisters Context from this instance and all DxgiAdapterDuplicator(s)
  // it owns.
  void Unregister(const Context* const context);

  // All functions below should be called in |lock_| locked scope.

  // If current instance has not been initialized, executes DoInitialize
  // function, and returns initialize result. Otherwise directly returns true.
  bool Initialize();

  bool DoInitialize();

  // Clears all COM components referred by this instance. So next Duplicate()
  // call will eventually initialize this instance again.
  void Deinitialize();

  // A helper function to check whether a Context has been expired.
  bool ContextExpired(const Context* const context) const;

  // Updates Context if needed.
  void Setup(Context* context);

  // Do the real duplication work. |monitor_id < 0| to capture entire screen.
  bool DoDuplicate(Context* context,
                   int monitor_id,
                   const DesktopFrame* last_frame,
                   DesktopFrame* target);

  // This lock must be locked whenever accessing any of the following objects.
  rtc::CriticalSection lock_;

  // A self-incremented integer to compare with the one in Context, to
  // ensure a Context has been initialized after DxgiDuplicatorController.
  int identity_ = 0;
  DesktopRect desktop_rect_;
  DesktopVector dpi_;
  std::vector<DxgiAdapterDuplicator> duplicators_;
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
