Add AlphaFormat to ILockedFramebuffer (#20556)
* Add AlphaFormat to ILockedFramebuffer * Update API suppressions
This commit is contained in:
committed by
GitHub
parent
3394815603
commit
4c3c9aa99f
@@ -19,6 +19,12 @@
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Platform.IReadableBitmapWithAlphaImpl</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Utilities.StringTokenizer</Target>
|
||||
@@ -55,6 +61,12 @@
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Platform.IReadableBitmapWithAlphaImpl</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Utilities.StringTokenizer</Target>
|
||||
@@ -127,6 +139,12 @@
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Media.Imaging.Bitmap.CopyPixels(Avalonia.Platform.ILockedFramebuffer,Avalonia.Platform.AlphaFormat)</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Media.StreamGeometryContext.ArcTo(Avalonia.Point,Avalonia.Size,System.Double,System.Boolean,Avalonia.Media.SweepDirection)</Target>
|
||||
@@ -229,6 +247,12 @@
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Platform.LockedFramebuffer.#ctor(System.IntPtr,Avalonia.PixelSize,System.Int32,Avalonia.Vector,Avalonia.Platform.PixelFormat,System.Action)</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Visuals.Platform.PathGeometryContext.ArcTo(Avalonia.Point,Avalonia.Size,System.Double,System.Boolean,Avalonia.Media.SweepDirection)</Target>
|
||||
@@ -481,6 +505,12 @@
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Media.Imaging.Bitmap.CopyPixels(Avalonia.Platform.ILockedFramebuffer,Avalonia.Platform.AlphaFormat)</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Media.StreamGeometryContext.ArcTo(Avalonia.Point,Avalonia.Size,System.Double,System.Boolean,Avalonia.Media.SweepDirection)</Target>
|
||||
@@ -583,6 +613,12 @@
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Platform.LockedFramebuffer.#ctor(System.IntPtr,Avalonia.PixelSize,System.Int32,Avalonia.Vector,Avalonia.Platform.PixelFormat,System.Action)</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Avalonia.Visuals.Platform.PathGeometryContext.ArcTo(Avalonia.Point,Avalonia.Size,System.Double,System.Boolean,Avalonia.Media.SweepDirection)</Target>
|
||||
@@ -853,6 +889,18 @@
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>P:Avalonia.Platform.ILockedFramebuffer.AlphaFormat</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>P:Avalonia.Platform.IReadableBitmapImpl.AlphaFormat</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>M:Avalonia.Input.Platform.IClipboard.SetDataAsync(Avalonia.Input.IAsyncDataTransfer)</Target>
|
||||
@@ -1003,6 +1051,18 @@
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>P:Avalonia.Platform.ILockedFramebuffer.AlphaFormat</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>P:Avalonia.Platform.IReadableBitmapImpl.AlphaFormat</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0006</DiagnosticId>
|
||||
<Target>M:Avalonia.OpenGL.IGlExternalSemaphore.SignalTimelineSemaphore(Avalonia.OpenGL.IGlExternalImageTexture,System.UInt64)</Target>
|
||||
@@ -1087,12 +1147,24 @@
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0008</DiagnosticId>
|
||||
<Target>T:Avalonia.Platform.IWriteableBitmapImpl</Target>
|
||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0008</DiagnosticId>
|
||||
<Target>T:Avalonia.Media.StreamGeometryContext</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0008</DiagnosticId>
|
||||
<Target>T:Avalonia.Platform.IWriteableBitmapImpl</Target>
|
||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
|
||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0009</DiagnosticId>
|
||||
<Target>T:Avalonia.Platform.Screen</Target>
|
||||
|
||||
@@ -25,10 +25,10 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
||||
Size = new PixelSize(rc.right, rc.bottom);
|
||||
ANativeWindow_lock(_window, &buffer, &rc);
|
||||
|
||||
Format = buffer.format == AndroidPixelFormat.WINDOW_FORMAT_RGB_565
|
||||
? PixelFormat.Rgb565 : PixelFormat.Rgba8888;
|
||||
(Format, AlphaFormat, RowBytes) = buffer.format == AndroidPixelFormat.WINDOW_FORMAT_RGB_565 ?
|
||||
(PixelFormat.Rgb565, AlphaFormat.Opaque, buffer.stride * 2) :
|
||||
(PixelFormat.Rgba8888, AlphaFormat.Premul, buffer.stride * 4);
|
||||
|
||||
RowBytes = buffer.stride * (Format == PixelFormat.Rgb565 ? 2 : 4);
|
||||
Address = buffer.bits;
|
||||
|
||||
Dpi = new Vector(96, 96) * scaling;
|
||||
@@ -46,6 +46,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
||||
public int RowBytes { get; }
|
||||
public Vector Dpi { get; }
|
||||
public PixelFormat Format { get; }
|
||||
public AlphaFormat AlphaFormat { get; }
|
||||
|
||||
[DllImport("android")]
|
||||
internal static extern IntPtr ANativeWindow_fromSurface(IntPtr jniEnv, IntPtr handle);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Avalonia.Platform;
|
||||
@@ -177,7 +176,7 @@ namespace Avalonia.Media.Imaging
|
||||
|
||||
public virtual PixelFormat? Format => (PlatformImpl.Item as IReadableBitmapImpl)?.Format;
|
||||
|
||||
public virtual AlphaFormat? AlphaFormat => (PlatformImpl.Item as IReadableBitmapWithAlphaImpl)?.AlphaFormat;
|
||||
public virtual AlphaFormat? AlphaFormat => (PlatformImpl.Item as IReadableBitmapImpl)?.AlphaFormat;
|
||||
|
||||
private protected unsafe void CopyPixelsCore(PixelRect sourceRect, IntPtr buffer, int bufferSize, int stride,
|
||||
ILockedFramebuffer fb)
|
||||
@@ -237,16 +236,15 @@ namespace Avalonia.Media.Imaging
|
||||
/// Copies pixels to the target buffer and transcodes the pixel and alpha format if needed.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The target buffer.</param>
|
||||
/// <param name="alphaFormat">The alpha format.</param>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
public void CopyPixels(ILockedFramebuffer buffer, AlphaFormat alphaFormat)
|
||||
public void CopyPixels(ILockedFramebuffer buffer)
|
||||
{
|
||||
if (PlatformImpl.Item is not IReadableBitmapWithAlphaImpl readable || readable.Format == null || readable.AlphaFormat == null)
|
||||
if (PlatformImpl.Item is not IReadableBitmapImpl readable || readable.Format == null || readable.AlphaFormat == null)
|
||||
{
|
||||
throw new NotSupportedException("CopyPixels is not supported for this bitmap type");
|
||||
}
|
||||
|
||||
if (buffer.Format != readable.Format || alphaFormat != readable.AlphaFormat)
|
||||
if (buffer.Format != readable.Format || buffer.AlphaFormat != readable.AlphaFormat)
|
||||
{
|
||||
using (var fb = readable.Lock())
|
||||
{
|
||||
@@ -255,11 +253,11 @@ namespace Avalonia.Media.Imaging
|
||||
fb.Size,
|
||||
fb.RowBytes,
|
||||
fb.Format,
|
||||
readable.AlphaFormat.Value,
|
||||
fb.AlphaFormat,
|
||||
buffer.Address,
|
||||
buffer.RowBytes,
|
||||
buffer.Format,
|
||||
alphaFormat);
|
||||
buffer.AlphaFormat);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -71,10 +71,10 @@ namespace Avalonia.Media.Imaging
|
||||
|
||||
return new LockedFramebuffer(_pixelFormatMemory.Address, _pixelFormatMemory.Size,
|
||||
_pixelFormatMemory.RowBytes,
|
||||
Dpi, _pixelFormatMemory.Format, () =>
|
||||
Dpi, _pixelFormatMemory.Format, _pixelFormatMemory.AlphaFormat, () =>
|
||||
{
|
||||
using var inner = ((IWriteableBitmapImpl)PlatformImpl.Item).Lock();
|
||||
_pixelFormatMemory.CopyToRgba(Platform.AlphaFormat.Unpremul, inner.Address, inner.RowBytes);
|
||||
_pixelFormatMemory.CopyToRgba(inner.AlphaFormat, inner.Address, inner.RowBytes);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ namespace Avalonia.Platform
|
||||
/// </summary>
|
||||
PixelFormat Format { get; }
|
||||
|
||||
//TODO12: Add AlphaFormat
|
||||
/// <summary>
|
||||
/// Gets the alpha format.
|
||||
/// </summary>
|
||||
AlphaFormat AlphaFormat { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,10 @@ using Avalonia.Metadata;
|
||||
|
||||
namespace Avalonia.Platform;
|
||||
|
||||
public interface IReadableBitmapImpl
|
||||
[PrivateApi]
|
||||
public interface IReadableBitmapImpl : IBitmapImpl
|
||||
{
|
||||
PixelFormat? Format { get; }
|
||||
AlphaFormat? AlphaFormat { get; }
|
||||
ILockedFramebuffer Lock();
|
||||
}
|
||||
|
||||
//TODO12: Remove me once we can change IReadableBitmapImpl
|
||||
[Unstable]
|
||||
public interface IReadableBitmapWithAlphaImpl : IReadableBitmapImpl
|
||||
{
|
||||
AlphaFormat? AlphaFormat { get; }
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace Avalonia.Platform
|
||||
/// <summary>
|
||||
/// Defines the platform-specific interface for a <see cref="Avalonia.Media.Imaging.WriteableBitmap"/>.
|
||||
/// </summary>
|
||||
[Unstable]
|
||||
public interface IWriteableBitmapImpl : IBitmapImpl, IReadableBitmapWithAlphaImpl
|
||||
[PrivateApi]
|
||||
public interface IWriteableBitmapImpl : IBitmapImpl, IReadableBitmapImpl
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Avalonia.Platform
|
||||
private readonly Action? _onDispose;
|
||||
|
||||
public LockedFramebuffer(IntPtr address, PixelSize size, int rowBytes, Vector dpi, PixelFormat format,
|
||||
Action? onDispose)
|
||||
AlphaFormat alphaFormat, Action? onDispose)
|
||||
{
|
||||
_onDispose = onDispose;
|
||||
Address = address;
|
||||
@@ -15,6 +15,7 @@ namespace Avalonia.Platform
|
||||
RowBytes = rowBytes;
|
||||
Dpi = dpi;
|
||||
Format = format;
|
||||
AlphaFormat = alphaFormat;
|
||||
}
|
||||
|
||||
public IntPtr Address { get; }
|
||||
@@ -22,6 +23,7 @@ namespace Avalonia.Platform
|
||||
public int RowBytes { get; }
|
||||
public Vector Dpi { get; }
|
||||
public PixelFormat Format { get; }
|
||||
public AlphaFormat AlphaFormat { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Avalonia.Metadata;
|
||||
using Avalonia.Platform.Internal;
|
||||
|
||||
namespace Avalonia.Platform;
|
||||
@@ -10,6 +8,7 @@ internal class RetainedFramebuffer : IDisposable
|
||||
public PixelSize Size { get; }
|
||||
public int RowBytes { get; }
|
||||
public PixelFormat Format { get; }
|
||||
public AlphaFormat AlphaFormat { get; }
|
||||
public IntPtr Address => _blob?.Address ?? throw new ObjectDisposedException(nameof(RetainedFramebuffer));
|
||||
private UnmanagedBlob? _blob;
|
||||
|
||||
@@ -17,13 +16,13 @@ internal class RetainedFramebuffer : IDisposable
|
||||
? format
|
||||
: throw new ArgumentOutOfRangeException(nameof(format));
|
||||
|
||||
public RetainedFramebuffer(PixelSize size, PixelFormat format) : this(size, ValidateKnownFormat(format),
|
||||
format.BitsPerPixel / 8 * size.Width)
|
||||
public RetainedFramebuffer(PixelSize size, PixelFormat format, AlphaFormat alphaFormat)
|
||||
: this(size, ValidateKnownFormat(format), alphaFormat, format.BitsPerPixel / 8 * size.Width)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public RetainedFramebuffer(PixelSize size, PixelFormat format, int rowBytes)
|
||||
public RetainedFramebuffer(PixelSize size, PixelFormat format, AlphaFormat alphaFormat, int rowBytes)
|
||||
{
|
||||
if (size.Width <= 0 || size.Height <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(size));
|
||||
@@ -32,6 +31,7 @@ internal class RetainedFramebuffer : IDisposable
|
||||
Size = size;
|
||||
RowBytes = rowBytes;
|
||||
Format = format;
|
||||
AlphaFormat = alphaFormat;
|
||||
_blob = new UnmanagedBlob(RowBytes * size.Height);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ internal class RetainedFramebuffer : IDisposable
|
||||
{
|
||||
if (_blob == null)
|
||||
throw new ObjectDisposedException(nameof(RetainedFramebuffer));
|
||||
return new LockedFramebuffer(_blob.Address, Size, RowBytes, dpi, Format, () =>
|
||||
return new LockedFramebuffer(_blob.Address, Size, RowBytes, dpi, Format, AlphaFormat, () =>
|
||||
{
|
||||
blit(this);
|
||||
GC.KeepAlive(this);
|
||||
|
||||
@@ -76,6 +76,7 @@ namespace Avalonia.Controls.Remote.Server
|
||||
Stride,
|
||||
new Vector(_dpi, _dpi),
|
||||
new PlatformPixelFormat((PixelFormatEnum)Format),
|
||||
Format == ProtocolPixelFormat.Rgb565 ? AlphaFormat.Opaque : AlphaFormat.Premul,
|
||||
() =>
|
||||
{
|
||||
handle.Free();
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace Avalonia.Native
|
||||
public int RowBytes { get; set; }
|
||||
public Vector Dpi { get; set; }
|
||||
public PixelFormat Format { get; set; }
|
||||
public AlphaFormat AlphaFormat { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace Avalonia.X11
|
||||
return new LockedFramebuffer(
|
||||
_blob.Address + Marshal.SizeOf<XcursorImage>(),
|
||||
_pixelSize, _pixelSize.Width * 4,
|
||||
new Vector(96, 96), PixelFormat.Bgra8888, null);
|
||||
new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul, null);
|
||||
}
|
||||
|
||||
public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock);
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Avalonia.X11
|
||||
{
|
||||
_fb?.Dispose();
|
||||
_fb = null;
|
||||
_fb = new RetainedFramebuffer(new PixelSize(width, height), PixelFormat.Bgra8888);
|
||||
_fb = new RetainedFramebuffer(new PixelSize(width, height), PixelFormat.Bgra8888, AlphaFormat.Premul);
|
||||
}
|
||||
|
||||
properties = new FramebufferLockProperties(framebufferValid);
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Avalonia.X11
|
||||
{
|
||||
var h = GCHandle.Alloc(_bdata, GCHandleType.Pinned);
|
||||
return new LockedFramebuffer(h.AddrOfPinnedObject(), new PixelSize(_width, _height), _width * 4,
|
||||
new Vector(96, 96), PixelFormat.Bgra8888,
|
||||
new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul,
|
||||
() => h.Free());
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ partial class BrowserSoftwareRenderTarget : BrowserRenderTarget, IFramebufferPla
|
||||
{
|
||||
_fb?.Dispose();
|
||||
_fb = null;
|
||||
_fb = new RetainedFramebuffer(size, PixelFormat.Rgba8888);
|
||||
_fb = new RetainedFramebuffer(size, PixelFormat.Rgba8888, AlphaFormat.Premul);
|
||||
}
|
||||
|
||||
return _fb.Lock(new Vector(scaling * 96, scaling * 96), _parent._blit);
|
||||
|
||||
@@ -414,8 +414,8 @@ namespace Avalonia.Headless
|
||||
|
||||
public Vector Dpi { get; }
|
||||
public PixelSize PixelSize { get; }
|
||||
public PixelFormat? Format { get; }
|
||||
public AlphaFormat? AlphaFormat { get; }
|
||||
public PixelFormat? Format => PixelFormat.Rgba8888;
|
||||
public AlphaFormat? AlphaFormat => Platform.AlphaFormat.Premul;
|
||||
public int Version { get; set; }
|
||||
|
||||
public void Save(string fileName, int? quality = null)
|
||||
@@ -434,7 +434,7 @@ namespace Avalonia.Headless
|
||||
Version++;
|
||||
var mem = Marshal.AllocHGlobal(PixelSize.Width * PixelSize.Height * 4);
|
||||
return new LockedFramebuffer(mem, PixelSize, PixelSize.Width * 4, Dpi, PixelFormat.Rgba8888,
|
||||
() => Marshal.FreeHGlobal(mem));
|
||||
Platform.AlphaFormat.Premul, () => Marshal.FreeHGlobal(mem));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,7 @@ namespace Avalonia.Headless
|
||||
public int RowBytes => _fb.RowBytes;
|
||||
public Vector Dpi => _fb.Dpi;
|
||||
public PixelFormat Format => _fb.Format;
|
||||
public AlphaFormat AlphaFormat => _fb.AlphaFormat;
|
||||
}
|
||||
|
||||
public ILockedFramebuffer Lock()
|
||||
|
||||
@@ -101,12 +101,17 @@ namespace Avalonia.LinuxFramebuffer.Output
|
||||
public static LockedFramebuffer LockFb(IntPtr address, fb_var_screeninfo varInfo,
|
||||
fb_fix_screeninfo fixedInfo, Vector dpi, Action? dispose)
|
||||
{
|
||||
var (format, alphaFormat) = varInfo switch
|
||||
{
|
||||
{ bits_per_pixel: 16 } => (PixelFormat.Rgb565, AlphaFormat.Opaque),
|
||||
{ bits_per_pixel: 32, blue.offset: 16 } => (PixelFormat.Rgba8888, AlphaFormat.Premul),
|
||||
_ => (PixelFormat.Bgra8888, AlphaFormat.Premul)
|
||||
};
|
||||
|
||||
return new LockedFramebuffer(address,
|
||||
new PixelSize((int)varInfo.xres, (int)varInfo.yres),
|
||||
(int)fixedInfo.line_length, dpi,
|
||||
varInfo.bits_per_pixel == 16 ? PixelFormat.Rgb565
|
||||
: varInfo.blue.offset == 16 ? PixelFormat.Rgba8888
|
||||
: PixelFormat.Bgra8888, dispose);
|
||||
format, alphaFormat, dispose);
|
||||
}
|
||||
|
||||
private void BlitToDevice()
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Avalonia.Skia
|
||||
var framebuffer = _renderTargetWithProperties?.Lock(out lockProperties) ?? _renderTarget.Lock();
|
||||
var framebufferImageInfo = new SKImageInfo(framebuffer.Size.Width, framebuffer.Size.Height,
|
||||
framebuffer.Format.ToSkColorType(),
|
||||
framebuffer.Format == PixelFormat.Rgb565 ? SKAlphaType.Opaque : SKAlphaType.Premul);
|
||||
framebuffer.AlphaFormat.ToSkAlphaType());
|
||||
|
||||
CreateSurface(framebufferImageInfo, framebuffer);
|
||||
_hadConversionShim |= _conversionShim != null;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Avalonia.Skia
|
||||
/// <summary>
|
||||
/// Immutable Skia bitmap.
|
||||
/// </summary>
|
||||
internal class ImmutableBitmap : IDrawableBitmapImpl, IReadableBitmapWithAlphaImpl
|
||||
internal class ImmutableBitmap : IDrawableBitmapImpl, IReadableBitmapImpl
|
||||
{
|
||||
private readonly SKImage _image;
|
||||
private readonly SKBitmap? _bitmap;
|
||||
@@ -195,7 +195,9 @@ namespace Avalonia.Skia
|
||||
if (_bitmap.ColorType.ToAvalonia() is not { } format)
|
||||
throw new NotSupportedException($"Unsupported format {_bitmap.ColorType}");
|
||||
|
||||
return new LockedFramebuffer(_bitmap.GetPixels(), PixelSize, _bitmap.RowBytes, Dpi, format, null);
|
||||
var alphaFormat = _bitmap.AlphaType.ToAlphaFormat();
|
||||
|
||||
return new LockedFramebuffer(_bitmap.GetPixels(), PixelSize, _bitmap.RowBytes, Dpi, format, alphaFormat, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,6 +238,8 @@ namespace Avalonia.Skia
|
||||
public Vector Dpi => _parent.Dpi;
|
||||
/// <inheritdoc />
|
||||
public PixelFormat Format => _bitmap.ColorType.ToPixelFormat();
|
||||
|
||||
public AlphaFormat AlphaFormat => _bitmap.AlphaType.ToAlphaFormat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Avalonia.Win32
|
||||
|
||||
return fb = new LockedFramebuffer(
|
||||
framebufferData.Data.Address, framebufferData.Size, framebufferData.RowBytes,
|
||||
GetCurrentDpi(), s_format, _onDisposeAction);
|
||||
GetCurrentDpi(), s_format, AlphaFormat.Premul, _onDisposeAction);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -96,14 +96,14 @@ internal class Win32Icon : IDisposable
|
||||
|
||||
static IntPtr CreateHBitmap(Bitmap source)
|
||||
{
|
||||
using var fb = AllocFramebuffer(source.PixelSize, PixelFormats.Bgra8888);
|
||||
source.CopyPixels(fb, AlphaFormat.Unpremul);
|
||||
using var fb = AllocFramebuffer(source.PixelSize, PixelFormats.Bgra8888, AlphaFormat.Unpremul);
|
||||
source.CopyPixels(fb);
|
||||
return UnmanagedMethods.CreateBitmap(source.PixelSize.Width, source.PixelSize.Height, 1, 32, fb.Address);
|
||||
}
|
||||
|
||||
static unsafe IntPtr AlphaToMask(Bitmap source)
|
||||
{
|
||||
using var alphaMaskBuffer = AllocFramebuffer(source.PixelSize, PixelFormats.BlackWhite);
|
||||
using var alphaMaskBuffer = AllocFramebuffer(source.PixelSize, PixelFormats.BlackWhite, AlphaFormat.Opaque);
|
||||
var height = alphaMaskBuffer.Size.Height;
|
||||
var width = alphaMaskBuffer.Size.Width;
|
||||
|
||||
@@ -114,8 +114,8 @@ internal class Win32Icon : IDisposable
|
||||
}
|
||||
else
|
||||
{
|
||||
using var argbBuffer = AllocFramebuffer(source.PixelSize, PixelFormat.Bgra8888);
|
||||
source.CopyPixels(argbBuffer, AlphaFormat.Unpremul);
|
||||
using var argbBuffer = AllocFramebuffer(source.PixelSize, PixelFormat.Bgra8888, AlphaFormat.Unpremul);
|
||||
source.CopyPixels(argbBuffer);
|
||||
var pSource = (byte*)argbBuffer.Address;
|
||||
var pDest = (byte*)alphaMaskBuffer.Address;
|
||||
|
||||
@@ -140,7 +140,7 @@ internal class Win32Icon : IDisposable
|
||||
return UnmanagedMethods.CreateBitmap(width, height, 1, 1, alphaMaskBuffer.Address);
|
||||
}
|
||||
|
||||
static LockedFramebuffer AllocFramebuffer(PixelSize size, PixelFormat format)
|
||||
static LockedFramebuffer AllocFramebuffer(PixelSize size, PixelFormat format, AlphaFormat alphaFormat)
|
||||
{
|
||||
if (size.Width < 1 || size.Height < 1)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
@@ -149,7 +149,7 @@ internal class Win32Icon : IDisposable
|
||||
var data = Marshal.AllocHGlobal(size.Height * stride);
|
||||
if (data == IntPtr.Zero)
|
||||
throw new OutOfMemoryException();
|
||||
return new LockedFramebuffer(data, size, stride, new Vector(96, 96), format,
|
||||
return new LockedFramebuffer(data, size, stride, new Vector(96, 96), format, alphaFormat,
|
||||
() => Marshal.FreeHGlobal(data));
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public class DirectFbCompositionTests : TestBase
|
||||
SKBitmap fb = new SKBitmap(200, 200, SKColorType.Rgba8888, SKAlphaType.Premul);
|
||||
|
||||
ILockedFramebuffer LockFb() => new LockedFramebuffer(fb.GetAddress(0, 0), new(fb.Width, fb.Height),
|
||||
fb.RowBytes, new Vector(96, 96), PixelFormat.Rgba8888, null);
|
||||
fb.RowBytes, new Vector(96, 96), PixelFormat.Rgba8888, AlphaFormat.Premul, null);
|
||||
|
||||
bool previousFrameIsRetained = false;
|
||||
IFramebufferRenderTarget rt = advertised
|
||||
|
||||
@@ -25,10 +25,11 @@ namespace Avalonia.Skia.RenderTests
|
||||
|
||||
class Framebuffer : ILockedFramebuffer, IFramebufferPlatformSurface
|
||||
{
|
||||
public Framebuffer(PixelFormat fmt, PixelSize size)
|
||||
public Framebuffer(PixelFormat fmt, AlphaFormat alphaFormat, PixelSize size)
|
||||
{
|
||||
Format = fmt;
|
||||
var bpp = fmt == PixelFormat.Rgb565 ? 2 : 4;
|
||||
AlphaFormat = alphaFormat;
|
||||
Size = size;
|
||||
RowBytes = bpp * size.Width;
|
||||
Address = Marshal.AllocHGlobal(size.Height * RowBytes);
|
||||
@@ -40,6 +41,8 @@ namespace Avalonia.Skia.RenderTests
|
||||
|
||||
public PixelFormat Format { get; }
|
||||
|
||||
public AlphaFormat AlphaFormat { get; }
|
||||
|
||||
public PixelSize Size { get; }
|
||||
|
||||
public int RowBytes { get; }
|
||||
@@ -64,7 +67,7 @@ namespace Avalonia.Skia.RenderTests
|
||||
{
|
||||
var fmt = new PixelFormat(fmte);
|
||||
var testName = nameof(FramebufferRenderResultsShouldBeUsableAsBitmap) + "_" + fmt;
|
||||
var fb = new Framebuffer(fmt, new PixelSize(80, 80));
|
||||
var fb = new Framebuffer(fmt, AlphaFormat.Premul, new PixelSize(80, 80));
|
||||
var r = AvaloniaLocator.Current.GetRequiredService<IPlatformRenderInterface>();
|
||||
using(var cpuContext = r.CreateBackendContext(null))
|
||||
using (var target = cpuContext.CreateRenderTarget(new object[] { fb }))
|
||||
|
||||
@@ -174,7 +174,7 @@ public class CompositorTestServices : IDisposable
|
||||
{
|
||||
var ptr = Marshal.AllocHGlobal(128);
|
||||
return new LockedFramebuffer(ptr, new PixelSize(1, 1), 4, new Vector(96, 96),
|
||||
PixelFormat.Rgba8888, () => Marshal.FreeHGlobal(ptr));
|
||||
PixelFormat.Rgba8888, AlphaFormat.Premul, () => Marshal.FreeHGlobal(ptr));
|
||||
}
|
||||
|
||||
public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock);
|
||||
|
||||
Reference in New Issue
Block a user