Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(834)

Unified Diff: webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h

Issue 2099123002: [Chromoting] Improve DirectX capturer to support multiple outputs (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Use a self-incremented integer to identify a DxgiDuplicatorContaienr::Initialize Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..65f6d91288f96add59bd0b30d8a23474b7bbaa16
--- /dev/null
+++ b/webrtc/modules/desktop_capture/win/dxgi_duplicator_container.h
@@ -0,0 +1,159 @@
+/*
+ * 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"
+#include "webrtc/modules/desktop_capture/win/dxgi_context.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.
+//
+// Consumers should create a DxgiContext and keep it through their lifetime.
+// Calls Prepare() function with the DxgiContext before each Duplicate()
+// function calls. If a previous Prepare() function call returns true, but a
+// later one 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 be various.)
+//
+// This implementation is typically for ScreenCapturer(s) with double buffering,
+// such as ScreenCapturerWinDirectx. And 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.
+class DxgiDuplicatorContainer {
Sergey Ulanov 2016/07/28 22:15:32 Maybe call this DxgiDuplicatorController to make t
Hzj_jie 2016/07/29 02:12:23 Done.
+ 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 and updates |context|. This function equals
+ // to call Prepare() and Setup(DxgiContext*) sequentially.
+ bool Prepare(DxgiContext* context);
+
+ // 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.
+ 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(DxgiContext* context,
+ 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(DxgiContext* context,
+ 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:
+ // DxgiContext calls private Unregister(DxgiContext*) function during
+ // destructing.
+ friend class DxgiContext;
+
+ // 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;
+
+ // A private constructor to ensure consumers to use
+ // DxgiDuplicatorContainer::Instance().
+ DxgiDuplicatorContainer();
+
+ // A helper function to check whether a DxgiContext has been expired. This
+ // function should be called in lock_ locked scope.
+ bool DxgiContextExpired(const DxgiContext* const context) const;
+
+ // Updates DxgiContext if needed.
+ void Setup(DxgiContext* context);
+
+ // Unregisters DxgiContext from this instance and all DxgiAdapterDuplicator(s)
+ // it owns.
+ void Unregister(const DxgiContext* const context);
+
+ // Does the real initialization work.
+ 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_;
+
+ // A self-incremented integer to compare with the one in DxgiContext, to
+ // ensure a DxgiContext has been initialized after DxgiDuplicatorContainer.
+ int identity_ = 0;
+ DesktopRect desktop_rect_;
+ DesktopVector dpi_;
+ std::vector<DxgiAdapterDuplicator> duplicators_;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_H_

Powered by Google App Engine
This is Rietveld 408576698