[PATCH] Direct3D Smooth (delayed) resize
I've developed a smooth resize patch when in slave mode (WinID >= 0). The rationale is that currently (before the patch) resize_d3d() is fired on each resize event, which happens many time per second when the window is progressively being resized. This leads to many destroy/create surfaces and Direct3DDevice resets, which translates into skipped frames, no picture at all and general jerkiness. You can test it with MPUI/SMPlayer. My patch (active ONLY in slave mode) schedules a call to resize_d3d() on each resize event. In render_d3d_frame() a check is performed and if a resize event is scheduled and at least some time has passed since the last resize event (it's a milliseconds #define), the resize is performed. Multiple quick resize events just reset the timer (delay the real resize). What happens is that when the window is being resized, no Direct3DDeviceReset is called immediately, but let's say 100ms after the last window dimensions change. This enables very smooth resize of both MPUI and SMplayer and once the user stops moving the window border for 100ms (adjustable), the Reset occures and the user sees just a quick "flash" when the new rendering context takes place. This is not noticeable at all. I've also changed StretchRect's error message (Unable to copy....) from MSG_ERR to MSG_V, because this is not really an error (we handle it) and it used to happen very often when resizing fast before this patch (yet, after the patch I still assume that it may happen when those 100ms have just passed, we call Reset again, but the user decides to resize exactly at this very moment).
Hmm, it introduces a delayed d3d_resize when going to / back from fullscreen, so I'll post a updated patch to fix it.
On Tue, Dec 09, 2008 at 12:46:24PM +0200, Georgi Petrov wrote:
Hmm, it introduces a delayed d3d_resize when going to / back from fullscreen, so I'll post a updated patch to fix it.
I'd consider it more worthwhile to see if the initialization can be made faster first. I know the situation is different, but vo_gl can handle resizing in real-time just fine (not sure if it still flickers a bit in Windows).
I'd consider it more worthwhile to see if the initialization can be made faster first.
Do you have any suggestions? I tried anything I could think of, but in the end you just have to free all those surfaces (offscreen/backbuffer) and textures (for OSD), do a Reset and allocate them again. It can't be faster than that. As we know without a Reset, the backbuffer has wrong dimensions which results in ugly aliasing. I think it's more natural to do what this patch offers. I'll fix the fullscreen very soon and you can test how smooth it behaves.
I know the situation is different, but vo_gl can handle resizing in real-time just fine (not sure if it still flickers a bit in Windows).
In SMPlayer it flickers A LOT. In MPUI it just doesn't display anything until you release the window or resize it reaaaaaaly slow. Normal resizing results in flicker (SMplayer) or absence of any image at all (MPUI). This is for vo_gl. You may try it on a Windows PC. Direct3D is the same without the patch, but VERY smooth with the patch applied. Expect soon a fixed patch ready for testing. Please - try vo_gl on Windows. Can somebody else try as well?
On Wed, Dec 10, 2008 at 12:44:02PM +0200, Georgi Petrov wrote:
I'd consider it more worthwhile to see if the initialization can be made faster first.
Do you have any suggestions? I tried anything I could think of
I don't know yet, but allocating a larger backbuffer might be an option, and also never resetting when the Window size is reduced. I have no idea if that would actually work, it's just one thing maybe worth trying.
On Wed, Dec 10, 2008 at 12:44:02PM +0200, Georgi Petrov wrote:
I know the situation is different, but vo_gl can handle resizing in real-time just fine (not sure if it still flickers a bit in Windows).
In SMPlayer it flickers A LOT.
Yes, I just noticed that ATI drivers are very buggy once more, even on Linux. It looked nice enough with NVidia drivers... (I guess you use ATI, too)
In SMPlayer it flickers A LOT.
Yes, I just noticed that ATI drivers are very buggy once more, even on Linux. It looked nice enough with NVidia drivers... (I guess you use ATI, too)
No, I have Geforce 7600 GS and it's not pleasant at all. I have a laptop with ATI Mobility Radeon M6 as well, but just today I realized that my video out doesn't work at all! I'll investigate this and if I find a fix, I'll post a patch. Back on the topic: What exactly you don't like about the patch? It's perfectly fine IMHO. I don't do anything bad. Allocating larger backbuffer or don't resizing on window shrinking is not an option. I tried all possible combinations and the video look aliased. A Reset needs to be done. But Reset triggers a black screen for a couple of milliseconds - there's no way around it. I'll try to do a little bit research on the internet and see how other players handle this issue. I can look at VLC's code as well as Media Player Classic.
On Wed, Dec 10, 2008 at 02:56:15PM +0200, Georgi Petrov wrote:
Back on the topic: What exactly you don't like about the patch? It's perfectly fine IMHO. I don't do anything bad.
Well, firstly I do not see a good reason for the -wid special-case: either the flicker is annoying or it is not, whether SMPlayer is used or not is not relevant. Such inconsistencies in behaviour are also a major pain for long-term maintenance, for example because it means when a user reports "video breaks when resizing" you now have to ask if they use a Gui, because you use different code then. Secondly, I think we agree that it is not a perfect solution (I'd tend to even call it a hack) so I wanted to be sure you looked enough that we can be reasonably sure there is no better solution. Thirdly, it could be considered a bug workaround. I don't think there is any technical necessity why the driver could not reset, reinitialize and redraw in such a way that it is impossible to notice and gets at least 25 fps with current hardware. Under this aspect, since what your patch is non-optional it makes those with good drivers (which admittedly may not exist) suffer just because most drivers are bad. And no, I don't claim the patch is bad. But I think you can do at least a bit better, and possibly even a lot better. Greetings, Reimar Döffinger
Reimar, you inspired me! I'll try to deliver a far better patch. Actually I found what I was looking for. Taken from the net:
On CreateDevice, choose backbuffer-dimensions large enogh to fit a maximized window.
On windows-messages about window resizing, set d3d9's vieport dimensions to the size of the window's client area.
Tonight I'll experiment with allocating fullscreen-sized backbuffer and changing only this "viewpoint" on resize events!
Hello, On Wed, Dec 10, 2008 at 03:49:11PM +0200, Georgi Petrov wrote:
Tonight I'll experiment with allocating fullscreen-sized backbuffer and changing only this "viewpoint" on resize events!
Just two minor things you might want to keep in mind: 1) A non-fullscreen video window might be larger than the (fullscreen)screen size. 2) Backbuffer takes up video memory. It might be kind to not always allocate excessive amounts, preferably it should not become completely impossible to play a 320x200 video just because you have two monitors with 1920x1080 resolution attached to a low-end 32 MB card (yes, an unlikely situation, that's why I said "preferably").
Ok, I'll update you with my status and achievements later.
participants (2)
-
Georgi Petrov -
Reimar Döffinger