123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728 |
- #include "winrt-capture.h"
- extern "C" EXPORT BOOL winrt_capture_supported()
- try {
- /* no contract for IGraphicsCaptureItemInterop, verify 10.0.18362.0 */
- return winrt::Windows::Foundation::Metadata::ApiInformation::
- IsApiContractPresent(L"Windows.Foundation.UniversalApiContract",
- 8);
- } catch (const winrt::hresult_error &err) {
- blog(LOG_ERROR, "winrt_capture_supported (0x%08X): %s",
- err.code().value, winrt::to_string(err.message()).c_str());
- return false;
- } catch (...) {
- blog(LOG_ERROR, "winrt_capture_supported (0x%08X)",
- winrt::to_hresult().value);
- return false;
- }
- extern "C" EXPORT BOOL winrt_capture_cursor_toggle_supported()
- try {
- return winrt::Windows::Foundation::Metadata::ApiInformation::
- IsPropertyPresent(
- L"Windows.Graphics.Capture.GraphicsCaptureSession",
- L"IsCursorCaptureEnabled");
- } catch (const winrt::hresult_error &err) {
- blog(LOG_ERROR, "winrt_capture_cursor_toggle_supported (0x%08X): %s",
- err.code().value, winrt::to_string(err.message()).c_str());
- return false;
- } catch (...) {
- blog(LOG_ERROR, "winrt_capture_cursor_toggle_supported (0x%08X)",
- winrt::to_hresult().value);
- return false;
- }
- template<typename T>
- static winrt::com_ptr<T> GetDXGIInterfaceFromObject(
- winrt::Windows::Foundation::IInspectable const &object)
- {
- auto access = object.as<Windows::Graphics::DirectX::Direct3D11::
- IDirect3DDxgiInterfaceAccess>();
- winrt::com_ptr<T> result;
- winrt::check_hresult(
- access->GetInterface(winrt::guid_of<T>(), result.put_void()));
- return result;
- }
- static bool get_client_box(HWND window, uint32_t width, uint32_t height,
- D3D11_BOX *client_box)
- {
- RECT client_rect{}, window_rect{};
- POINT upper_left{};
- /* check iconic (minimized) twice, ABA is very unlikely */
- bool client_box_available =
- !IsIconic(window) && GetClientRect(window, &client_rect) &&
- !IsIconic(window) && (client_rect.right > 0) &&
- (client_rect.bottom > 0) &&
- (DwmGetWindowAttribute(window, DWMWA_EXTENDED_FRAME_BOUNDS,
- &window_rect,
- sizeof(window_rect)) == S_OK) &&
- ClientToScreen(window, &upper_left);
- if (client_box_available) {
- const uint32_t left =
- (upper_left.x > window_rect.left)
- ? (upper_left.x - window_rect.left)
- : 0;
- client_box->left = left;
- const uint32_t top = (upper_left.y > window_rect.top)
- ? (upper_left.y - window_rect.top)
- : 0;
- client_box->top = top;
- uint32_t texture_width = 1;
- if (width > left) {
- texture_width =
- min(width - left, (uint32_t)client_rect.right);
- }
- uint32_t texture_height = 1;
- if (height > top) {
- texture_height =
- min(height - top, (uint32_t)client_rect.bottom);
- }
- client_box->right = left + texture_width;
- client_box->bottom = top + texture_height;
- client_box->front = 0;
- client_box->back = 1;
- client_box_available = (client_box->right <= width) &&
- (client_box->bottom <= height);
- }
- return client_box_available;
- }
- 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
- : sdr_format;
- }
- struct winrt_capture {
- HWND window;
- BOOL client_area;
- BOOL force_sdr;
- HMONITOR monitor;
- DXGI_FORMAT format;
- bool capture_cursor;
- BOOL cursor_visible;
- gs_texture_t *texture;
- bool texture_written;
- winrt::Windows::Graphics::Capture::GraphicsCaptureItem item{nullptr};
- winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice device{
- nullptr};
- ComPtr<ID3D11DeviceContext> context;
- winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool frame_pool{
- nullptr};
- winrt::Windows::Graphics::Capture::GraphicsCaptureSession session{
- nullptr};
- winrt::Windows::Graphics::SizeInt32 last_size;
- winrt::Windows::Graphics::Capture::GraphicsCaptureItem::Closed_revoker
- closed;
- winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool::
- FrameArrived_revoker frame_arrived;
- uint32_t texture_width;
- uint32_t texture_height;
- D3D11_BOX client_box;
- BOOL active;
- struct winrt_capture *next;
- void on_closed(
- winrt::Windows::Graphics::Capture::GraphicsCaptureItem const &,
- winrt::Windows::Foundation::IInspectable const &)
- {
- active = FALSE;
- }
- void on_frame_arrived(winrt::Windows::Graphics::Capture::
- Direct3D11CaptureFramePool const &sender,
- winrt::Windows::Foundation::IInspectable const &)
- {
- const winrt::Windows::Graphics::Capture::Direct3D11CaptureFrame
- frame = sender.TryGetNextFrame();
- const winrt::Windows::Graphics::SizeInt32 frame_content_size =
- frame.ContentSize();
- winrt::com_ptr<ID3D11Texture2D> frame_surface =
- GetDXGIInterfaceFromObject<ID3D11Texture2D>(
- frame.Surface());
- /* need GetDesc because ContentSize is not reliable */
- D3D11_TEXTURE2D_DESC desc;
- frame_surface->GetDesc(&desc);
- obs_enter_graphics();
- if (desc.Format ==
- get_pixel_format(window, monitor, force_sdr)) {
- if (!client_area ||
- get_client_box(window, desc.Width, desc.Height,
- &client_box)) {
- if (client_area) {
- texture_width = client_box.right -
- client_box.left;
- texture_height = client_box.bottom -
- client_box.top;
- } else {
- texture_width = desc.Width;
- texture_height = desc.Height;
- }
- if (texture) {
- if (texture_width !=
- gs_texture_get_width(
- texture) ||
- texture_height !=
- gs_texture_get_height(
- texture)) {
- gs_texture_destroy(texture);
- texture = nullptr;
- }
- }
- if (!texture) {
- const gs_color_format color_format =
- desc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT
- ? GS_RGBA16F
- : GS_BGRA;
- texture = gs_texture_create(
- texture_width, texture_height,
- color_format, 1, NULL, 0);
- }
- if (client_area) {
- context->CopySubresourceRegion(
- (ID3D11Texture2D *)
- gs_texture_get_obj(
- texture),
- 0, 0, 0, 0, frame_surface.get(),
- 0, &client_box);
- } else {
- /* if they gave an SRV, we could avoid this copy */
- context->CopyResource(
- (ID3D11Texture2D *)
- gs_texture_get_obj(
- texture),
- frame_surface.get());
- }
- texture_written = true;
- }
- if (frame_content_size.Width != last_size.Width ||
- frame_content_size.Height != last_size.Height) {
- format = desc.Format;
- frame_pool.Recreate(
- device,
- static_cast<
- winrt::Windows::Graphics::DirectX::
- DirectXPixelFormat>(
- format),
- 2, frame_content_size);
- last_size = frame_content_size;
- }
- } else {
- active = FALSE;
- }
- obs_leave_graphics();
- }
- };
- static struct winrt_capture *capture_list;
- static void winrt_capture_device_loss_release(void *data)
- {
- winrt_capture *capture = static_cast<winrt_capture *>(data);
- capture->active = FALSE;
- capture->frame_arrived.revoke();
- try {
- capture->frame_pool.Close();
- } catch (winrt::hresult_error &err) {
- blog(LOG_ERROR,
- "Direct3D11CaptureFramePool::Close (0x%08X): %s",
- err.code().value, winrt::to_string(err.message()).c_str());
- } catch (...) {
- blog(LOG_ERROR, "Direct3D11CaptureFramePool::Close (0x%08X)",
- winrt::to_hresult().value);
- }
- try {
- capture->session.Close();
- } catch (winrt::hresult_error &err) {
- blog(LOG_ERROR, "GraphicsCaptureSession::Close (0x%08X): %s",
- err.code().value, winrt::to_string(err.message()).c_str());
- } catch (...) {
- blog(LOG_ERROR, "GraphicsCaptureSession::Close (0x%08X)",
- winrt::to_hresult().value);
- }
- capture->session = nullptr;
- capture->frame_pool = nullptr;
- capture->context = nullptr;
- capture->device = nullptr;
- capture->item = nullptr;
- }
- static bool winrt_capture_border_toggle_supported()
- try {
- return winrt::Windows::Foundation::Metadata::ApiInformation::
- IsPropertyPresent(
- L"Windows.Graphics.Capture.GraphicsCaptureSession",
- L"IsBorderRequired");
- } catch (const winrt::hresult_error &err) {
- blog(LOG_ERROR, "winrt_capture_border_toggle_supported (0x%08X): %s",
- err.code().value, winrt::to_string(err.message()).c_str());
- return false;
- } catch (...) {
- blog(LOG_ERROR, "winrt_capture_border_toggle_supported (0x%08X)",
- winrt::to_hresult().value);
- return false;
- }
- static winrt::Windows::Graphics::Capture::GraphicsCaptureItem
- winrt_capture_create_item(IGraphicsCaptureItemInterop *const interop_factory,
- HWND window, HMONITOR monitor)
- {
- winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr};
- if (window) {
- try {
- const HRESULT hr = interop_factory->CreateForWindow(
- window,
- winrt::guid_of<ABI::Windows::Graphics::Capture::
- IGraphicsCaptureItem>(),
- reinterpret_cast<void **>(
- winrt::put_abi(item)));
- if (FAILED(hr))
- blog(LOG_ERROR, "CreateForWindow (0x%08X)", hr);
- } catch (winrt::hresult_error &err) {
- blog(LOG_ERROR, "CreateForWindow (0x%08X): %s",
- err.code().value,
- winrt::to_string(err.message()).c_str());
- } catch (...) {
- blog(LOG_ERROR, "CreateForWindow (0x%08X)",
- winrt::to_hresult().value);
- }
- } else {
- assert(monitor);
- try {
- const HRESULT hr = interop_factory->CreateForMonitor(
- monitor,
- winrt::guid_of<ABI::Windows::Graphics::Capture::
- IGraphicsCaptureItem>(),
- reinterpret_cast<void **>(
- winrt::put_abi(item)));
- if (FAILED(hr))
- blog(LOG_ERROR, "CreateForMonitor (0x%08X)",
- hr);
- } catch (winrt::hresult_error &err) {
- blog(LOG_ERROR, "CreateForMonitor (0x%08X): %s",
- err.code().value,
- winrt::to_string(err.message()).c_str());
- } catch (...) {
- blog(LOG_ERROR, "CreateForMonitor (0x%08X)",
- winrt::to_hresult().value);
- }
- }
- return item;
- }
- static void winrt_capture_device_loss_rebuild(void *device_void, void *data)
- {
- winrt_capture *capture = static_cast<winrt_capture *>(data);
- auto activation_factory = winrt::get_activation_factory<
- winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
- auto interop_factory =
- activation_factory.as<IGraphicsCaptureItemInterop>();
- winrt::Windows::Graphics::Capture::GraphicsCaptureItem item =
- winrt_capture_create_item(interop_factory.get(),
- capture->window, capture->monitor);
- if (!item)
- return;
- ID3D11Device *const d3d_device = (ID3D11Device *)device_void;
- ComPtr<IDXGIDevice> dxgi_device;
- if (FAILED(d3d_device->QueryInterface(&dxgi_device)))
- blog(LOG_ERROR, "Failed to get DXGI device");
- winrt::com_ptr<IInspectable> inspectable;
- if (FAILED(CreateDirect3D11DeviceFromDXGIDevice(dxgi_device.Get(),
- inspectable.put())))
- blog(LOG_ERROR, "Failed to get WinRT device");
- const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice
- device = inspectable.as<winrt::Windows::Graphics::DirectX::
- Direct3D11::IDirect3DDevice>();
- const winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool
- frame_pool = winrt::Windows::Graphics::Capture::
- Direct3D11CaptureFramePool::Create(
- device,
- static_cast<winrt::Windows::Graphics::DirectX::
- DirectXPixelFormat>(
- capture->format),
- 2, capture->last_size);
- const winrt::Windows::Graphics::Capture::GraphicsCaptureSession session =
- frame_pool.CreateCaptureSession(item);
- if (winrt_capture_border_toggle_supported()) {
- winrt::Windows::Graphics::Capture::GraphicsCaptureAccess::
- RequestAccessAsync(
- winrt::Windows::Graphics::Capture::
- GraphicsCaptureAccessKind::Borderless)
- .get();
- session.IsBorderRequired(false);
- }
- if (winrt_capture_cursor_toggle_supported())
- session.IsCursorCaptureEnabled(capture->capture_cursor &&
- capture->cursor_visible);
- capture->item = item;
- capture->device = device;
- d3d_device->GetImmediateContext(&capture->context);
- capture->frame_pool = frame_pool;
- capture->session = session;
- capture->frame_arrived = frame_pool.FrameArrived(
- winrt::auto_revoke,
- {capture, &winrt_capture::on_frame_arrived});
- try {
- session.StartCapture();
- capture->active = TRUE;
- } catch (winrt::hresult_error &err) {
- blog(LOG_ERROR, "StartCapture (0x%08X): %s", err.code().value,
- winrt::to_string(err.message()).c_str());
- } catch (...) {
- blog(LOG_ERROR, "StartCapture (0x%08X)",
- winrt::to_hresult().value);
- }
- }
- 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<IDXGIDevice> dxgi_device;
- HRESULT hr = d3d_device->QueryInterface(&dxgi_device);
- if (FAILED(hr)) {
- blog(LOG_ERROR, "Failed to get DXGI device");
- return nullptr;
- }
- winrt::com_ptr<IInspectable> inspectable;
- hr = CreateDirect3D11DeviceFromDXGIDevice(dxgi_device.Get(),
- inspectable.put());
- if (FAILED(hr)) {
- blog(LOG_ERROR, "Failed to get WinRT device");
- return nullptr;
- }
- auto activation_factory = winrt::get_activation_factory<
- winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
- auto interop_factory =
- activation_factory.as<IGraphicsCaptureItemInterop>();
- winrt::Windows::Graphics::Capture::GraphicsCaptureItem item =
- winrt_capture_create_item(interop_factory.get(), window,
- monitor);
- if (!item)
- return nullptr;
- const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice
- device = inspectable.as<winrt::Windows::Graphics::DirectX::
- Direct3D11::IDirect3DDevice>();
- const winrt::Windows::Graphics::SizeInt32 size = item.Size();
- 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(
- device,
- static_cast<winrt::Windows::Graphics::DirectX::
- DirectXPixelFormat>(format),
- 2, size);
- const winrt::Windows::Graphics::Capture::GraphicsCaptureSession session =
- frame_pool.CreateCaptureSession(item);
- if (winrt_capture_border_toggle_supported()) {
- winrt::Windows::Graphics::Capture::GraphicsCaptureAccess::
- RequestAccessAsync(
- winrt::Windows::Graphics::Capture::
- GraphicsCaptureAccessKind::Borderless)
- .get();
- session.IsBorderRequired(false);
- }
- /* disable cursor capture if possible since ours performs better */
- const BOOL cursor_toggle_supported =
- winrt_capture_cursor_toggle_supported();
- if (cursor_toggle_supported)
- session.IsCursorCaptureEnabled(cursor);
- 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;
- capture->cursor_visible = cursor;
- capture->item = item;
- capture->device = device;
- d3d_device->GetImmediateContext(&capture->context);
- capture->frame_pool = frame_pool;
- capture->session = session;
- capture->last_size = size;
- capture->closed = item.Closed(winrt::auto_revoke,
- {capture, &winrt_capture::on_closed});
- capture->frame_arrived = frame_pool.FrameArrived(
- winrt::auto_revoke,
- {capture, &winrt_capture::on_frame_arrived});
- capture->next = capture_list;
- capture_list = capture;
- session.StartCapture();
- capture->active = TRUE;
- gs_device_loss callbacks;
- callbacks.device_loss_release = winrt_capture_device_loss_release;
- callbacks.device_loss_rebuild = winrt_capture_device_loss_rebuild;
- callbacks.data = capture;
- gs_register_loss_callbacks(&callbacks);
- return capture;
- } catch (const winrt::hresult_error &err) {
- blog(LOG_ERROR, "winrt_capture_init (0x%08X): %s", err.code().value,
- winrt::to_string(err.message()).c_str());
- return nullptr;
- } catch (...) {
- blog(LOG_ERROR, "winrt_capture_init (0x%08X)",
- winrt::to_hresult().value);
- return nullptr;
- }
- extern "C" EXPORT struct winrt_capture *
- winrt_capture_init_window(BOOL cursor, HWND window, BOOL client_area,
- BOOL force_sdr)
- {
- 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, BOOL force_sdr)
- {
- return winrt_capture_init_internal(cursor, NULL, false, force_sdr,
- monitor);
- }
- extern "C" EXPORT void winrt_capture_free(struct winrt_capture *capture)
- {
- if (capture) {
- struct winrt_capture *current = capture_list;
- if (current == capture) {
- capture_list = capture->next;
- } else {
- struct winrt_capture *previous;
- do {
- previous = current;
- current = current->next;
- } while (current != capture);
- previous->next = current->next;
- }
- obs_enter_graphics();
- gs_unregister_loss_callbacks(capture);
- gs_texture_destroy(capture->texture);
- obs_leave_graphics();
- capture->frame_arrived.revoke();
- capture->closed.revoke();
- try {
- if (capture->frame_pool)
- capture->frame_pool.Close();
- } catch (winrt::hresult_error &err) {
- blog(LOG_ERROR,
- "Direct3D11CaptureFramePool::Close (0x%08X): %s",
- err.code().value,
- winrt::to_string(err.message()).c_str());
- } catch (...) {
- blog(LOG_ERROR,
- "Direct3D11CaptureFramePool::Close (0x%08X)",
- winrt::to_hresult().value);
- }
- try {
- if (capture->session)
- capture->session.Close();
- } catch (winrt::hresult_error &err) {
- blog(LOG_ERROR,
- "GraphicsCaptureSession::Close (0x%08X): %s",
- err.code().value,
- winrt::to_string(err.message()).c_str());
- } catch (...) {
- blog(LOG_ERROR,
- "GraphicsCaptureSession::Close (0x%08X)",
- winrt::to_hresult().value);
- }
- delete capture;
- }
- }
- extern "C" EXPORT BOOL winrt_capture_active(const struct winrt_capture *capture)
- {
- return capture->active;
- }
- extern "C" EXPORT BOOL winrt_capture_show_cursor(struct winrt_capture *capture,
- BOOL visible)
- {
- BOOL success = FALSE;
- try {
- if (capture->capture_cursor) {
- if (capture->cursor_visible != visible) {
- capture->session.IsCursorCaptureEnabled(
- visible);
- capture->cursor_visible = visible;
- }
- }
- success = TRUE;
- } catch (winrt::hresult_error &err) {
- blog(LOG_ERROR,
- "GraphicsCaptureSession::IsCursorCaptureEnabled (0x%08X): %s",
- err.code().value, winrt::to_string(err.message()).c_str());
- } catch (...) {
- blog(LOG_ERROR,
- "GraphicsCaptureSession::IsCursorCaptureEnabled (0x%08X)",
- winrt::to_hresult().value);
- }
- return success;
- }
- extern "C" EXPORT enum gs_color_space
- winrt_capture_get_color_space(const struct winrt_capture *capture)
- {
- return (capture->format == DXGI_FORMAT_R16G16B16A16_FLOAT)
- ? GS_CS_709_EXTENDED
- : GS_CS_SRGB;
- }
- extern "C" EXPORT void winrt_capture_render(struct winrt_capture *capture)
- {
- if (capture->texture_written) {
- const char *tech_name = "Draw";
- float multiplier = 1.f;
- const gs_color_space current_space = gs_get_color_space();
- if (capture->format == DXGI_FORMAT_R16G16B16A16_FLOAT) {
- switch (current_space) {
- case GS_CS_SRGB:
- case GS_CS_SRGB_16F:
- tech_name = "DrawMultiplyTonemap";
- multiplier =
- 80.f / obs_get_video_sdr_white_level();
- break;
- case GS_CS_709_EXTENDED:
- tech_name = "DrawMultiply";
- multiplier =
- 80.f / obs_get_video_sdr_white_level();
- }
- } else if (current_space == GS_CS_709_SCRGB) {
- tech_name = "DrawMultiply";
- multiplier = obs_get_video_sdr_white_level() / 80.f;
- }
- gs_effect_t *const effect =
- obs_get_base_effect(OBS_EFFECT_DEFAULT);
- gs_technique_t *tech =
- gs_effect_get_technique(effect, tech_name);
- const bool previous = gs_framebuffer_srgb_enabled();
- gs_enable_framebuffer_srgb(true);
- gs_blend_state_push();
- gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
- gs_texture_t *const texture = capture->texture;
- gs_effect_set_texture_srgb(
- gs_effect_get_param_by_name(effect, "image"), texture);
- gs_effect_set_float(gs_effect_get_param_by_name(effect,
- "multiplier"),
- multiplier);
- const size_t passes = gs_technique_begin(tech);
- for (size_t i = 0; i < passes; i++) {
- if (gs_technique_begin_pass(tech, i)) {
- gs_draw_sprite(texture, 0, 0, 0);
- gs_technique_end_pass(tech);
- }
- }
- gs_technique_end(tech);
- gs_blend_state_pop();
- gs_enable_framebuffer_srgb(previous);
- }
- }
- extern "C" EXPORT uint32_t
- winrt_capture_width(const struct winrt_capture *capture)
- {
- return capture ? capture->texture_width : 0;
- }
- extern "C" EXPORT uint32_t
- winrt_capture_height(const struct winrt_capture *capture)
- {
- return capture ? capture->texture_height : 0;
- }
- extern "C" EXPORT void winrt_capture_thread_start()
- {
- struct winrt_capture *capture = capture_list;
- void *const device = gs_get_device_obj();
- while (capture) {
- winrt_capture_device_loss_rebuild(device, capture);
- capture = capture->next;
- }
- }
- extern "C" EXPORT void winrt_capture_thread_stop()
- {
- struct winrt_capture *capture = capture_list;
- while (capture) {
- winrt_capture_device_loss_release(capture);
- capture = capture->next;
- }
- }
|