Skip to content

Multiple screen captures in a loop cause explorer.exe and native Windows app to lag? #122

@BenShapira

Description

@BenShapira

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 -

  1. Delays in opening the Windows Start menu (can take 30 seconds and even more).
  2. Delays and lags in using native Windows apps such as a snipping tool. (doesn't open, or doesn't work right).
  3. 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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions