Browse Source

Only do manual layer fbo management on Windows

pull/4794/head
Nikita Tsukanov 6 years ago
parent
commit
731974b041
  1. 2
      src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
  2. 5
      src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs
  3. 2
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  4. 3
      src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
  5. 7
      src/Skia/Avalonia.Skia/Gpu/OpenGl/FboSkiaSurface.cs
  6. 9
      src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs
  7. 16
      src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
  8. 12
      src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs

2
src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs

@ -272,6 +272,8 @@ namespace Avalonia.Headless
}
public bool CanBlit => false;
public Vector Dpi { get; }
public PixelSize PixelSize { get; }
public int Version { get; set; }

5
src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs

@ -164,5 +164,10 @@ namespace Avalonia.Platform
/// </summary>
/// <param name="context"></param>
void Blit(IDrawingContextImpl context);
/// <summary>
/// Returns true if layer supports optimized blit
/// </summary>
bool CanBlit { get; }
}
}

2
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@ -502,7 +502,7 @@ namespace Avalonia.Rendering
if (layer.OpacityMask == null)
{
if (firstLayer)
if (firstLayer && bitmap.Item.CanBlit)
bitmap.Item.Blit(context);
else
context.DrawBitmap(bitmap, layer.Opacity, sourceRect, clientRect);

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

@ -28,8 +28,7 @@ namespace Avalonia.Skia
{
SKSurface Surface { get; }
bool CanBlit { get; }
void Blit();
void Blit(SKCanvas canvas);
}
public interface IOpenGlAwareSkiaGpu : ISkiaGpu

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

@ -116,8 +116,13 @@ namespace Avalonia.Skia
public SKSurface Surface { get; private set; }
public bool CanBlit { get; }
public void Blit()
public void Blit(SKCanvas canvas)
{
// This should set the render target as the current FBO
// which is definitely not the best method, but it works
canvas.Clear();
canvas.Flush();
var gl = _glContext.GlInterface;
gl.GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, out var oldRead);
gl.BindFramebuffer(GL_READ_FRAMEBUFFER, _fbo);

9
src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Avalonia.Logging;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Imaging;
@ -48,6 +49,14 @@ namespace Avalonia.Skia
public ISkiaSurface TryCreateSurface(PixelSize size)
{
// Only windows platform needs our FBO trickery
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return null;
// Blit feature requires glBlitFramebuffer
if (_glContext.GlInterface.BlitFramebuffer == null)
return null;
size = new PixelSize(Math.Max(size.Width, 1), Math.Max(size.Height, 1));
if (_canCreateSurfaces == false)
return null;

16
src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs

@ -23,20 +23,18 @@ namespace Avalonia.Skia
class SkiaSurfaceWrapper : ISkiaSurface
{
public SKSurface Surface { get; private set; }
public SKSurface ReadSurface { get; private set; }
public bool CanBlit => false;
public void Blit() => throw new NotSupportedException();
public void Blit(SKCanvas canvas) => throw new NotSupportedException();
public SkiaSurfaceWrapper(SKSurface surface)
{
Surface = ReadSurface = surface;
Surface = surface;
}
public void Dispose()
{
Surface?.Dispose();
Surface = null;
ReadSurface = null;
}
}
@ -141,11 +139,7 @@ namespace Avalonia.Skia
if (_surface.CanBlit)
{
_surface.Surface.Canvas.Flush();
// This should set the render target as the current FBO
context.Canvas.Clear();
context.Canvas.Flush();
_surface.Blit();
_surface.Blit(context.Canvas);
}
else
{
@ -155,7 +149,9 @@ namespace Avalonia.Skia
context.Canvas.SetMatrix(oldMatrix);
}
}
public bool CanBlit => true;
/// <inheritdoc />
public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
{

12
src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs

@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Utilities;
@ -34,12 +35,9 @@ namespace Avalonia.Direct2D1.Media.Imaging
return new DrawingContextImpl(visualBrushRenderer, this, _renderTarget, null, () => Version++);
}
public void Blit(IDrawingContextImpl context)
{
var rc = new Rect(0, 0, PixelSize.Width, PixelSize.Height);
context.DrawBitmap(RefCountable.CreateUnownedNotClonable(this),
1, rc, rc);
}
public void Blit(IDrawingContextImpl context) => throw new NotSupportedException();
public bool CanBlit => false;
public IDrawingContextLayerImpl CreateLayer(Size size)
{

Loading…
Cancel
Save