From f9e9be6d9dcc7c558a7e4bdd2e8905614f1defe8 Mon Sep 17 00:00:00 2001 From: huiyadanli Date: Fri, 23 Feb 2024 22:55:31 +0800 Subject: [PATCH] add WindowsGraphicsCapture cache option --- BetterGenshinImpact/Core/Config/AllConfig.cs | 7 +++ .../GameTask/TaskTriggerDispatcher.cs | 7 ++- .../View/CaptureTestWindow.xaml.cs | 9 +++- BetterGenshinImpact/View/Pages/HomePage.xaml | 27 ++++++++++ Fischless.GameCapture/BitBlt/BitBltCapture.cs | 2 +- .../DwmSharedSurface/SharedSurfaceCapture.cs | 2 +- .../Graphics/GraphicsCapture.cs | 53 ++++++++++++------- Fischless.GameCapture/IGameCapture.cs | 2 +- 8 files changed, 84 insertions(+), 25 deletions(-) diff --git a/BetterGenshinImpact/Core/Config/AllConfig.cs b/BetterGenshinImpact/Core/Config/AllConfig.cs index daa44000..2146ac0b 100644 --- a/BetterGenshinImpact/Core/Config/AllConfig.cs +++ b/BetterGenshinImpact/Core/Config/AllConfig.cs @@ -45,6 +45,13 @@ namespace BetterGenshinImpact.Core.Config /// [ObservableProperty] private bool _detailedErrorLogs = false; + /// + /// WGC使用位图缓存 + /// 高帧率情况下,可能会导致卡顿 + /// 云原神可能会出现黑屏 + /// + [ObservableProperty] private bool _wgcUseBitmapCache = true; + /// /// 遮罩窗口配置 /// diff --git a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs index 99a32cff..9127e1ed 100644 --- a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs +++ b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs @@ -105,7 +105,12 @@ namespace BetterGenshinImpact.GameTask _triggers = GameTaskManager.LoadTriggers(); // 启动截图 - GameCapture.Start(hWnd); + GameCapture.Start(hWnd, + new Dictionary() + { + { "useBitmapCache", TaskContext.Instance().Config.WgcUseBitmapCache } + } + ); // 捕获模式初始化配置 if (TaskContext.Instance().Config.CommonConfig.ScreenshotEnabled) diff --git a/BetterGenshinImpact/View/CaptureTestWindow.xaml.cs b/BetterGenshinImpact/View/CaptureTestWindow.xaml.cs index 0e02f8a9..627f3e63 100644 --- a/BetterGenshinImpact/View/CaptureTestWindow.xaml.cs +++ b/BetterGenshinImpact/View/CaptureTestWindow.xaml.cs @@ -1,8 +1,10 @@ using BetterGenshinImpact.Helpers.Extensions; using System; +using System.Collections.Generic; using System.Diagnostics; using System.Windows; using System.Windows.Media; +using BetterGenshinImpact.GameTask; using Fischless.GameCapture; namespace BetterGenshinImpact.View @@ -47,7 +49,12 @@ namespace BetterGenshinImpact.View _capture = GameCaptureFactory.Create(captureMode); //_capture.IsClientEnabled = true; - _capture.Start(hWnd); + _capture.Start(hWnd, + new Dictionary() + { + { "useBitmapCache", TaskContext.Instance().Config.WgcUseBitmapCache } + } + ); CompositionTarget.Rendering += Loop; } diff --git a/BetterGenshinImpact/View/Pages/HomePage.xaml b/BetterGenshinImpact/View/Pages/HomePage.xaml index 7e157aab..19dfa90f 100644 --- a/BetterGenshinImpact/View/Pages/HomePage.xaml +++ b/BetterGenshinImpact/View/Pages/HomePage.xaml @@ -161,6 +161,33 @@ Text="{Binding Config.TriggerInterval, Mode=TwoWay}" /> + + + + + + + + + + + + + + diff --git a/Fischless.GameCapture/BitBlt/BitBltCapture.cs b/Fischless.GameCapture/BitBlt/BitBltCapture.cs index 137557f3..454a224f 100644 --- a/Fischless.GameCapture/BitBlt/BitBltCapture.cs +++ b/Fischless.GameCapture/BitBlt/BitBltCapture.cs @@ -13,7 +13,7 @@ public class BitBltCapture : IGameCapture public void Dispose() => Stop(); - public void Start(nint hWnd) + public void Start(nint hWnd, Dictionary? settings = null) { _hWnd = hWnd; IsCapturing = true; diff --git a/Fischless.GameCapture/DwmSharedSurface/SharedSurfaceCapture.cs b/Fischless.GameCapture/DwmSharedSurface/SharedSurfaceCapture.cs index 8ea02f90..b5f59828 100644 --- a/Fischless.GameCapture/DwmSharedSurface/SharedSurfaceCapture.cs +++ b/Fischless.GameCapture/DwmSharedSurface/SharedSurfaceCapture.cs @@ -21,7 +21,7 @@ namespace Fischless.GameCapture.DwmSharedSurface public CaptureModes Mode => CaptureModes.DwmGetDxSharedSurface; - public void Start(nint hWnd) + public void Start(nint hWnd, Dictionary? settings = null) { _hWnd = hWnd; User32.ShowWindow(hWnd, ShowWindowCommand.SW_RESTORE); diff --git a/Fischless.GameCapture/Graphics/GraphicsCapture.cs b/Fischless.GameCapture/Graphics/GraphicsCapture.cs index 02336f39..31c86f77 100644 --- a/Fischless.GameCapture/Graphics/GraphicsCapture.cs +++ b/Fischless.GameCapture/Graphics/GraphicsCapture.cs @@ -21,11 +21,12 @@ public class GraphicsCapture : IGameCapture private ResourceRegion? _region; + private bool _useBitmapCache = false; private Bitmap? _currentBitmap; public void Dispose() => Stop(); - public void Start(nint hWnd) + public void Start(nint hWnd, Dictionary? settings = null) { _hWnd = hWnd; @@ -46,7 +47,13 @@ public class GraphicsCapture : IGameCapture _captureFramePool = Direct3D11CaptureFramePool.Create(device, DirectXPixelFormat.B8G8R8A8UIntNormalized, 2, _captureItem.Size); - // _captureFramePool.FrameArrived += OnFrameArrived; + + if (settings != null && settings.TryGetValue("useBitmapCache", out object? value) && (bool)value) + { + _useBitmapCache = true; + _captureFramePool.FrameArrived += OnFrameArrived; + } + _captureSession = _captureFramePool.CreateCaptureSession(_captureItem); _captureSession.IsCursorCaptureEnabled = false; if (ApiInformation.IsWriteablePropertyPresent("Windows.Graphics.Capture.GraphicsCaptureSession", "IsBorderRequired")) @@ -109,29 +116,35 @@ public class GraphicsCapture : IGameCapture return null; } - try + if (!_useBitmapCache) { - using var frame = _captureFramePool?.TryGetNextFrame(); - - if (frame == null) + try + { + using var frame = _captureFramePool?.TryGetNextFrame(); + + if (frame == null) + { + return null; + } + + return frame.ToBitmap(_region); + } + catch (Exception e) + { + Debug.WriteLine(e); + } + + return null; + } + else + { + if (_currentBitmap == null) { return null; } - - return frame.ToBitmap(_region); - } - catch (Exception e) - { - Debug.WriteLine(e); - } - - return null; - // if (_currentBitmap == null) - // { - // return null; - // } - // return (Bitmap)_currentBitmap.Clone(); + return (Bitmap)_currentBitmap.Clone(); + } } public void Stop() diff --git a/Fischless.GameCapture/IGameCapture.cs b/Fischless.GameCapture/IGameCapture.cs index 46a2e786..d6922cf2 100644 --- a/Fischless.GameCapture/IGameCapture.cs +++ b/Fischless.GameCapture/IGameCapture.cs @@ -5,7 +5,7 @@ public interface IGameCapture : IDisposable public CaptureModes Mode { get; } public bool IsCapturing { get; } - public void Start(nint hWnd); + public void Start(nint hWnd, Dictionary? settings = null); public Bitmap? Capture();