Browse Source

Removed ComputeSharp and rolled back replace color to CPU

flabbet 2 years ago
parent
commit
66c5346d45

+ 0 - 2
src/ChunkyImageLib/ChunkyImageLib.csproj

@@ -9,8 +9,6 @@
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="ComputeSharp" Version="2.0.0-preview2" />
-    <PackageReference Include="ComputeSharp.Core" Version="2.0.0-preview2" />
     <PackageReference Include="OneOf" Version="3.0.223" />
     <PackageReference Include="OneOf" Version="3.0.223" />
     <PackageReference Update="StyleCop.Analyzers" Version="1.2.0-beta.435">
     <PackageReference Update="StyleCop.Analyzers" Version="1.2.0-beta.435">
       <PrivateAssets>all</PrivateAssets>
       <PrivateAssets>all</PrivateAssets>

+ 7 - 16
src/ChunkyImageLib/DataHolders/ColorBounds.cs

@@ -1,5 +1,4 @@
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
-using ComputeSharp;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 
 
 namespace ChunkyImageLib.DataHolders;
 namespace ChunkyImageLib.DataHolders;
@@ -7,12 +6,19 @@ namespace ChunkyImageLib.DataHolders;
 public struct ColorBounds
 public struct ColorBounds
 {
 {
     public float LowerR { get; set; }
     public float LowerR { get; set; }
+    
     public float LowerG { get; set; }
     public float LowerG { get; set; }
+    
     public float LowerB { get; set; }
     public float LowerB { get; set; }
+    
     public float LowerA { get; set; }
     public float LowerA { get; set; }
+    
     public float UpperR { get; set; }
     public float UpperR { get; set; }
+    
     public float UpperG { get; set; }
     public float UpperG { get; set; }
+    
     public float UpperB { get; set; }
     public float UpperB { get; set; }
+
     public float UpperA { get; set; }
     public float UpperA { get; set; }
 
 
     public ColorBounds(Color color)
     public ColorBounds(Color color)
@@ -56,20 +62,5 @@ public struct ColorBounds
             return false;
             return false;
         return true;
         return true;
     }
     }
-    
-    public readonly bool IsWithinBounds(Float4 color)
-    {
-        float r = color.R;
-        float g = color.G;
-        float b = color.B;
-        float a = color.A;
-        if (r < LowerR || r > UpperR)
-            return false;
-        if (g < LowerG || g > UpperG)
-            return false;
-        if (b < LowerB || b > UpperB)
-            return false;
-        return !(a < LowerA) && !(a > UpperA);
-    }
 }
 }
 
 

+ 23 - 23
src/ChunkyImageLib/Operations/ReplaceColorOperation.cs

@@ -1,8 +1,7 @@
 using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.DataHolders;
-using ChunkyImageLib.Shaders;
-using ComputeSharp;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.DrawingApi.Core.Surface;
 
 
 namespace ChunkyImageLib.Operations;
 namespace ChunkyImageLib.Operations;
 internal class ReplaceColorOperation : IDrawOperation
 internal class ReplaceColorOperation : IDrawOperation
@@ -11,7 +10,6 @@ internal class ReplaceColorOperation : IDrawOperation
     private readonly Color newColor;
     private readonly Color newColor;
 
 
     private readonly ColorBounds oldColorBounds;
     private readonly ColorBounds oldColorBounds;
-    private readonly HlslColorBounds oldColorBoundsHlsl;
     private readonly ulong newColorBits;
     private readonly ulong newColorBits;
 
 
     public bool IgnoreEmptyChunks => true;
     public bool IgnoreEmptyChunks => true;
@@ -21,42 +19,44 @@ internal class ReplaceColorOperation : IDrawOperation
         this.oldColor = oldColor;
         this.oldColor = oldColor;
         this.newColor = newColor;
         this.newColor = newColor;
         oldColorBounds = new ColorBounds(oldColor);
         oldColorBounds = new ColorBounds(oldColor);
-        oldColorBoundsHlsl = new HlslColorBounds(new Float4(oldColor.R, oldColor.G, oldColor.B, oldColor.A));
         newColorBits = newColor.ToULong();
         newColorBits = newColor.ToULong();
     }
     }
 
 
     public void DrawOnChunk(Chunk chunk, VecI chunkPos)
     public void DrawOnChunk(Chunk chunk, VecI chunkPos)
     {
     {
-        ReplaceColor(oldColorBoundsHlsl, newColor, chunk);
+        ReplaceColor(oldColorBounds, newColorBits, chunk);
     }
     }
 
 
-    private static void ReplaceColor(HlslColorBounds oldColorBounds, Color newColor, Chunk chunk)
+    private static unsafe void ReplaceColor(ColorBounds oldColorBounds, ulong newColorBits, Chunk chunk)
     {
     {
-        Span<UInt2> span = chunk.Surface.DrawingSurface.PeekPixels().GetPixelSpan<UInt2>();
-        using var texture = GraphicsDevice.GetDefault()
-            .AllocateReadWriteTexture2D<UInt2>(chunk.PixelSize.X, chunk.PixelSize.Y);
-
-        texture.CopyFrom(span);
-
-        UInt2 packedColor = ShaderUtils.PackPixel(newColor);
-        
-        GraphicsDevice.GetDefault().For(texture.Width, texture.Height, 1,  8, 8, 1,
-            new ReplaceColorShader(
-                texture,
-                oldColorBounds,
-                packedColor));
-        texture.CopyTo(span);
+        int maxThreads = Environment.ProcessorCount;
+        VecI imageSize = chunk.PixelSize;
+        int rowsPerThread = imageSize.Y / maxThreads;
+
+        using Pixmap pixmap = chunk.Surface.DrawingSurface.PeekPixels();
+        IntPtr pixels = pixmap.GetPixels();
+
+        Half* endOffset = (Half*)(pixels + pixmap.BytesSize);
+        for (Half* i = (Half*)pixels; i < endOffset; i += 4)
+        {
+            if (oldColorBounds.IsWithinBounds(i))
+            {
+                *(ulong*)i = newColorBits;
+            }
+        }
     }
     }
 
 
-    public HashSet<VecI> FindAffectedChunks(VecI imageSize)
+    HashSet<VecI> IDrawOperation.FindAffectedChunks(VecI imageSize)
     {
     {
         return OperationHelper.FindChunksTouchingRectangle(new RectI(VecI.Zero, imageSize), ChunkyImage.FullChunkSize);
         return OperationHelper.FindChunksTouchingRectangle(new RectI(VecI.Zero, imageSize), ChunkyImage.FullChunkSize);
     }
     }
 
 
     public IDrawOperation AsMirrored(int? verAxisX, int? horAxisY)
     public IDrawOperation AsMirrored(int? verAxisX, int? horAxisY)
     {
     {
-        return new ReplaceColorOperation(oldColor, newColor);
+        return new ReplaceColorOperation(this.oldColor, this.newColor);
     }
     }
 
 
-    public void Dispose() { }
+    public void Dispose()
+    {
+    }
 }
 }

+ 0 - 74
src/ChunkyImageLib/Shaders/ReplaceColorShader.cs

@@ -1,74 +0,0 @@
-using ComputeSharp;
-
-namespace ChunkyImageLib.Shaders;
-
-[AutoConstructor]
-[EmbeddedBytecode(8, 8, 1)]
-internal readonly partial struct ReplaceColorShader : IComputeShader
-{
-    public readonly ReadWriteTexture2D<UInt2> texture;
-    public readonly HlslColorBounds colorBounds;
-    public readonly UInt2 newColor;
-    
-    public void Execute()
-    {
-        UInt2 rgba = texture[ThreadIds.XY];
-        Float4 rgbaFloat = ShaderUtils.UnpackPixel(rgba);
-        
-        if(IsWithinBounds(rgbaFloat))
-        {
-            texture[ThreadIds.XY] = newColor;
-        }
-    }
-
-    private bool IsWithinBounds(Float4 color)
-    {
-        float r = color.R;
-        float g = color.G;
-        float b = color.B;
-        float a = color.A;
-        if (r < colorBounds.LowerR || r > colorBounds.UpperR)
-            return false;
-        if (g < colorBounds.LowerG || g > colorBounds.UpperG)
-            return false;
-        if (b < colorBounds.LowerB || b > colorBounds.UpperB)
-            return false;
-        return !(a < colorBounds.LowerA) && !(a > colorBounds.UpperA);
-    }
-}
-
-public readonly struct HlslColorBounds
-{
-    public readonly float LowerR;
-    public readonly float LowerG;
-    public readonly float LowerB;
-    public readonly float LowerA;
-    public readonly float UpperR;
-    public readonly float UpperG;
-    public readonly float UpperB;
-    public readonly float UpperA;
-
-    public HlslColorBounds(Float4 color)
-    {
-        static (float lower, float upper) FindInclusiveBoundaryPremul(float channel, float alpha)
-        {
-            float subHalf = channel > 0 ? channel - .5f : channel;
-            float addHalf = channel < 255 ? channel + .5f : channel;
-            return (subHalf * alpha / 255f, addHalf * alpha / 255f);
-        }
-
-        static (float lower, float upper) FindInclusiveBoundary(float channel)
-        {
-            float subHalf = channel > 0 ? channel - .5f : channel;
-            float addHalf = channel < 255 ? channel + .5f : channel;
-            return (subHalf / 255f, addHalf / 255f);
-        }
-
-        float a = color.A / 255f;
-
-        (LowerR, UpperR) = FindInclusiveBoundaryPremul(color.R, a);
-        (LowerG, UpperG) = FindInclusiveBoundaryPremul(color.G, a);
-        (LowerB, UpperB) = FindInclusiveBoundaryPremul(color.B, a);
-        (LowerA, UpperA) = FindInclusiveBoundary(color.A);
-    }
-}

+ 0 - 27
src/ChunkyImageLib/Shaders/ShaderUtils.cs

@@ -1,27 +0,0 @@
-using ComputeSharp;
-using PixiEditor.DrawingApi.Core.ColorsImpl;
-
-namespace ChunkyImageLib.Shaders;
-
-public static class ShaderUtils
-{
-    public static Float4 UnpackPixel(UInt2 packedPixel)
-    {
-        return new Float4(
-            Hlsl.Float16ToFloat32(packedPixel.X),
-            Hlsl.Float16ToFloat32(packedPixel.X >> 16),
-            Hlsl.Float16ToFloat32(packedPixel.Y),
-            Hlsl.Float16ToFloat32(packedPixel.Y >> 16)
-        );
-    }
-
-    public static UInt2 PackPixel(Color color)
-    {
-        uint convR = (BitConverter.HalfToUInt16Bits((Half)(color.R / 255f)));
-        uint convG = (BitConverter.HalfToUInt16Bits((Half)(color.G / 255f)));
-        uint convB = (BitConverter.HalfToUInt16Bits((Half)(color.B / 255f)));
-        uint convA = (BitConverter.HalfToUInt16Bits((Half)(color.A / 255f)));
-
-        return new UInt2(convG << 16 | convR, convB | convA << 16);
-    }
-}

+ 9 - 1
src/PixiEditor.DrawingApi.Core/Bridge/NativeObjectsImpl/IPixmapImplementation.cs

@@ -7,9 +7,17 @@ namespace PixiEditor.DrawingApi.Core.Bridge.NativeObjectsImpl;
 public interface IPixmapImplementation
 public interface IPixmapImplementation
 {
 {
     public void Dispose(IntPtr objectPointer);
     public void Dispose(IntPtr objectPointer);
+
     public IntPtr GetPixels(IntPtr objectPointer);
     public IntPtr GetPixels(IntPtr objectPointer);
-    public Span<T> GetPixelSpan<T>(Pixmap pixmap) where T : unmanaged;
+
+    public Span<T> GetPixelSpan<T>(Pixmap pixmap)
+        where T : unmanaged;
+
     public IntPtr Construct(IntPtr dataPtr, ImageInfo imgInfo);
     public IntPtr Construct(IntPtr dataPtr, ImageInfo imgInfo);
+
     public int GetWidth(Pixmap pixmap);
     public int GetWidth(Pixmap pixmap);
+
     public int GetHeight(Pixmap pixmap);
     public int GetHeight(Pixmap pixmap);
+
+    public int GetBytesSize(Pixmap pixmap);
 }
 }

+ 2 - 0
src/PixiEditor.DrawingApi.Core/Surface/Pixmap.cs

@@ -25,6 +25,8 @@ public class Pixmap : NativeObject
         get => DrawingBackendApi.Current.PixmapImplementation.GetHeight(this);
         get => DrawingBackendApi.Current.PixmapImplementation.GetHeight(this);
     }
     }
 
 
+    public int BytesSize => DrawingBackendApi.Current.PixmapImplementation.GetBytesSize(this);
+
     public override void Dispose()
     public override void Dispose()
     {
     {
         DrawingBackendApi.Current.PixmapImplementation.Dispose(ObjectPointer);
         DrawingBackendApi.Current.PixmapImplementation.Dispose(ObjectPointer);

+ 12 - 7
src/PixiEditor.DrawingApi.Skia/Implementations/SkiaPixmapImplementation.cs

@@ -8,17 +8,16 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
 {
 {
     public class SkiaPixmapImplementation : SkObjectImplementation<SKPixmap>, IPixmapImplementation
     public class SkiaPixmapImplementation : SkObjectImplementation<SKPixmap>, IPixmapImplementation
     {
     {
-        private readonly SkiaColorSpaceImplementation _colorSpaceImplementation;
-        
+        private readonly SkiaColorSpaceImplementation colorSpaceImplementation;
+
         public SkiaPixmapImplementation(SkiaColorSpaceImplementation colorSpaceImplementation)
         public SkiaPixmapImplementation(SkiaColorSpaceImplementation colorSpaceImplementation)
         {
         {
-            _colorSpaceImplementation = colorSpaceImplementation;
+            this.colorSpaceImplementation = colorSpaceImplementation;
         }
         }
-        
+
         public void Dispose(IntPtr objectPointer)
         public void Dispose(IntPtr objectPointer)
         {
         {
             ManagedInstances[objectPointer].Dispose();
             ManagedInstances[objectPointer].Dispose();
-            
             ManagedInstances.Remove(objectPointer);
             ManagedInstances.Remove(objectPointer);
         }
         }
 
 
@@ -27,7 +26,8 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
             return ManagedInstances[objectPointer].GetPixels();
             return ManagedInstances[objectPointer].GetPixels();
         }
         }
 
 
-        public Span<T> GetPixelSpan<T>(Pixmap pixmap) where T : unmanaged
+        public Span<T> GetPixelSpan<T>(Pixmap pixmap)
+            where T : unmanaged
         {
         {
             return ManagedInstances[pixmap.ObjectPointer].GetPixelSpan<T>();
             return ManagedInstances[pixmap.ObjectPointer].GetPixelSpan<T>();
         }
         }
@@ -49,10 +49,15 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
             return ManagedInstances[pixmap.ObjectPointer].Height;
             return ManagedInstances[pixmap.ObjectPointer].Height;
         }
         }
 
 
+        public int GetBytesSize(Pixmap pixmap)
+        {
+            return ManagedInstances[pixmap.ObjectPointer].BytesSize;
+        }
+
         public Pixmap CreateFrom(SKPixmap pixmap)
         public Pixmap CreateFrom(SKPixmap pixmap)
         {
         {
             ManagedInstances[pixmap.Handle] = pixmap;
             ManagedInstances[pixmap.Handle] = pixmap;
-            return new Pixmap(pixmap.Info.ToImageInfo(_colorSpaceImplementation), pixmap.GetPixels());
+            return new Pixmap(pixmap.Info.ToImageInfo(colorSpaceImplementation), pixmap.GetPixels());
         }
         }
     }
     }
 }
 }

+ 0 - 1
src/PixiEditor/Models/Controllers/KeyboardInputFilter.cs

@@ -1,6 +1,5 @@
 using System.Windows.Input;
 using System.Windows.Input;
 using PixiEditor.Models.Events;
 using PixiEditor.Models.Events;
-using TerraFX.Interop.Windows;
 
 
 namespace PixiEditor.Models.Controllers;
 namespace PixiEditor.Models.Controllers;
 #nullable enable
 #nullable enable

+ 1 - 12
src/PixiEditor/Views/UserControls/Overlays/LineToolOverlay/LineToolOverlay.cs

@@ -1,21 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
+using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Controls;
 using System.Windows.Input;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media;
 using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.DataHolders;
-using PixiEditor;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
-using PixiEditor.Views;
-using PixiEditor.Views.UserControls;
-using PixiEditor.Views.UserControls.Overlays;
-using PixiEditor.Views.UserControls.Overlays.LineToolOverlay;
 using PixiEditor.Views.UserControls.Overlays.TransformOverlay;
 using PixiEditor.Views.UserControls.Overlays.TransformOverlay;
-using TerraFX.Interop.Windows;
 
 
 namespace PixiEditor.Views.UserControls.Overlays.LineToolOverlay;
 namespace PixiEditor.Views.UserControls.Overlays.LineToolOverlay;
 internal class LineToolOverlay : Control
 internal class LineToolOverlay : Control