提交 65f81105 编写于 作者: W Wouter 提交者: jp9000

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
上级 ed917657
......@@ -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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册