|
@@ -16,6 +16,7 @@
|
|
|
******************************************************************************/
|
|
|
|
|
|
#include "d3d11-subsystem.hpp"
|
|
|
+#include <map>
|
|
|
|
|
|
static inline bool get_monitor(gs_device_t *device, int monitor_idx,
|
|
|
IDXGIOutput **dxgiOutput)
|
|
@@ -55,7 +56,9 @@ void gs_duplicator::Start()
|
|
|
gs_duplicator::gs_duplicator(gs_device_t *device_, int monitor_idx)
|
|
|
: gs_obj (device_, gs_type::gs_duplicator),
|
|
|
texture (nullptr),
|
|
|
- idx (monitor_idx)
|
|
|
+ idx (monitor_idx),
|
|
|
+ refs (1),
|
|
|
+ updated (false)
|
|
|
{
|
|
|
Start();
|
|
|
}
|
|
@@ -116,13 +119,30 @@ EXPORT bool device_get_duplicator_monitor_info(gs_device_t *device,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+static std::map<int, gs_duplicator*> instances;
|
|
|
+
|
|
|
+void reset_duplicators(void)
|
|
|
+{
|
|
|
+ for (auto &pair : instances) {
|
|
|
+ pair.second->updated = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
EXPORT gs_duplicator_t *device_duplicator_create(gs_device_t *device,
|
|
|
int monitor_idx)
|
|
|
{
|
|
|
gs_duplicator *duplicator = nullptr;
|
|
|
|
|
|
+ auto it = instances.find(monitor_idx);
|
|
|
+ if (it != instances.end()) {
|
|
|
+ duplicator = it->second;
|
|
|
+ duplicator->refs++;
|
|
|
+ return duplicator;
|
|
|
+ }
|
|
|
+
|
|
|
try {
|
|
|
duplicator = new gs_duplicator(device, monitor_idx);
|
|
|
+ instances[monitor_idx] = duplicator;
|
|
|
|
|
|
} catch (const char *error) {
|
|
|
blog(LOG_DEBUG, "device_duplicator_create: %s",
|
|
@@ -140,7 +160,10 @@ EXPORT gs_duplicator_t *device_duplicator_create(gs_device_t *device,
|
|
|
|
|
|
EXPORT void gs_duplicator_destroy(gs_duplicator_t *duplicator)
|
|
|
{
|
|
|
- delete duplicator;
|
|
|
+ if (--duplicator->refs == 0) {
|
|
|
+ instances.erase(duplicator->idx);
|
|
|
+ delete duplicator;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static inline void copy_texture(gs_duplicator_t *d, ID3D11Texture2D *tex)
|
|
@@ -174,6 +197,9 @@ EXPORT bool gs_duplicator_update_frame(gs_duplicator_t *d)
|
|
|
if (!d->duplicator) {
|
|
|
return false;
|
|
|
}
|
|
|
+ if (d->updated) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
hr = d->duplicator->AcquireNextFrame(0, &info, res.Assign());
|
|
|
if (hr == DXGI_ERROR_ACCESS_LOST) {
|
|
@@ -199,6 +225,7 @@ EXPORT bool gs_duplicator_update_frame(gs_duplicator_t *d)
|
|
|
|
|
|
copy_texture(d, tex);
|
|
|
d->duplicator->ReleaseFrame();
|
|
|
+ d->updated = true;
|
|
|
return true;
|
|
|
}
|
|
|
|