add WindowsGraphicsCapture cache option

This commit is contained in:
huiyadanli 2024-02-23 22:55:31 +08:00
parent fbc5a3ced9
commit f9e9be6d9d
8 changed files with 84 additions and 25 deletions

View File

@ -45,6 +45,13 @@ namespace BetterGenshinImpact.Core.Config
/// </summary>
[ObservableProperty] private bool _detailedErrorLogs = false;
/// <summary>
/// WGC使用位图缓存
/// 高帧率情况下,可能会导致卡顿
/// 云原神可能会出现黑屏
/// </summary>
[ObservableProperty] private bool _wgcUseBitmapCache = true;
/// <summary>
/// 遮罩窗口配置
/// </summary>

View File

@ -105,7 +105,12 @@ namespace BetterGenshinImpact.GameTask
_triggers = GameTaskManager.LoadTriggers();
// 启动截图
GameCapture.Start(hWnd);
GameCapture.Start(hWnd,
new Dictionary<string, object>()
{
{ "useBitmapCache", TaskContext.Instance().Config.WgcUseBitmapCache }
}
);
// 捕获模式初始化配置
if (TaskContext.Instance().Config.CommonConfig.ScreenshotEnabled)

View File

@ -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<string, object>()
{
{ "useBitmapCache", TaskContext.Instance().Config.WgcUseBitmapCache }
}
);
CompositionTarget.Rendering += Loop;
}

View File

@ -161,6 +161,33 @@
Text="{Binding Config.TriggerInterval, Mode=TwoWay}" />
</Grid>
<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="WindowsGraphicsCapture 截图方式启用位图缓存"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="云原神出现获取到黑屏图案、原神出现掉帧的情况请尝试关闭此功能"
TextWrapping="Wrap" />
<ui:ToggleSwitch
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
IsChecked="{Binding Config.WgcUseBitmapCache, Mode=TwoWay}" />
</Grid>
<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />

View File

@ -13,7 +13,7 @@ public class BitBltCapture : IGameCapture
public void Dispose() => Stop();
public void Start(nint hWnd)
public void Start(nint hWnd, Dictionary<string, object>? settings = null)
{
_hWnd = hWnd;
IsCapturing = true;

View File

@ -21,7 +21,7 @@ namespace Fischless.GameCapture.DwmSharedSurface
public CaptureModes Mode => CaptureModes.DwmGetDxSharedSurface;
public void Start(nint hWnd)
public void Start(nint hWnd, Dictionary<string, object>? settings = null)
{
_hWnd = hWnd;
User32.ShowWindow(hWnd, ShowWindowCommand.SW_RESTORE);

View File

@ -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<string, object>? 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()

View File

@ -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<string, object>? settings = null);
public Bitmap? Capture();