mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
libobs-d3d11: Allow multiple display captures of same monitor
This commit fixes a bug that occurs on Windows 8+ when two or more "Display Capture" sources are active that are configured to capture the same monitor. Only one display capture would show, while all subsequent display captures would display nothing. Closes jp9000/obs-studio#1142
This commit is contained in:
parent
ed917657eb
commit
65f81105f5
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1456,9 +1456,12 @@ void device_present(gs_device_t *device)
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void reset_duplicators(void);
|
||||
|
||||
void device_flush(gs_device_t *device)
|
||||
{
|
||||
device->context->Flush();
|
||||
reset_duplicators();
|
||||
}
|
||||
|
||||
void device_set_cull_mode(gs_device_t *device, enum gs_cull_mode mode)
|
||||
|
@ -561,6 +561,8 @@ struct gs_duplicator : gs_obj {
|
||||
ComPtr<IDXGIOutputDuplication> duplicator;
|
||||
gs_texture_2d *texture;
|
||||
int idx;
|
||||
long refs;
|
||||
bool updated;
|
||||
|
||||
void Start();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user