|
|
@ -22,27 +22,6 @@ namespace Avalonia.Skia |
|
|
//Nothing to do here, since we don't own framebuffer
|
|
|
//Nothing to do here, since we don't own framebuffer
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class FramebufferDrawingContextImpl : DrawingContextImpl |
|
|
|
|
|
{ |
|
|
|
|
|
private readonly SKCanvas _canvas; |
|
|
|
|
|
private readonly SKSurface _surface; |
|
|
|
|
|
private readonly ILockedFramebuffer _framebuffer; |
|
|
|
|
|
|
|
|
|
|
|
public FramebufferDrawingContextImpl(SKCanvas canvas, SKSurface surface, ILockedFramebuffer framebuffer) : base(canvas) |
|
|
|
|
|
{ |
|
|
|
|
|
_canvas = canvas; |
|
|
|
|
|
_surface = surface; |
|
|
|
|
|
_framebuffer = framebuffer; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void Dispose() |
|
|
|
|
|
{ |
|
|
|
|
|
_canvas.Dispose(); |
|
|
|
|
|
_surface.Dispose(); |
|
|
|
|
|
_framebuffer.Dispose(); |
|
|
|
|
|
base.Dispose(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SKColorType TranslatePixelFormat(PixelFormat fmt) |
|
|
SKColorType TranslatePixelFormat(PixelFormat fmt) |
|
|
{ |
|
|
{ |
|
|
@ -55,22 +34,63 @@ namespace Avalonia.Skia |
|
|
throw new ArgumentException("Unknown pixel format: " + fmt); |
|
|
throw new ArgumentException("Unknown pixel format: " + fmt); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PixelFormatShim : IDisposable |
|
|
|
|
|
{ |
|
|
|
|
|
private readonly SKImageInfo _nfo; |
|
|
|
|
|
private readonly IntPtr _fb; |
|
|
|
|
|
private readonly int _rowBytes; |
|
|
|
|
|
private SKBitmap _bitmap; |
|
|
|
|
|
|
|
|
|
|
|
public PixelFormatShim(SKImageInfo nfo, IntPtr fb, int rowBytes) |
|
|
|
|
|
{ |
|
|
|
|
|
_nfo = nfo; |
|
|
|
|
|
_fb = fb; |
|
|
|
|
|
_rowBytes = rowBytes; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_bitmap = new SKBitmap(nfo.Width, nfo.Height); |
|
|
|
|
|
if (!_bitmap.CanCopyTo(nfo.ColorType)) |
|
|
|
|
|
{ |
|
|
|
|
|
_bitmap.Dispose(); |
|
|
|
|
|
throw new Exception( |
|
|
|
|
|
$"Unable to create pixel format shim for conversion from {_bitmap.ColorType} to {nfo.ColorType}"); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public SKSurface CreateSurface() => SKSurface.Create(_bitmap.Info, _bitmap.GetPixels(), _bitmap.RowBytes); |
|
|
|
|
|
|
|
|
|
|
|
public void Dispose() |
|
|
|
|
|
{ |
|
|
|
|
|
using (var tmp = _bitmap.Copy(_nfo.ColorType)) |
|
|
|
|
|
tmp.CopyPixelsTo(_fb, _nfo.BytesPerPixel * _nfo.Height * _rowBytes, _rowBytes); |
|
|
|
|
|
_bitmap.Dispose(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public DrawingContext CreateDrawingContext() |
|
|
public DrawingContext CreateDrawingContext() |
|
|
{ |
|
|
{ |
|
|
var fb = _surface.Lock(); |
|
|
var fb = _surface.Lock(); |
|
|
|
|
|
PixelFormatShim shim = null; |
|
|
SKImageInfo nfo = new SKImageInfo(fb.Width, fb.Height, TranslatePixelFormat(fb.Format), |
|
|
SKImageInfo framebuffer = new SKImageInfo(fb.Width, fb.Height, TranslatePixelFormat(fb.Format), |
|
|
SKAlphaType.Opaque); |
|
|
SKAlphaType.Opaque); |
|
|
var surface = SKSurface.Create(nfo, fb.Address, fb.RowBytes); |
|
|
var surface = SKSurface.Create(framebuffer, fb.Address, fb.RowBytes) ?? |
|
|
|
|
|
(shim = new PixelFormatShim(framebuffer, fb.Address, fb.RowBytes)) |
|
|
|
|
|
.CreateSurface(); |
|
|
if (surface == null) |
|
|
if (surface == null) |
|
|
throw new Exception("Unable to create a surface for pixel format " + fb.Format); |
|
|
throw new Exception("Unable to create a surface for pixel format " + fb.Format + |
|
|
|
|
|
" or pixel format translator"); |
|
|
var canvas = surface.Canvas; |
|
|
var canvas = surface.Canvas; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
canvas.RestoreToCount(0); |
|
|
canvas.RestoreToCount(0); |
|
|
canvas.Save(); |
|
|
canvas.Save(); |
|
|
canvas.Clear(SKColors.Red); |
|
|
canvas.Clear(SKColors.Red); |
|
|
canvas.ResetMatrix(); |
|
|
canvas.ResetMatrix(); |
|
|
|
|
|
|
|
|
return new DrawingContext(new FramebufferDrawingContextImpl(canvas, surface, fb), |
|
|
return new DrawingContext(new DrawingContextImpl(canvas, canvas, surface, shim, fb), |
|
|
Matrix.CreateScale(fb.Dpi.Width / 96, fb.Dpi.Height / 96)); |
|
|
Matrix.CreateScale(fb.Dpi.Width / 96, fb.Dpi.Height / 96)); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|