[confirm] TV Guide border highlight causing render exception (1 Viewer)

tourettes

Retired Team Member
  • Premium Supporter
  • January 7, 2005
    17,301
    4,800
    However, When scrolling fast, I get DirectX errors in log E_OUTOFMEMORY - seems, that textures are faster pushed to render device, than are disposed - maybe @tourettes can you comment? Will your maps solve such issues?

    I guess @Scythe42 is much better person to answer any DirectX (or even Skin Engine) resource management issues. Are we relying on the GC to dispose the textures and therefore they are left "over" for extensive preriods of time? Or are we assuming that every texture that is loaded in a view is required by the EPG all the time so they aren't even tried to be disposed?
     

    Brownard

    Development Group
  • Team MediaPortal
  • March 21, 2007
    2,290
    1,872
    Home Country
    United Kingdom United Kingdom
    • Thread starter
    • Moderator
    • #12
    You could get an IndexOutOfRange using @Guzzi 's fix if, on the last iteration, the last control is removed between the for statement and accessing the control via the indexer.
     

    Guzzi

    Retired Team Member
  • Premium Supporter
  • August 20, 2007
    2,161
    747
    Added branch to mantis - pls check:
    https://github.com/MediaPortal/MediaPortal-1/tree/EXP-3868-Fix_Flicker_Issue_on_EPG
    Note: We possibly might need a null check (in case the element is removed from collection while we're processing it) - I didn't do it, as it is already done in many (but not all) method calls and I didn't have a problem so far.

    It cures the .NET "collection modified" error, but it wont cure the logical issue we have. The collection content might be modified during the rendering pass so it is still possible to access an item that has been freed (unles .NET takes care of not freeing the item) or possible to skip some items if the collection receives new items while it is being iterated thru.
    I am aware of that - but changing that properly requires a lot more changes and making it threadsafe - that should be done by someone who knows the skinengine better in details - so I decided to limit the change just to avoid the exception causing the flickering (which is NOT curing the root cause, yes).
    In this case it is the EPG calling in in GUIWindow
    Code:
        public void SendToFront(ref GUIControl ctrl)
        {
          // Remove the control from the collection and add it back to the end of the collection.
          Remove(ctrl.GetID);
          Add(ref ctrl);
        }
     

    Guzzi

    Retired Team Member
  • Premium Supporter
  • August 20, 2007
    2,161
    747
    You could get an IndexOutOfRange using @Guzzi 's fix if, on the last iteration, the last control is removed between the for statement and accessing the control via the indexer.
    Yes, true. At least it is down to exactly this one iteration, instead of the whole enumeration. But as mentioned above, it doesn't solve the root case anyway (that those areas are not threadsafe and there is a lot of other parts affected too, even if we currently are not affected in GUI, as most stuff is used synchronously)
     

    Guzzi

    Retired Team Member
  • Premium Supporter
  • August 20, 2007
    2,161
    747
    Best practice in such cases is running the for-next starting with highest menber and going down - like that:
    Code:
              for (int i = Children.Count - 1; i >= 0; i--)
              {...}
    But I think we must not do that in the renderloop, as the order of the controls must be like that (ascending).
     

    Brownard

    Development Group
  • Team MediaPortal
  • March 21, 2007
    2,290
    1,872
    Home Country
    United Kingdom United Kingdom
    • Thread starter
    • Moderator
    • #16
    The guide gets a lock on itself anyway when it renders, could you not just put a lock around SendToFront() in SetFocusBorder as this is the only offending method - I know it doesn't fix the underlying thread (un)safety but it does fix the current problem with no modifications to the base code
     

    Guzzi

    Retired Team Member
  • Premium Supporter
  • August 20, 2007
    2,161
    747
    ... how about using the RenderLayer lock in Add/Remove methods in GUIWindow.cs?

    Code:
    lock (GUIGraphicsContext.RenderLock)
     
    {...}
     

    Scythe42

    Retired Team Member
  • Premium Supporter
  • June 20, 2009
    2,065
    2,703
    50
    Berlin
    Home Country
    Germany Germany
    I guess @Scythe42 is much better person to answer any DirectX (or even Skin Engine) resource management issues. Are we relying on the GC to dispose the textures and therefore they are left "over" for extensive preriods of time? Or are we assuming that every texture that is loaded in a view is required by the EPG all the time so they aren't even tried to be disposed?
    Currently the skin engine tracks in a variable if the resources have been loaded and on sometimes just dispose them and re-load them anyway. The are rarely properly disposed and sometimes even require manual calls to allocation/disposing. Code is just bad here. It grew over the years without heading into direction for all the cases. This can only be solved be rewriting.

    Proper Texture mangement is alreay in the works. It will work like this:
    • As soon as a texture file is accessed it is automatically loaded. Rest of the code doesn't need to care about it at all.
    • It will never be disposed as long as MP runs if it is a texture from a skin. We don't really use much GPU memory for the skin anyway. And because it is essential the stuff should always be in memory.
    • other texture are treated as dynamic stuff (e.g. backdrops, covers) and use up to a configurable amout of memory in a pool (basically making good use of availalbe VRAM).
    • textures are loaded in their resolution they are stored in, there is no scaling taking place anymore. This will happen in rendering instead as it should
    • textures are backed up by system memory, so we do not need to reload them on device resets
    • other stuff like vertices are re-created on device resets.
    • Texture atlas as a cache will be removed. Performance loss because of texture switching is minimal compared to our current D3D state handling.
    In the end you just get a few new methods in the code for accessing a texture. The new texture manager will take care of everything in the background. Old methods will be marked as obsolete and make proper calls to the new texture manager.

    This is essential for anything else rendering releated. A decent transparent resource manager. You give it a file-name relatively to a skin/theme base and the texture manager does everything in the background.

    We can then build on it for additional rendering features (1st one: replace font engine and 3D support).
     

    Guzzi

    Retired Team Member
  • Premium Supporter
  • August 20, 2007
    2,161
    747
    • textures are loaded in their resolution they are stored in, there is no scaling taking place anymore. This will happen in rendering instead as it should

    • Will that also enable us to e.g. have a really fast picture viewer ? As I noticed, we currently do rescaling before sending image to the device, which takes ages - would be interesting to test that also with respect to (scaling) quality ...
     

    Scythe42

    Retired Team Member
  • Premium Supporter
  • June 20, 2009
    2,065
    2,703
    50
    Berlin
    Home Country
    Germany Germany
    Yes, picture viewer will be as fast as data can be loaded from the HDD and send to the GPU. Rescaling will be done by the GPU upon rendering.

    No special scaling shaders yet implemented, so it is just D3D9 out of the box. Shader support will be added for video playback, but of course shaders for pictures can be added as well. Just some more HLSL code. Need to read up what is recommended to scale pictures instead of videos by the GPU.

    As not every frame needs to be processed again it makes sense to render pictures using a shader to another texture that is than displayed and not processed again. And timing isn't essential here, so we can go for a very high quality shader here. No need to render at 60fps all the time.

    In fact all post processing works this way. You render a lot of stuff from textures to a final screen quad (just a texture in screen resolution) which is than shown to the user. All the steps in between are just various passes on what you want to achieve and live deep down in GPU memory.

    There are tons of effect files out there. Just need to google a bit and throw them in. Once we have shader support coded in it is just a matter of selecting a shader when rendering to use a different effect. One line of code that just selects the shader (shader object class will of course load them if needed) is needed in the rendering loop. Which kind depends on the rendering pass we are in or what we are displaying.

    Later I'll add background caching, so that MP preloads pictures, covers, backdrops etc. when being idle. But first all the texture stuff needs to be rewritten.

    All the D3D features should be complete for 1.4.0. Parts that are ready early can already be but in into the 1.3.x release line if it makes sense and can stand on their own.
     
    Last edited:

    Users who are viewing this thread

    Top Bottom