vlc/vlc-3.0 | branch: master | Steve Lhomme <[email protected]> | Fri Jan 15 13:50:24 2021 +0100| [bdfd31f4899d4c0febe32b902b00e9e7f2dbed00] | committer: Steve Lhomme
direct3d11: rework the rendering wait The core needs to know how long the rendering takes place to estimate when a frame needs to be dropped preemptively or not. So far we waited until the render (plus decoding and filtering?) is done before we allowed the picture swap to happen. Now we only wait until (almost) the swap date. If we still have to wait, we'll do it after the swap, hoping it will still happen in time. It is reversing the strict waiting (all?) commands issued to be processed, including all decoder threads and filters on the ID3D11DeviceContext. We no longer allow waiting past the display date and we do the swap when we're told. We no longer release the ID3D11DeviceContext lock either as it allows more commands in and makes the waiting time/performance worse. We do wait until the initial wait condition is done, if anything to silence some D3D11 warnings saying we wanted to wait for something but never got to the point it was actually finished. It also keeps the waiting in the display thread so it doesn't think it can do more things when it's still busy with the previous call. This will allow it do drop frames more accurately. A cleaner way would be to count the Display call in the time to render of the core, but it's not possible as in some case we wait and the work is actually finished and in some others we wait and the work is not finished. We can't tell the difference in the core. Fixes #21600 (cherry picked from commit 42011b9fb105b4b5de832fdafd097b86c8154eda) (edited) edited: - this branch doesn't pass the render date to prepare. We use display->date instead which ends up being similar, in pause we'll wait more in the display - this branch didn't use vlc_tick_t Signed-off-by: Steve Lhomme <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=bdfd31f4899d4c0febe32b902b00e9e7f2dbed00 --- modules/video_output/win32/direct3d11.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c index 9c6e318abf..fe659a6d5a 100644 --- a/modules/video_output/win32/direct3d11.c +++ b/modules/video_output/win32/direct3d11.c @@ -1000,11 +1000,15 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic while (S_FALSE == ID3D11DeviceContext_GetData(sys->d3d_dev.d3dcontext, sys->prepareWait, NULL, 0, 0)) { - if (is_d3d11_opaque(picture->format.i_chroma)) - d3d11_device_unlock( &sys->d3d_dev ); - SleepEx(2, TRUE); - if (is_d3d11_opaque(picture->format.i_chroma)) - d3d11_device_lock( &sys->d3d_dev ); + mtime_t sleep_duration = (picture->date - mdate()) / 4; + if (sleep_duration <= 2 * CLOCK_FREQ / 1000) + { + // don't wait any longer, the display will likely be late + // we'll finish waiting during the Display call + break; + } + // wait a little until the rendering is done + SleepEx(sleep_duration * 1000 / CLOCK_FREQ, TRUE); } } @@ -1025,6 +1029,22 @@ static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpic /* TODO device lost */ msg_Err(vd, "SwapChain Present failed. (hr=0x%lX)", hr); } + + if (sys->prepareWait) + { + mtime_t start = 0; + while (S_FALSE == ID3D11DeviceContext_GetData(sys->d3d_dev.d3dcontext, + sys->prepareWait, NULL, 0, 0)) + { + if (start == 0) + start = mdate(); + SleepEx(2, TRUE); + } + if (start != 0 && var_InheritInteger(vd, "verbose") >= 4) + msg_Dbg(vd, "rendering wasn't finished, waited extra %lld ms", + (mdate() - start) * 1000 / CLOCK_FREQ); + } + d3d11_device_unlock( &sys->d3d_dev ); picture_Release(picture); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
