Skip to content

Commit

Permalink
Merge pull request #37 from DarthAffe/v3
Browse files Browse the repository at this point in the history
V3
  • Loading branch information
DarthAffe authored Jul 22, 2024
2 parents ae6cf5c + f314a41 commit 44a669c
Show file tree
Hide file tree
Showing 33 changed files with 223 additions and 2,790 deletions.
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ using (fullscreen.Lock())
IColor imageColorExample = image[10, 20];

// Get the first row
IImage.IImageRow row = image.Rows[0];
IImageRow row = image.Rows[0];
// Get the 10th pixel of the row
IColor rowColorExample = row[10];

// Get the first column
IImage.IImageColumn column = image.Columns[0];
IImageColumn column = image.Columns[0];
// Get the 10th pixel of the column
IColor columnColorExample = column[10];

Expand All @@ -73,7 +73,7 @@ using (fullscreen.Lock())
}
```

IF you know which Capture-provider you're using it performs a bit better to not use the abstraction but a more low-level approach instead.
If you know which Capture-provider you're using it performs a bit better to not use the abstraction but a more low-level approach instead.
This is the same example as above but without using the interfaces:
```csharp
DX11ScreenCaptureService screenCaptureService = new DX11ScreenCaptureService();
Expand All @@ -88,17 +88,20 @@ screenCapture.CaptureScreen();

using (fullscreen.Lock())
{
RefImage<ColorBGRA> image = fullscreen.Image;
IImage<ColorBGRA> image = fullscreen.Image;

// You can also get a ref image which has a slight performance benefit in some cases
// RefImage<ColorBGRA> refImage = image.AsRefImage();
foreach (ColorBGRA color in image)
Console.WriteLine($"A: {color.A}, R: {color.R}, G: {color.G}, B: {color.B}");

ColorBGRA imageColorExample = image[10, 20];

ReadOnlyRefEnumerable<ColorBGRA> row = image.Rows[0];
ImageRow<ColorBGRA> row = image.Rows[0];
ColorBGRA rowColorExample = row[10];

ReadOnlyRefEnumerable<ColorBGRA> column = image.Columns[0];
ImageColumn<ColorBGRA> column = image.Columns[0];
ColorBGRA columnColorExample = column[10];

RefImage<ColorBGRA> subImage = image[100, 150, 400, 300];
Expand Down
19 changes: 10 additions & 9 deletions ScreenCapture.NET.DX11/DX11ScreenCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using HPPH;
using SharpGen.Runtime;
using Vortice.Direct3D;
using Vortice.Direct3D11;
Expand All @@ -23,12 +24,12 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture<ColorBGRA>
#region Constants

private static readonly FeatureLevel[] FEATURE_LEVELS =
{
[
FeatureLevel.Level_11_1,
FeatureLevel.Level_11_0,
FeatureLevel.Level_10_1,
FeatureLevel.Level_10_0
};
];

#endregion

Expand All @@ -53,7 +54,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture<ColorBGRA>
private ID3D11DeviceContext? _context;
private ID3D11Texture2D? _captureTexture;

private readonly Dictionary<CaptureZone<ColorBGRA>, ZoneTextures> _textures = new();
private readonly Dictionary<CaptureZone<ColorBGRA>, ZoneTextures> _textures = [];

#endregion

Expand Down Expand Up @@ -135,7 +136,7 @@ protected override bool PerformScreenCapture()
}

/// <inheritdoc />
protected override void PerformCaptureZoneUpdate(CaptureZone<ColorBGRA> captureZone, in Span<byte> buffer)
protected override void PerformCaptureZoneUpdate(CaptureZone<ColorBGRA> captureZone, Span<byte> buffer)
{
if (_context == null) return;

Expand Down Expand Up @@ -188,7 +189,7 @@ protected override void PerformCaptureZoneUpdate(CaptureZone<ColorBGRA> captureZ
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void CopyRotate0(in ReadOnlySpan<byte> source, int sourceStride, in CaptureZone<ColorBGRA> captureZone, in Span<byte> buffer)
private static void CopyRotate0(ReadOnlySpan<byte> source, int sourceStride, CaptureZone<ColorBGRA> captureZone, Span<byte> buffer)
{
int height = captureZone.Height;
int stride = captureZone.Stride;
Expand All @@ -204,7 +205,7 @@ private static void CopyRotate0(in ReadOnlySpan<byte> source, int sourceStride,
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void CopyRotate90(in ReadOnlySpan<byte> source, int sourceStride, in CaptureZone<ColorBGRA> captureZone, in Span<byte> buffer)
private static void CopyRotate90(ReadOnlySpan<byte> source, int sourceStride, CaptureZone<ColorBGRA> captureZone, Span<byte> buffer)
{
int width = captureZone.Width;
int height = captureZone.Height;
Expand All @@ -220,7 +221,7 @@ private static void CopyRotate90(in ReadOnlySpan<byte> source, int sourceStride,
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void CopyRotate180(in ReadOnlySpan<byte> source, int sourceStride, in CaptureZone<ColorBGRA> captureZone, in Span<byte> buffer)
private static void CopyRotate180(ReadOnlySpan<byte> source, int sourceStride, CaptureZone<ColorBGRA> captureZone, Span<byte> buffer)
{
int width = captureZone.Width;
int height = captureZone.Height;
Expand All @@ -237,7 +238,7 @@ private static void CopyRotate180(in ReadOnlySpan<byte> source, int sourceStride
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void CopyRotate270(in ReadOnlySpan<byte> source, int sourceStride, in CaptureZone<ColorBGRA> captureZone, in Span<byte> buffer)
private static void CopyRotate270(ReadOnlySpan<byte> source, int sourceStride, CaptureZone<ColorBGRA> captureZone, Span<byte> buffer)
{
int width = captureZone.Width;
int height = captureZone.Height;
Expand Down Expand Up @@ -309,7 +310,7 @@ protected override void ValidateCaptureZoneAndThrow(int x, int y, int width, int
base.ValidateCaptureZoneAndThrow(x, y, width, height, downscaleLevel);
}

private void InitializeCaptureZone(in CaptureZone<ColorBGRA> captureZone)
private void InitializeCaptureZone(CaptureZone<ColorBGRA> captureZone)
{
int x;
int y;
Expand Down
11 changes: 5 additions & 6 deletions ScreenCapture.NET.DX11/ScreenCapture.NET.DX11.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net7.0;net6.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
Expand All @@ -27,12 +27,11 @@
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>

<PackageReleaseNotes>
- Fixed a memory-leak when disposing the ScreenCapture
</PackageReleaseNotes>

<Version>2.0.4</Version>
<AssemblyVersion>2.0.4</AssemblyVersion>
<FileVersion>2.0.4</FileVersion>
<Version>3.0.0</Version>
<AssemblyVersion>3.0.0</AssemblyVersion>
<FileVersion>3.0.0</FileVersion>

<OutputPath>..\bin\</OutputPath>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down Expand Up @@ -63,7 +62,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Vortice.Direct3D11" Version="3.2.0" />
<PackageReference Include="Vortice.Direct3D11" Version="3.5.0" />
</ItemGroup>

<ItemGroup>
Expand Down
47 changes: 9 additions & 38 deletions ScreenCapture.NET.DX9/DX9ScreenCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using ScreenCapture.NET.Downscale;
using HPPH;
using SharpGen.Runtime;
using Vortice.Direct3D9;

Expand Down Expand Up @@ -92,7 +92,7 @@ protected override bool PerformScreenCapture()
}

/// <inheritdoc />
protected override void PerformCaptureZoneUpdate(CaptureZone<ColorBGRA> captureZone, in Span<byte> buffer)
protected override void PerformCaptureZoneUpdate(CaptureZone<ColorBGRA> captureZone, Span<byte> buffer)
{
if (_buffer == null) return;

Expand All @@ -106,55 +106,26 @@ protected override void PerformCaptureZoneUpdate(CaptureZone<ColorBGRA> captureZ
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void CopyZone(CaptureZone<ColorBGRA> captureZone, in Span<byte> buffer)
private void CopyZone(CaptureZone<ColorBGRA> captureZone, Span<byte> buffer)
{
ReadOnlySpan<ColorBGRA> source = MemoryMarshal.Cast<byte, ColorBGRA>(_buffer);
Span<ColorBGRA> target = MemoryMarshal.Cast<byte, ColorBGRA>(buffer);

int offsetX = captureZone.X;
int offsetY = captureZone.Y;
int width = captureZone.Width;
int height = captureZone.Height;

for (int y = 0; y < height; y++)
{
int sourceOffset = ((y + offsetY) * Display.Width) + offsetX;
int targetOffset = y * width;

source.Slice(sourceOffset, width).CopyTo(target.Slice(targetOffset, width));
}
RefImage<ColorBGRA>.Wrap(_buffer, Display.Width, Display.Height, _stride)[captureZone.X, captureZone.Y, captureZone.Width, captureZone.Height]
.CopyTo(MemoryMarshal.Cast<byte, ColorBGRA>(buffer));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DownscaleZone(CaptureZone<ColorBGRA> captureZone, in Span<byte> buffer)
private void DownscaleZone(CaptureZone<ColorBGRA> captureZone, Span<byte> buffer)
{
ReadOnlySpan<byte> source = _buffer;
Span<byte> target = buffer;
RefImage<ColorBGRA> source = RefImage<ColorBGRA>.Wrap(_buffer, Display.Width, Display.Height, _stride)[captureZone.X, captureZone.Y, captureZone.UnscaledWidth, captureZone.UnscaledHeight];
Span<ColorBGRA> target = MemoryMarshal.Cast<byte, ColorBGRA>(buffer);

int blockSize = 1 << captureZone.DownscaleLevel;

int offsetX = captureZone.X;
int offsetY = captureZone.Y;
int width = captureZone.Width;
int height = captureZone.Height;
int stride = captureZone.Stride;
int bpp = captureZone.ColorFormat.BytesPerPixel;
int unscaledWith = captureZone.UnscaledWidth;

Span<byte> scaleBuffer = stackalloc byte[bpp];
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
AverageByteSampler.Sample(new SamplerInfo<byte>((x + offsetX) * blockSize, (y + offsetY) * blockSize, blockSize, blockSize, unscaledWith, bpp, source), scaleBuffer);

int targetOffset = (y * stride) + (x * bpp);

// DarthAffe 07.09.2023: Unroll as optimization since we know it's always 4 bpp - not ideal but it does quite a lot
target[targetOffset] = scaleBuffer[0];
target[targetOffset + 1] = scaleBuffer[1];
target[targetOffset + 2] = scaleBuffer[2];
target[targetOffset + 3] = scaleBuffer[3];
}
target[(y * width) + x] = source[x * blockSize, y * blockSize, blockSize, blockSize].Average();
}

/// <inheritdoc />
Expand Down
149 changes: 0 additions & 149 deletions ScreenCapture.NET.DX9/Downscale/AverageByteSampler.cs

This file was deleted.

Loading

0 comments on commit 44a669c

Please sign in to comment.