Browse Source

Do the manual blit if possible

Nikita Tsukanov 6 years ago
parent
commit
445290ecec
  1. 13
      src/Avalonia.OpenGL/GlInterface.cs
  2. 4
      src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
  3. 15
      src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs
  4. 10
      src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs

13
src/Avalonia.OpenGL/GlInterface.cs

@ -117,6 +117,19 @@ namespace Avalonia.OpenGL
public delegate int GlCheckFramebufferStatus(int target);
[GlEntryPoint("glCheckFramebufferStatus")]
public GlCheckFramebufferStatus CheckFramebufferStatus { get; }
public delegate void GlBlitFramebuffer(int srcX0,
int srcY0,
int srcX1,
int srcY1,
int dstX0,
int dstY0,
int dstX1,
int dstY1,
int mask,
int filter);
[GlMinVersionEntryPoint("glBlitFramebuffer", 3, 0)]
public GlBlitFramebuffer BlitFramebuffer { get; }
public delegate void GlGenRenderbuffers(int count, int[] res);
[GlEntryPoint("glGenRenderbuffers")]

4
src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs

@ -28,7 +28,9 @@ namespace Avalonia.Skia
{
SKSurface WriteSurface { get; }
SKSurface ReadSurface { get; }
bool CanBlit { get; }
void Blit();
}
public interface IOpenGlAwareSkiaGpu : ISkiaGpu

15
src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs

@ -97,15 +97,16 @@ namespace Avalonia.Skia
new GRGlFramebufferInfo((uint)_fbo, SKColorType.Rgba8888.ToGlSizedFormat()));
WriteSurface = SKSurface.Create(_grContext, target,
GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888);
CanBlit = gl.BlitFramebuffer != null;
}
public void Dispose()
{
using (_glContext.EnsureCurrent())
{
WriteSurface.Dispose();
WriteSurface?.Dispose();
WriteSurface = null;
ReadSurface.Dispose();
ReadSurface?.Dispose();
ReadSurface = null;
var gl = _glContext.GlInterface;
if (_fbo != 0)
@ -120,5 +121,15 @@ namespace Avalonia.Skia
public SKSurface WriteSurface { get; private set; }
public SKSurface ReadSurface { get; private set; }
public bool CanBlit { get; }
public void Blit()
{
var gl = _glContext.GlInterface;
gl.GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, out var oldRead);
gl.BindFramebuffer(GL_READ_FRAMEBUFFER, _fbo);
gl.BlitFramebuffer(0, 0, _pixelSize.Width, _pixelSize.Height, 0, 0, _pixelSize.Width, _pixelSize.Height,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
gl.BindFramebuffer(GL_READ_FRAMEBUFFER, oldRead);
}
}
}

10
src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs

@ -23,6 +23,8 @@ namespace Avalonia.Skia
{
public SKSurface WriteSurface { get; private set; }
public SKSurface ReadSurface { get; private set; }
public bool CanBlit => false;
public void Blit() => throw new NotSupportedException();
public SkiaSurfaceWrapper(SKSurface surface)
{
@ -136,8 +138,12 @@ namespace Avalonia.Skia
{
if (sourceRect.Left == 0 && sourceRect.Top == 0 && sourceRect.Size == destRect.Size)
{
_surface.ReadSurface.Canvas.Flush();
_surface.ReadSurface.Draw(context.Canvas, destRect.Left, destRect.Top, paint);
_surface.WriteSurface.Canvas.Flush();
if (context.Canvas.TotalMatrix.IsIdentity && _surface.CanBlit && destRect.Top == 0 &&
destRect.Left == 0)
_surface.Blit();
else
_surface.ReadSurface.Draw(context.Canvas, destRect.Left, destRect.Top, paint);
}
else
using (var image = SnapshotImage())

Loading…
Cancel
Save