-
Notifications
You must be signed in to change notification settings - Fork 193
Open
Description
Hey Rob!
My app takes a screenshot of multiple selected windows every 30 seconds in a loop.
The way the screenshots are taken is by using this service -
public class ScreenshotService
{
private IDirect3DDevice device;
private SharpDX.Direct3D11.Device d3dDevice;
public ScreenshotService()
{
device = Direct3D11Helper.CreateDevice();
d3dDevice = Direct3D11Helper.CreateSharpDXDevice(device);
}
public async Task<Image> Screenshot(GraphicsCaptureItem item)
{
// create add texture2D 2D accessible by the CPU
var desc = new Texture2DDescription()
{
Width = item.Size.Width,
Height = item.Size.Height,
CpuAccessFlags = CpuAccessFlags.Read,
Usage = ResourceUsage.Staging,
Format = Format.B8G8R8A8_UNorm,
ArraySize = 1,
MipLevels = 1,
SampleDescription = new SampleDescription(1, 0),
};
using var cpuTexture = new Texture2D(d3dDevice, desc);
var taskCompletionSource = new TaskCompletionSource<Direct3D11CaptureFrame>();
using var framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(
device,
DirectXPixelFormat.B8G8R8A8UIntNormalized,
1,
item.Size);
framePool.FrameArrived += (sender, a) =>
{
if (!taskCompletionSource.Task.IsCompleted) taskCompletionSource.SetResult(sender.TryGetNextFrame());
};
using var session = framePool.CreateCaptureSession(item);
session.StartCapture();
using var frame = await taskCompletionSource.Task;
using (var bitmap = Direct3D11Helper.CreateSharpDXTexture2D(frame.Surface))
{
// add this to copy the DirectX resource into the CPU-readable texture2D
d3dDevice.ImmediateContext.CopyResource(bitmap, cpuTexture);
}
// get IDirect3DSurface from texture
using var surf = Direct3D11Helper.CreateDirect3DSurfaceFromSharpDXTexture(cpuTexture);
// build a WinRT's SoftwareBitmap from this surface/texture
using var softwareBitmap = await SoftwareBitmap.CreateCopyFromSurfaceAsync(surf);
using var InMemoryStream = new InMemoryRandomAccessStream();
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, InMemoryStream);
encoder.SetSoftwareBitmap(softwareBitmap);
await encoder.FlushAsync();
using var stream = InMemoryStream.AsStream();
return Image.Load(stream);
}
public void Dispose()
{
device.Dispose();
d3dDevice.Dispose();
}
}The service is initialized once, and the Screenshot(item) method is the one that's being called in a loop.
I and a few others using my app (on Windows 10 and 11) reported odd OS lags after letting the app run for a while.
Such as -
- Delays in opening the Windows Start menu (can take 30 seconds and even more).
- Delays and lags in using native Windows apps such as a snipping tool. (doesn't open, or doesn't work right).
- One user also reported that after closing the app, he still sees the screen capture yellow border mark around one of his windows, how could that even be possible?
Everything else works just fine, it's only the OS-related apps that seem to go nuts.
Looking at the app CPU/RAM consumption after a few days of running seems to be reasonable and steady -
1% CPU
80-100MB RAM
By the way, the issues above persist even after closing the app... only fixed after a restart.
Thanks, Ben
Metadata
Metadata
Assignees
Labels
No labels