From 1e9c74af5260c32dc24ed9b4050c3eabfd8f760d Mon Sep 17 00:00:00 2001 From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com> Date: Fri, 23 Jan 2026 21:13:40 +0100 Subject: [PATCH] Optimize bitmap rendering in PluginWindow --- src/DesktopMagic/DesktopMagic.csproj | 1 + src/DesktopMagic/Plugins/PluginWindow.xaml.cs | 66 +++++++++++++------ 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/DesktopMagic/DesktopMagic.csproj b/src/DesktopMagic/DesktopMagic.csproj index 7bdc2b6..242b72e 100644 --- a/src/DesktopMagic/DesktopMagic.csproj +++ b/src/DesktopMagic/DesktopMagic.csproj @@ -15,6 +15,7 @@ net8.0-windows7.0 win-x64 enable + true false AnyCPU;x64 diff --git a/src/DesktopMagic/Plugins/PluginWindow.xaml.cs b/src/DesktopMagic/Plugins/PluginWindow.xaml.cs index 4481c55..f6cc550 100644 --- a/src/DesktopMagic/Plugins/PluginWindow.xaml.cs +++ b/src/DesktopMagic/Plugins/PluginWindow.xaml.cs @@ -42,6 +42,9 @@ public partial class PluginWindow : Window, IPluginWindow private System.Timers.Timer? reloadDebounceTimer; private bool isReloading = false; + private WriteableBitmap? writeableBitmap; + private BitmapScalingMode lastBitmapScalingMode = BitmapScalingMode.Unspecified; + public bool IsRunning { get; private set; } = true; public PluginMetadata PluginMetadata { get; private set; } public string PluginFolderPath { get; private set; } @@ -337,22 +340,52 @@ public partial class PluginWindow : Window, IPluginWindow WindowPos.GetWindowLong(helper.Handle, WindowPos.GWL_EXSTYLE) | WindowPos.WS_EX_NOACTIVATE); } - private static BitmapSource BitmapToImageSource(Bitmap bitmap) + private void UpdateImageFromBitmap(Bitmap bitmap, BitmapScalingMode scalingMode) { - BitmapData bitmapData = bitmap.LockBits( - new Rectangle(0, 0, bitmap.Width, bitmap.Height), - ImageLockMode.ReadOnly, bitmap.PixelFormat); + BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - BitmapSource bitmapSource = BitmapSource.Create( - bitmapData.Width, bitmapData.Height, - bitmap.HorizontalResolution, bitmap.VerticalResolution, - PixelFormats.Bgra32, null, - bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride); + try + { + Dispatcher.Invoke(() => + { + if (lastBitmapScalingMode != scalingMode) + { + RenderOptions.SetBitmapScalingMode(image, scalingMode); + lastBitmapScalingMode = scalingMode; + } - bitmap.UnlockBits(bitmapData); + if (writeableBitmap == null || writeableBitmap.PixelWidth != bitmapData.Width || writeableBitmap.PixelHeight != bitmapData.Height) + { + writeableBitmap = new WriteableBitmap( + bitmapData.Width, bitmapData.Height, + bitmap.HorizontalResolution, bitmap.VerticalResolution, + PixelFormats.Bgra32, null); + image.Source = writeableBitmap; + } - bitmapSource.Freeze(); - return bitmapSource; + writeableBitmap.Lock(); + try + { + unsafe + { + Buffer.MemoryCopy( + bitmapData.Scan0.ToPointer(), + writeableBitmap.BackBuffer.ToPointer(), + writeableBitmap.BackBufferStride * writeableBitmap.PixelHeight, + bitmapData.Stride * bitmapData.Height); + } + writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, bitmapData.Width, bitmapData.Height)); + } + finally + { + writeableBitmap.Unlock(); + } + }); + } + finally + { + bitmap.UnlockBits(bitmapData); + } } private void Window_ContentRendered(object? sender, EventArgs e) @@ -826,14 +859,7 @@ public partial class PluginWindow : Window, IPluginWindow _ => BitmapScalingMode.Unspecified }; - // Update Image - BitmapSource frozenSource = BitmapToImageSource(result); - - _ = Dispatcher.BeginInvoke(() => - { - RenderOptions.SetBitmapScalingMode(image, renderOptions); - image.Source = frozenSource; - }); + UpdateImageFromBitmap(result, renderOptions); } } }