mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
112 lines
3.6 KiB
C#
112 lines
3.6 KiB
C#
using System;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
using Artemis.Core;
|
|
using Artemis.Core.Services;
|
|
using SkiaSharp;
|
|
using SkiaSharp.Views.WPF;
|
|
using Stylet;
|
|
|
|
namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
|
{
|
|
public class RenderDebugViewModel : Screen
|
|
{
|
|
private readonly ICoreService _coreService;
|
|
private double _currentFps;
|
|
private ImageSource _currentFrame;
|
|
private int _renderWidth;
|
|
private int _renderHeight;
|
|
|
|
public RenderDebugViewModel(ICoreService coreService)
|
|
{
|
|
_coreService = coreService;
|
|
DisplayName = "Rendering";
|
|
}
|
|
|
|
public ImageSource CurrentFrame
|
|
{
|
|
get => _currentFrame;
|
|
set => SetAndNotify(ref _currentFrame, value);
|
|
}
|
|
|
|
public double CurrentFps
|
|
{
|
|
get => _currentFps;
|
|
set => SetAndNotify(ref _currentFps, value);
|
|
}
|
|
|
|
public int RenderWidth
|
|
{
|
|
get => _renderWidth;
|
|
set => SetAndNotify(ref _renderWidth, value);
|
|
}
|
|
|
|
public int RenderHeight
|
|
{
|
|
get => _renderHeight;
|
|
set => SetAndNotify(ref _renderHeight, value);
|
|
}
|
|
|
|
protected override void OnActivate()
|
|
{
|
|
_coreService.FrameRendered += CoreServiceOnFrameRendered;
|
|
_coreService.FrameRendering += CoreServiceOnFrameRendering;
|
|
base.OnActivate();
|
|
}
|
|
|
|
protected override void OnDeactivate()
|
|
{
|
|
_coreService.FrameRendered -= CoreServiceOnFrameRendered;
|
|
_coreService.FrameRendering -= CoreServiceOnFrameRendering;
|
|
base.OnDeactivate();
|
|
}
|
|
|
|
private void CoreServiceOnFrameRendered(object sender, FrameRenderedEventArgs e)
|
|
{
|
|
Execute.PostToUIThread(() =>
|
|
{
|
|
// TODO: Remove, frames shouldn't even be rendered if this is the case
|
|
if (e.Texture.Bitmap.Pixels.Length == 0)
|
|
return;
|
|
|
|
SKImageInfo bitmapInfo = e.Texture.Bitmap.Info;
|
|
RenderHeight = bitmapInfo.Height;
|
|
RenderWidth = bitmapInfo.Width;
|
|
|
|
if (!(CurrentFrame is WriteableBitmap writeableBitmap) ||
|
|
writeableBitmap.Width != bitmapInfo.Width ||
|
|
writeableBitmap.Height != bitmapInfo.Height)
|
|
{
|
|
CurrentFrame = e.Texture.Bitmap.ToWriteableBitmap();
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
using (SKImage skiaImage = SKImage.FromPixels(e.Texture.Bitmap.PeekPixels()))
|
|
{
|
|
SKImageInfo info = new(skiaImage.Width, skiaImage.Height);
|
|
writeableBitmap.Lock();
|
|
using (SKPixmap pixmap = new(info, writeableBitmap.BackBuffer, writeableBitmap.BackBufferStride))
|
|
{
|
|
skiaImage.ReadPixels(pixmap, 0, 0);
|
|
}
|
|
|
|
writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight));
|
|
writeableBitmap.Unlock();
|
|
}
|
|
}
|
|
catch (AccessViolationException)
|
|
{
|
|
// oops
|
|
}
|
|
});
|
|
}
|
|
|
|
private void CoreServiceOnFrameRendering(object sender, FrameRenderingEventArgs e)
|
|
{
|
|
CurrentFps = Math.Round(1.0 / e.DeltaTime, 2);
|
|
}
|
|
}
|
|
} |