Index: webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h |
diff --git a/webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h b/webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..594aca54c4782f5140758ccef4d16c896fca0243 |
--- /dev/null |
+++ b/webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h |
@@ -0,0 +1,119 @@ |
+/* |
+ * 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 MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_H_ |
+#define MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_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 container for all the objects we need to call Windows DirectX based capture |
+// APIs. Note, one application can only have one IDXGIOutputDuplication instance |
+// per output, so this class should be singleton. |
+class DxgiDuplicatorContainer { |
+ public: |
+ // Creates or retrieves the singleton instance of DxgiDuplicatorContainer. |
+ static DxgiDuplicatorContainer* Instance(); |
+ |
+ // Destructs current instance. We need to make sure COM components and their |
+ // containers are destructed in correct order. |
+ ~DxgiDuplicatorContainer(); |
+ |
+ // Initializes all the components. Returns false if system does not support |
+ // DirectX based capture, or system resource is not enough to support to |
+ // capture all monitors. By default, only four applications can capture the |
+ // screen with DirectX based capture simultaneously. Returns true if this |
+ // instance has been initialized already. Consumers should call this function |
+ // each time before calling Duplicate functions. |
+ bool Prepare(); |
+ |
+ // 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(DesktopFrame* target, |
+ const DesktopFrame* last_frame); |
+ |
+ // Captures one screen and writes into target. If id < 0 or greater than |
+ // the total screen count of all the Duplicators, this function returns false. |
+ bool Duplicate(int id, |
+ DesktopFrame* target, |
+ const DesktopFrame* last_frame); |
+ |
+ DesktopVector dpi() const { |
+ return dpi_; |
+ } |
+ |
+ // Returns entire desktop size. |
+ DesktopRect desktop_rect() const { |
+ return 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() const { |
+ return DesktopSize(desktop_rect_.right(), desktop_rect_.bottom()); |
+ } |
+ |
+ // Returns the size of one screen. If id < 0 or greater than the total screen |
+ // count of all the Duplicators, this function returns an empty DesktopRect. |
+ DesktopRect ScreenRect(int id) const; |
+ |
+ // Returns the count of screens on the system. These screens can be retrieved |
+ // by an integer in the range of [0, ScreenCount()). |
+ int ScreenCount() const; |
+ |
+ private: |
+ // A class to allow only one thread to enter. This class is used to make sure |
+ // only one Initialize function call is being performed. |
+ class SingleEntry { |
+ public: |
+ bool Enter(); |
+ void Exit(); |
+ bool Hold() const; |
+ |
+ private: |
+ rtc::CriticalSection lock_; |
+ bool entered_ = false; |
+ }; |
+ |
+ // A helper class to execute SingleEntry::Exit in its destructor. |
+ class AutoExit; |
+ |
+ bool DoInitialize(); |
+ |
+ // Clears all COM components referred by this instance. So next Prepare() |
+ // call will eventually initialize this instance again. |
+ void Deinitialize(); |
+ |
+ rtc::CriticalSection lock_; |
+ SingleEntry initializing_; |
+ DesktopRect desktop_rect_; |
+ DesktopVector dpi_; |
+ std::vector<D3dDevice> devices_; |
+ std::vector<DxgiAdapterDuplicator> duplicators_; |
+}; |
+ |
+} // namespace webrtc |
+ |
+#endif // MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_H_ |