From 3f57753af0ca652a07415fd02cb23f17a29961b9 Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Fri, 15 Sep 2023 08:21:18 +0000 Subject: [PATCH] use avalonia bitmap to load image for loading screen --- .../UI/ViewModels/MainWindowViewModel.cs | 15 +++++++++--- src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs | 24 +++++++++---------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs index 7146dfd7c..fc2d1500e 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs @@ -3,6 +3,7 @@ using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; using Avalonia.Media; +using Avalonia.Media.Imaging; using Avalonia.Platform.Storage; using Avalonia.Threading; using DynamicData; @@ -37,6 +38,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Image = SixLabors.ImageSharp.Image; @@ -1141,12 +1143,19 @@ namespace Ryujinx.Ava.UI.ViewModels })); } - private void PrepareLoadScreen() + private unsafe void PrepareLoadScreen() { using MemoryStream stream = new(SelectedIcon); - using var gameIconBmp = Image.Load(stream); + using var bitmap = WriteableBitmap.Decode(stream); - var dominantColor = IconColorPicker.GetFilteredColor(gameIconBmp).ToPixel(); + using var l = bitmap.Lock(); + var buffer = new byte[l.RowBytes * l.Size.Height]; + + Marshal.Copy(l.Address, buffer, 0, buffer.Length); + + var pixels = MemoryMarshal.Cast(buffer.AsSpan()); + + var dominantColor = IconColorPicker.GetFilteredColor(pixels, l.Size.Width, l.Size.Height).ToPixel(); const float ColorMultiple = 0.5f; diff --git a/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs b/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs index 4c75a5ff9..21096fdf6 100644 --- a/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs +++ b/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs @@ -36,9 +36,9 @@ namespace Ryujinx.Ava.UI.Windows } } - public static Color GetFilteredColor(Image image) + public static Color GetFilteredColor(Span image, int width, int height) { - var color = GetColor(image).ToPixel(); + var color = GetColor(image, width, height).ToPixel(); // We don't want colors that are too dark. // If the color is too dark, make it brighter by reducing the range @@ -55,18 +55,16 @@ namespace Ryujinx.Ava.UI.Windows return color; } - public static Color GetColor(Image image) + public static Color GetColor(Span image, int width, int height) { var colors = new PaletteColor[TotalColors]; var dominantColorBin = new Dictionary(); - var buffer = GetBuffer(image); - - int w = image.Width; + int w = width; int w8 = w << 8; - int h8 = image.Height << 8; + int h8 = height << 8; #pragma warning disable IDE0059 // Unnecessary assignment int xStep = w8 / ColorsPerLine; @@ -76,17 +74,17 @@ namespace Ryujinx.Ava.UI.Windows int i = 0; int maxHitCount = 0; - for (int y = 0; y < image.Height; y++) + for (int y = 0; y < height; y++) { - int yOffset = y * image.Width; + int yOffset = y * width; - for (int x = 0; x < image.Width && i < TotalColors; x++) + for (int x = 0; x < width && i < TotalColors; x++) { int offset = x + yOffset; - byte cb = buffer[offset].B; - byte cg = buffer[offset].G; - byte cr = buffer[offset].R; + byte cb = image[offset].B; + byte cg = image[offset].G; + byte cr = image[offset].R; var qck = GetQuantizedColorKey(cr, cg, cb);