diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index cbc896813f..dac284ce1a 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -36,6 +36,7 @@ namespace Avalonia.Skia
private readonly SKPaint _fillPaint = new SKPaint();
private readonly SKPaint _boxShadowPaint = new SKPaint();
private static SKShader s_acrylicNoiseShader;
+ private readonly GRSurfaceOrigin _surfaceOrigin;
///
/// Context create info.
@@ -76,6 +77,8 @@ namespace Avalonia.Skia
/// Skia GPU provider context (optional)
///
public ISkiaGpu Gpu;
+
+ public ISkiaGpuRenderSession CurrentSession;
}
///
@@ -96,6 +99,8 @@ namespace Avalonia.Skia
Surface = createInfo.Surface;
Canvas = createInfo.Canvas ?? createInfo.Surface?.Canvas;
+ _surfaceOrigin = createInfo.CurrentSession?.SurfaceOrigin ?? GRSurfaceOrigin.TopLeft;
+
if (Canvas == null)
{
throw new ArgumentException("Invalid create info - no Canvas provided", nameof(createInfo));
@@ -972,7 +977,7 @@ namespace Avalonia.Skia
Gpu = _gpu
};
- return new SurfaceRenderTarget(createInfo);
+ return new SurfaceRenderTarget(createInfo, _surfaceOrigin);
}
///
diff --git a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
index 869c261f1b..7442f90ecf 100644
--- a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
+++ b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
@@ -21,7 +21,7 @@ namespace Avalonia.Skia
/// Creates an offscreen render target surface
///
/// size in pixels
- ISkiaSurface TryCreateSurface(PixelSize size);
+ ISkiaSurface TryCreateSurface(PixelSize size, GRSurfaceOrigin surfaceOrigin);
}
public interface ISkiaSurface : IDisposable
diff --git a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs
index a4e2bfed52..5faa6a41ec 100644
--- a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs
+++ b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderSession.cs
@@ -22,5 +22,7 @@ namespace Avalonia.Skia
/// Scaling factor.
///
double ScaleFactor { get; }
+
+ GRSurfaceOrigin SurfaceOrigin { get; }
}
}
diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs
index 24464c39d9..8ab275df63 100644
--- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs
+++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs
@@ -14,7 +14,7 @@ namespace Avalonia.Skia
private int _texture;
private static readonly bool[] TrueFalse = new[] { true, false };
- public FboSkiaSurface(GRContext grContext, IGlContext glContext, PixelSize pixelSize)
+ public FboSkiaSurface(GRContext grContext, IGlContext glContext, PixelSize pixelSize, GRSurfaceOrigin surfaceOrigin)
{
_grContext = grContext;
_glContext = glContext;
@@ -93,7 +93,7 @@ namespace Avalonia.Skia
var target = new GRBackendRenderTarget(pixelSize.Width, pixelSize.Height, 0, 8,
new GRGlFramebufferInfo((uint)_fbo, SKColorType.Rgba8888.ToGlSizedFormat()));
Surface = SKSurface.Create(_grContext, target,
- GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888);
+ surfaceOrigin, SKColorType.Rgba8888);
CanBlit = gl.BlitFramebuffer != null;
}
diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs
index e109922a3f..b4c5619c85 100644
--- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs
+++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs
@@ -39,6 +39,8 @@ namespace Avalonia.Skia
_backendRenderTarget = backendRenderTarget;
_surface = surface;
_glSession = glSession;
+
+ SurfaceOrigin = glSession.IsYFlipped ? GRSurfaceOrigin.TopLeft : GRSurfaceOrigin.BottomLeft;
}
public void Dispose()
{
@@ -48,6 +50,8 @@ namespace Avalonia.Skia
GrContext.Flush();
_glSession.Dispose();
}
+
+ public GRSurfaceOrigin SurfaceOrigin { get; }
public GRContext GrContext { get; }
public SKSurface SkSurface => _surface;
diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs
index c02d813e24..02e3766d40 100644
--- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs
+++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs
@@ -47,7 +47,7 @@ namespace Avalonia.Skia
return null;
}
- public ISkiaSurface TryCreateSurface(PixelSize size)
+ public ISkiaSurface TryCreateSurface(PixelSize size, GRSurfaceOrigin surfaceOrigin)
{
// Only windows platform needs our FBO trickery
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
@@ -62,7 +62,7 @@ namespace Avalonia.Skia
return null;
try
{
- var surface = new FboSkiaSurface(_grContext, _glContext, size);
+ var surface = new FboSkiaSurface(_grContext, _glContext, size, surfaceOrigin);
_canCreateSurfaces = true;
return surface;
}
diff --git a/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs
index 9992c9ba8c..6626546c0c 100644
--- a/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs
+++ b/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs
@@ -33,7 +33,8 @@ namespace Avalonia.Skia
Dpi = SkiaPlatform.DefaultDpi * session.ScaleFactor,
VisualBrushRenderer = visualBrushRenderer,
DisableTextLcdRendering = true,
- Gpu = _skiaGpu
+ Gpu = _skiaGpu,
+ CurrentSession = session
};
return new DrawingContextImpl(nfo, session);
diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
index d6f76a2c20..6048482110 100644
--- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
+++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
@@ -127,7 +127,7 @@ namespace Avalonia.Skia
DisableTextLcdRendering = false
};
- return new SurfaceRenderTarget(createInfo);
+ return new SurfaceRenderTarget(createInfo, GRSurfaceOrigin.TopLeft);
}
///
diff --git a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
index 61b599a731..905c9160a7 100644
--- a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
+++ b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
@@ -42,7 +42,7 @@ namespace Avalonia.Skia
/// Create new surface render target.
///
/// Create info.
- public SurfaceRenderTarget(CreateInfo createInfo)
+ public SurfaceRenderTarget(CreateInfo createInfo, GRSurfaceOrigin surfaceOrigin)
{
PixelSize = new PixelSize(createInfo.Width, createInfo.Height);
Dpi = createInfo.Dpi;
@@ -51,7 +51,7 @@ namespace Avalonia.Skia
_grContext = createInfo.GrContext;
_gpu = createInfo.Gpu;
- _surface = _gpu?.TryCreateSurface(PixelSize);
+ _surface = _gpu?.TryCreateSurface(PixelSize, surfaceOrigin);
if (_surface == null)
_surface = new SkiaSurfaceWrapper(CreateSurface(createInfo.GrContext, PixelSize.Width, PixelSize.Height,
createInfo.Format));
@@ -100,7 +100,7 @@ namespace Avalonia.Skia
VisualBrushRenderer = visualBrushRenderer,
DisableTextLcdRendering = _disableLcdRendering,
GrContext = _grContext,
- Gpu = _gpu
+ Gpu = _gpu,
};
return new DrawingContextImpl(createInfo, Disposable.Create(() => Version++));