From 5339d88f93eb4d9c742b0e061317e6d9c81c3356 Mon Sep 17 00:00:00 2001 From: Nelson Carrillo Date: Wed, 25 Jul 2018 14:15:55 -0400 Subject: [PATCH] Remove hardcoded DPI from GlRenderTarget. Cleanup WindowImpl a bit --- src/Avalonia.Gpu/IGpuContext.cs | 1 + src/Avalonia.Windowing/Bindings/GlWindow.cs | 6 ++ src/Avalonia.Windowing/WindowImpl.cs | 67 ++++++++++++++++----- src/Skia/Avalonia.Skia/GlRenderTarget.cs | 20 ++++-- 4 files changed, 72 insertions(+), 22 deletions(-) diff --git a/src/Avalonia.Gpu/IGpuContext.cs b/src/Avalonia.Gpu/IGpuContext.cs index d27e9c24f1..2656b97c44 100644 --- a/src/Avalonia.Gpu/IGpuContext.cs +++ b/src/Avalonia.Gpu/IGpuContext.cs @@ -8,5 +8,6 @@ namespace Avalonia.Gpu IntPtr GetProcAddress(string symbol); (double, double) GetFramebufferSize(); void ResizeContext(double width, double height); + (double, double) GetDpi(); } } diff --git a/src/Avalonia.Windowing/Bindings/GlWindow.cs b/src/Avalonia.Windowing/Bindings/GlWindow.cs index 334453e74a..35114b3deb 100644 --- a/src/Avalonia.Windowing/Bindings/GlWindow.cs +++ b/src/Avalonia.Windowing/Bindings/GlWindow.cs @@ -127,5 +127,11 @@ namespace Avalonia.Windowing.Bindings { winit_gl_window_hide(_handle); } + + public (double, double) GetDpi() + { + var scaleFactor = GetScaleFactor(); + return (scaleFactor, scaleFactor); + } } } diff --git a/src/Avalonia.Windowing/WindowImpl.cs b/src/Avalonia.Windowing/WindowImpl.cs index 2b39bef55e..966276873c 100644 --- a/src/Avalonia.Windowing/WindowImpl.cs +++ b/src/Avalonia.Windowing/WindowImpl.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reactive; +using System.Reactive.Disposables; using System.Reactive.Linq; using System.Reactive.Subjects; using Avalonia.Controls; @@ -20,15 +21,18 @@ namespace Avalonia.Windowing IWindowWrapper _windowWrapper; private LogicalPosition _lastPosition; + const int FramesPerSecond = 60; + public WindowImpl(IWindowWrapper wrapper) { _windowWrapper = wrapper; // TODO: This is only necessary when using ImmediateRenderer - Observable.Repeat(Observable.Timer(TimeSpan.FromMilliseconds(16))) + Observable.Repeat(Observable.Timer(TimeSpan.FromMilliseconds(1000 / FramesPerSecond))) .SubscribeOn(AvaloniaScheduler.Instance) .Subscribe((x) => { + // Dont schedule a paint for empty invalidations. if (coalescedRect != Rect.Empty) { Dispatcher.UIThread.Post(() => Paint(coalescedRect), DispatcherPriority.Render); coalescedRect = Rect.Empty; @@ -48,6 +52,7 @@ namespace Avalonia.Windowing } set { + // TODO: SetPosition var x = value; } } @@ -183,7 +188,7 @@ namespace Avalonia.Windowing public IDisposable ShowDialog() { - return null; + return Disposable.Create(() => {}); } public void ShowTaskbarIcon(bool value) @@ -192,25 +197,55 @@ namespace Avalonia.Windowing public void OnKeyboardEvent (KeyboardEvent evt) { - Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); - Input(new RawKeyEventArgs(KeyboardDevice, (uint)Environment.TickCount, evt.Pressed == 1 ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp, KeyTransform.TransformKeyCode(evt.VirtualKeyCode).Value, InputModifiers.None)); + Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); + var eventType = evt.Pressed == 1 ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp; + var timeStamp = (uint)Environment.TickCount; + + Input + ( + new RawKeyEventArgs + ( + KeyboardDevice, + timeStamp, + eventType, + KeyTransform.TransformKeyCode(evt.VirtualKeyCode).Value, + InputModifiers.None + ) + ); } public void OnMouseEvent(MouseEvent evt) { Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); - switch(evt.EventType) - { - case MouseEventType.Move: - _lastPosition = evt.Position; - break; - - case MouseEventType.Wheel: - Input(new RawMouseWheelEventArgs(MouseDevice, (uint)Environment.TickCount, _inputRoot, new Point(_lastPosition.X, _lastPosition.Y), new Point(evt.Position.X / 50, evt.Position.Y), InputModifiers.None)); - return; - } - - Input(new RawMouseEventArgs(MouseDevice, (uint)Environment.TickCount, _inputRoot, (RawMouseEventType)evt.EventType, new Point(_lastPosition.X, _lastPosition.Y), InputModifiers.None)); + var eventType = (RawMouseEventType)evt.EventType; + var timeStamp = (uint)Environment.TickCount; + + if (evt.EventType == MouseEventType.Move) + _lastPosition = evt.Position; + + Input + ( + eventType != RawMouseEventType.Wheel ? + new RawMouseEventArgs + ( + MouseDevice, + timeStamp, + _inputRoot, + eventType, + new Point(_lastPosition.X, _lastPosition.Y), + InputModifiers.None + ) + : + new RawMouseWheelEventArgs + ( + MouseDevice, + timeStamp, + _inputRoot, + new Point(_lastPosition.X, _lastPosition.Y), + new Point(evt.Position.X, evt.Position.Y), + InputModifiers.None + ) + ); } public void OnResizeEvent(ResizeEvent evt) diff --git a/src/Skia/Avalonia.Skia/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/GlRenderTarget.cs index 26b5435a8d..f4395d6210 100644 --- a/src/Skia/Avalonia.Skia/GlRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/GlRenderTarget.cs @@ -31,18 +31,27 @@ namespace Avalonia.Skia public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer) { var (width, height) = _context.GetFramebufferSize(); + var (dpiX, dpiY) = _context.GetDpi(); - if (_surface == null || (_desc.Width != (int)width * 2 || _desc.Height != (int)height * 2)) + width *= dpiX; + height *= dpiY; + + if (_surface == null || (_desc.Width != (int)width|| _desc.Height != (int)height)) { _context.ResizeContext(width, height); _desc = new GRBackendRenderTargetDesc { - Height = (int)height * 2, - Width = (int)width * 2, + Height = (int)height, + Width = (int)width, + // TODO: Get these framebuffer parameters from the GLContext SampleCount = 1, StencilBits = 8, + // TODO: Use the platform's preferred pixel format to reduce internal conversions Config = GRPixelConfig.Bgra8888, + Origin = GRSurfaceOrigin.BottomLeft, + + // TODO: Get the FBO ID rather than assuming zero here. RenderTargetHandle = IntPtr.Zero }; @@ -55,16 +64,15 @@ namespace Avalonia.Skia var createInfo = new DrawingContextImpl.CreateInfo { Canvas = _canvas, - Dpi = new Vector(192, 192), + Dpi = new Vector(dpiX * SkiaPlatform.DefaultDpi.X, dpiY * SkiaPlatform.DefaultDpi.Y), VisualBrushRenderer = visualBrushRenderer, DisableTextLcdRendering = true }; return new DrawingContextImpl(createInfo, Disposable.Create(() => { - // _canvas.Flush(); _grContext.Flush(); - _context.Present(); // Swap Buffers + _context.Present(); })); }