diff --git a/libobs-winrt/winrt-capture.cpp b/libobs-winrt/winrt-capture.cpp index 7c49fec71..09d5d80b0 100644 --- a/libobs-winrt/winrt-capture.cpp +++ b/libobs-winrt/winrt-capture.cpp @@ -109,19 +109,26 @@ static bool get_client_box(HWND window, uint32_t width, uint32_t height, return client_box_available; } -static DXGI_FORMAT get_pixel_format(HWND window, HMONITOR monitor) +static DXGI_FORMAT get_pixel_format(HWND window, HMONITOR monitor, + BOOL force_sdr) { + static constexpr DXGI_FORMAT sdr_format = DXGI_FORMAT_B8G8R8A8_UNORM; + + if (force_sdr) + return sdr_format; + if (window) monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST); return (monitor && gs_is_monitor_hdr(monitor)) ? DXGI_FORMAT_R16G16B16A16_FLOAT - : DXGI_FORMAT_B8G8R8A8_UNORM; + : sdr_format; } struct winrt_capture { HWND window; - bool client_area; + BOOL client_area; + BOOL force_sdr; HMONITOR monitor; DXGI_FORMAT format; @@ -177,7 +184,8 @@ struct winrt_capture { obs_enter_graphics(); - if (desc.Format == get_pixel_format(window, monitor)) { + if (desc.Format == + get_pixel_format(window, monitor, force_sdr)) { if (!client_area || get_client_box(window, desc.Width, desc.Height, &client_box)) { @@ -425,10 +433,9 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data) } } -static struct winrt_capture *winrt_capture_init_internal(BOOL cursor, - HWND window, - BOOL client_area, - HMONITOR monitor) +static struct winrt_capture * +winrt_capture_init_internal(BOOL cursor, HWND window, BOOL client_area, + BOOL force_sdr, HMONITOR monitor) try { ID3D11Device *const d3d_device = (ID3D11Device *)gs_get_device_obj(); ComPtr dxgi_device; @@ -461,7 +468,7 @@ try { device = inspectable.as(); const winrt::Windows::Graphics::SizeInt32 size = item.Size(); - const DXGI_FORMAT format = get_pixel_format(window, monitor); + const DXGI_FORMAT format = get_pixel_format(window, monitor, force_sdr); const winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool frame_pool = winrt::Windows::Graphics::Capture:: Direct3D11CaptureFramePool::Create( @@ -490,6 +497,7 @@ try { struct winrt_capture *capture = new winrt_capture{}; capture->window = window; capture->client_area = client_area; + capture->force_sdr = force_sdr; capture->monitor = monitor; capture->format = format; capture->capture_cursor = cursor && cursor_toggle_supported; @@ -530,15 +538,17 @@ try { } extern "C" EXPORT struct winrt_capture * -winrt_capture_init_window(BOOL cursor, HWND window, BOOL client_area) +winrt_capture_init_window(BOOL cursor, HWND window, BOOL client_area, + BOOL force_sdr) { - return winrt_capture_init_internal(cursor, window, client_area, NULL); + return winrt_capture_init_internal(cursor, window, client_area, + force_sdr, NULL); } extern "C" EXPORT struct winrt_capture * winrt_capture_init_monitor(BOOL cursor, HMONITOR monitor) { - return winrt_capture_init_internal(cursor, NULL, false, monitor); + return winrt_capture_init_internal(cursor, NULL, false, false, monitor); } extern "C" EXPORT void winrt_capture_free(struct winrt_capture *capture) diff --git a/libobs-winrt/winrt-capture.h b/libobs-winrt/winrt-capture.h index fff5581b9..58eb51154 100644 --- a/libobs-winrt/winrt-capture.h +++ b/libobs-winrt/winrt-capture.h @@ -12,7 +12,8 @@ extern "C" { EXPORT BOOL winrt_capture_supported(); EXPORT BOOL winrt_capture_cursor_toggle_supported(); EXPORT struct winrt_capture *winrt_capture_init_window(BOOL cursor, HWND window, - BOOL client_area); + BOOL client_area, + BOOL force_sdr); EXPORT struct winrt_capture *winrt_capture_init_monitor(BOOL cursor, HMONITOR monitor); EXPORT void winrt_capture_free(struct winrt_capture *capture); diff --git a/plugins/win-capture/data/locale/en-US.ini b/plugins/win-capture/data/locale/en-US.ini index ca2c46ae2..740394ea4 100644 --- a/plugins/win-capture/data/locale/en-US.ini +++ b/plugins/win-capture/data/locale/en-US.ini @@ -12,6 +12,7 @@ WindowCapture.Priority.Exe="Match title, otherwise find window of same executabl CaptureCursor="Capture Cursor" Compatibility="Multi-adapter Compatibility" ClientArea="Client Area" +ForceSdr="Force SDR" SLIFix="SLI/Crossfire Capture Mode (Slow)" AllowTransparency="Allow Transparency" Monitor="Display" diff --git a/plugins/win-capture/window-capture.c b/plugins/win-capture/window-capture.c index 84808bdae..26b401b69 100644 --- a/plugins/win-capture/window-capture.c +++ b/plugins/win-capture/window-capture.c @@ -21,6 +21,7 @@ #define TEXT_CAPTURE_CURSOR obs_module_text("CaptureCursor") #define TEXT_COMPATIBILITY obs_module_text("Compatibility") #define TEXT_CLIENT_AREA obs_module_text("ClientArea") +#define TEXT_FORCE_SDR obs_module_text("ForceSdr") /* clang-format on */ @@ -30,8 +31,10 @@ typedef BOOL (*PFN_winrt_capture_supported)(); typedef BOOL (*PFN_winrt_capture_cursor_toggle_supported)(); -typedef struct winrt_capture *(*PFN_winrt_capture_init_window)( - BOOL cursor, HWND window, BOOL client_area); +typedef struct winrt_capture *(*PFN_winrt_capture_init_window)(BOOL cursor, + HWND window, + BOOL client_area, + BOOL force_sdr); typedef void (*PFN_winrt_capture_free)(struct winrt_capture *capture); typedef BOOL (*PFN_winrt_capture_active)(const struct winrt_capture *capture); @@ -82,6 +85,7 @@ struct window_capture { bool cursor; bool compatibility; bool client_area; + bool force_sdr; bool use_wildcards; /* TODO */ struct dc_capture capture; @@ -204,6 +208,7 @@ static void update_settings(struct window_capture *wc, obs_data_t *s) wc->method = choose_method(method, wgc_supported, wc->class); wc->priority = (enum window_priority)priority; wc->cursor = obs_data_get_bool(s, "cursor"); + wc->force_sdr = obs_data_get_bool(s, "force_sdr"); wc->use_wildcards = obs_data_get_bool(s, "use_wildcards"); wc->compatibility = obs_data_get_bool(s, "compatibility"); wc->client_area = obs_data_get_bool(s, "client_area"); @@ -370,6 +375,7 @@ static void wc_defaults(obs_data_t *defaults) { obs_data_set_default_int(defaults, "method", METHOD_AUTO); obs_data_set_default_bool(defaults, "cursor", true); + obs_data_set_default_bool(defaults, "force_sdr", false); obs_data_set_default_bool(defaults, "compatibility", false); obs_data_set_default_bool(defaults, "client_area", true); } @@ -396,6 +402,9 @@ static void update_settings_visibility(obs_properties_t *props, p = obs_properties_get(props, "client_area"); obs_property_set_visible(p, wgc_options); + p = obs_properties_get(props, "force_sdr"); + obs_property_set_visible(p, wgc_cursor_toggle); + pthread_mutex_unlock(&wc->update_mutex); } @@ -465,6 +474,8 @@ static obs_properties_t *wc_properties(void *data) obs_properties_add_bool(ppts, "client_area", TEXT_CLIENT_AREA); + obs_properties_add_bool(ppts, "force_sdr", TEXT_FORCE_SDR); + return ppts; } @@ -608,7 +619,7 @@ static void wc_tick(void *data, float seconds) wc->capture_winrt = wc->exports.winrt_capture_init_window( wc->cursor, wc->window, - wc->client_area); + wc->client_area, wc->force_sdr); if (!wc->capture_winrt) { wc->previously_failed = true;