Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

SharpDX.SharpDXException: HRESULT: [0x8899000C], Module: [SharpDX.Direct2D1], ApiCode: [D2DERR_RECREATE_TARGET/RecreateTarget], Message: There has been a presentation error that may be recoverable. The caller needs to recreate, rerender the entire frame, and reattempt present. #567

Open
alantan opened this issue Jun 23, 2020 · 3 comments

Comments

@alantan
Copy link

alantan commented Jun 23, 2020

SharpDX.SharpDXException: HRESULT: [0x8899000C], Module: [SharpDX.Direct2D1], ApiCode: [D2DERR_RECREATE_TARGET/RecreateTarget], Message: There has been a presentation error that may be recoverable. The caller needs to recreate, rerender the entire frame, and reattempt present.

at SharpDX.Result.CheckError()
at DesktopDuplication.Direct2DEditorSession.EndDraw()
at DesktopDuplication.Direct2DEditor.GenerateFrame()
at Screna.Recorder.<>c__DisplayClass14_0.b__2()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Screna.Recorder.d__14.MoveNext()

Originally posted by @warichnict in #454 (comment)

@alantan
Copy link
Author

alantan commented Jun 23, 2020

I found a workaround solution to this problem that appears to work well in another project, but I do not trust my testing enough to suggest a commit yet.

The following appears to work for me:

  1. Putting this in EndDraw():
            try
            {
                RenderTarget.EndDraw();
            }
            catch (SharpDXException ex) when ((uint)ex.HResult == 0x8899000C)
            {
                throw new RenderTargetCorruptedException(ex);
            }

  1. Putting this in the Recorder.cs FrameWriter:
            try
            {
                frame = editableFrame.GenerateFrame(Timestamp);
            }
            catch (RenderTargetCorruptedException)
            {
                editableFrame.Dispose();
                // Retry
                return FrameWriter(Timestamp);
            }

@MathewSachin
Copy link
Owner

I think this is not safe to do. If it keeps on failing, we can get a StackOverflowException.

@alantan
Copy link
Author

alantan commented Jun 23, 2020

That's a very good point. Perhaps a limit on the number of retries? It is fairly rare, but when it happens it causes the entire recording to get corrupted. I realize this kind of solution is pretty ugly.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants