From eae2f5a6d3b4348a8b9c4ac1b6eb7073da37cfba Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Sat, 18 Sep 2021 16:16:44 +0800 Subject: [PATCH] reuse Data array from X11IconLoader.cs --- src/Avalonia.X11/X11IconLoader.cs | 8 ++--- src/Avalonia.X11/X11TrayIconImpl.cs | 45 ++++++++++++++--------------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/Avalonia.X11/X11IconLoader.cs b/src/Avalonia.X11/X11IconLoader.cs index 9a202bcf9e..093f2b12c1 100644 --- a/src/Avalonia.X11/X11IconLoader.cs +++ b/src/Avalonia.X11/X11IconLoader.cs @@ -48,8 +48,8 @@ namespace Avalonia.X11 public X11IconData(Bitmap bitmap) { - _width = Math.Min(bitmap.PixelSize.Width, 256); - _height = Math.Min(bitmap.PixelSize.Height, 256); + _width = Math.Min(bitmap.PixelSize.Width, 128); + _height = Math.Min(bitmap.PixelSize.Height, 128); _bdata = new uint[_width * _height]; fixed (void* ptr = _bdata) { @@ -57,12 +57,10 @@ namespace Avalonia.X11 iptr[0] = _width; iptr[1] = _height; } - using(var rt = AvaloniaLocator.Current.GetService().CreateRenderTarget(new[]{this})) using (var ctx = rt.CreateDrawingContext(null)) ctx.DrawBitmap(bitmap.PlatformImpl, 1, new Rect(bitmap.Size), new Rect(0, 0, _width, _height)); - Data = new UIntPtr[_width * _height + 2]; Data[0] = new UIntPtr((uint)_width); Data[1] = new UIntPtr((uint)_height); @@ -72,6 +70,8 @@ namespace Avalonia.X11 for (var x = 0; x < _width; x++) Data[r + x] = new UIntPtr(_bdata[r + x]); } + + _bdata = null; } public void Save(Stream outputStream) diff --git a/src/Avalonia.X11/X11TrayIconImpl.cs b/src/Avalonia.X11/X11TrayIconImpl.cs index caaf31862a..8fa5cea427 100644 --- a/src/Avalonia.X11/X11TrayIconImpl.cs +++ b/src/Avalonia.X11/X11TrayIconImpl.cs @@ -43,8 +43,8 @@ namespace Avalonia.X11 return new ARGB32(A, R, G, B); } } - - + + [StructLayout(LayoutKind.Explicit)] readonly struct ARGB32 { @@ -67,31 +67,30 @@ namespace Avalonia.X11 public void SetIcon(IWindowIconImpl icon) { - if (icon is X11IconData x11icon) + if (!(icon is X11IconData x11icon)) return; + + var w = (int)x11icon.Data[0]; + var h = (int)x11icon.Data[1]; + + var rx = x11icon.Data.AsSpan(2); + var pixLength = w * h; + var pixelArray = new ARGB32[pixLength]; + + for (var i = 0; i < pixLength; i++) { - var w = (int)x11icon.Data[0]; - var h = (int)x11icon.Data[1]; - - using var fb = x11icon.Lock(); - - var pixLength = w * h; - var pixelArray = new ARGB32[pixLength]; - - for (var i = 0; i < pixLength; i++) - { - var ins = new IntPtr(fb.Address.ToInt64() + i * 4); - pixelArray[i] = Marshal.PtrToStructure(ins).ToARGB32(); - } - - var pixmapBytes = MemoryMarshal.Cast(pixelArray).ToArray(); - - sni.SetIcon(new Pixmap(w, h, pixmapBytes)); + var u = rx[i].ToUInt32(); + var a = (byte)((u & 0xFF000000) >> 24); + var r = (byte)((u & 0x00FF0000) >> 16); + var g = (byte)((u & 0x0000FF00) >> 8); + var b = (byte)((u & 0x000000FF)); + pixelArray[i] = new ARGB32(a, r, g, b); } - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private int PixCoord(int x, int y, int w) => x + (y * w); + var pixmapBytes = MemoryMarshal.Cast(pixelArray).ToArray(); + sni.SetIcon(new Pixmap(w, h, pixmapBytes)); + } + public void SetIsVisible(bool visible) { }