Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: event-driven rendering (instead of rendering at each main loop iteration)?  (Read 6664 times)

0 Members and 3 Guests are viewing this topic.

Conan

  • Newbie
  • *
  • Posts: 4
    • View Profile
Hi

the examples i tried work nicely, but they hog the CPU because the window is re-drawn at every iteration of the main loop. While this is certainly what you'd want for an action game that has to re-render constantly as fast as possible because every frame is different, it's not what you'd want for an event-driven application where the rendering content only rarely changes (e.g. a drawing program or actually most type of non-game application software that doesn't show animations). So i tried to change the event processing so as to only redraw the window when either of these happens:
* resize
* exposure (even partial; e.g.: some other window is dragged over my window and hides a part of it during this process. Each obstructed part of my window has to be redrawn when the other window isn't hiding it any more)
* reactions to user interaction (e.g. ui elements changing appearance because of a click on an active region)

My problem:
When i look at sf::Event::EventType, i do see sf::Event::Resized  but no event type that would correspond to an Expose Event. Is there something i'm missing there? I don't see how to develop an event-driven main loop (i.e. one that does not constantly re-render even if nothing happens) without an expose event. So how would you guys do it?

Is there some example somewhere that would use sfml like that?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #1 on: November 12, 2012, 08:46:08 pm »
SFML is not designed to work like this, it's made for real-time rendering. What you need is a windowing/GUI library designed for desktop apps (Qt, wxWidgets, GTK, etc.).

By the way, if you enable v-sync or framerate limit, an SFML app can consume less than 1% CPU.
Laurent Gomila - SFML developer

Conan

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #2 on: November 12, 2012, 09:43:20 pm »
thanks for the quick answer.
Actually, i do come from such gui libraries (i'm mainly using Qt these last years but have used bot wx and gtk before).
My intent though was to switch my gui stuff to OpenGL only to cut the bloat (these frameworks have become terribly bloated),  be more independent of them and optimize my GUI. Besides, i do need full control of the main loop and the ability to do full speed OpenGL and realtime rendering sometimes too. Since i'm only doing OpenGL anyways, SFML would fit nicely as a system abstraction layer for my purposes except for the fact that i don't see how to do that expose event thingie.
Unfortunately, solving the CPU hogging with an artificial frame rate limitation would hurt me when i actually need the full frame rate (e.g. when dragging stuff around or in widget change animations).
Now i do understand that my use case may diverge somehow from that of most SFML users and its primary architectural target, but if it was just that nobody needed to pass through the expose events of the window system so far, then i guess it shouldbe feasable to add that... if it's mostly just that, then i would give it a try.
Or does the "not designed to work like this" imply that there might be some other, bigger problems with using SFML for desktop applications that use event-based rendering most of the time?
« Last Edit: November 12, 2012, 09:46:05 pm by Conan »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #3 on: November 12, 2012, 09:51:30 pm »
Quote
Unfortunately, solving the CPU hogging with an artificial frame rate limitation would hurt me when i actually need the full frame rate
You get "full" framerate with v-sync, and it's limited enough so that your app uses almost no CPU. Don't overcomplicate things ;)
That's what Qt does by the way, their QML API in Qt5 is based on OpenGL with v-sync enabled and it runs smoothly with lots of UI animation and fancy stuff. And it works equally well on desktop and mobile devices.

Quote
Or does the "not designed to work like this" imply that there might be some other, bigger problems with using SFML for desktop applications that use event-based rendering most of the time?
I don't think there would be any problem, but I don't want to support this way of doing things.
However you can easily hack inside SFML to forward the events that you need in sf::Event.
Laurent Gomila - SFML developer

trilavia

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #4 on: November 12, 2012, 10:03:15 pm »
@up (vsync reducing cpu usage)

Unfortunately, it is not true. As I said in my topic, there is ati driver related opengl bug, which causes 99% gpu usage on vsynced apps, and what's more (i hadn't mentioned it, but now i realised it) the cpu usage is only 40% instead of 50% when vsync is on. So yea, vsync and sfml is great on nvidia cards, but on ati unfortunately vsync increases gpu usage and reduces cpu usage only by 10 % (50% -> 40%). That's a bad bug, isn't it :(? It's a shame that you say it's driver related, because using vsync in sfml has no purpose on amd cards.

Solution? Well, directx vsync works flawlessy on amd cards. I hope one day it will get fixed...
« Last Edit: November 12, 2012, 10:06:27 pm by trilavia »

cire

  • Full Member
  • ***
  • Posts: 138
    • View Profile
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #5 on: November 12, 2012, 10:05:39 pm »

Unfortunately, solving the CPU hogging with an artificial frame rate limitation would hurt me when i actually need the full frame rate (e.g. when dragging stuff around or in widget change animations).

I'm not sure I see the problem.  When you don't want the limit, don't set the limit.  It's not like you need to make a choice now and it's set in stone for every application you generate from here on out (or even within a single application.) Also if you don't want to update/render when there are no events processed, don't.

while ( window.isOpen() )
{
    bool eventsProcessed = false ;
    sf::Event event ;
    while ( window.pollEvent(event) )
    {
        eventsProcessed = true ;
        // process events
    }

    if ( eventsProcessed )
   {
       window.clear() ;
       //  stuff ...
       window.display() ;
   }
   else
   {
       // ...
   }
}

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #6 on: November 12, 2012, 10:07:39 pm »
Unfortunately, it is not true. As I said in my topic, there is ati driver related opengl bug, which causes 99% gpu usage on vsynced apps, and what's more (i hadn't mentioned it, but now i realised it) the cpu usage is only 40% instead of 50% when vsync is on. So yea, vsync and sfml is great on nvidia cards, but on ati unfortunately vsync increases gpu usage and reduces cpu usage only by 10 % (50% -> 40%). That's a bad bug, isn't it :(? It's a shame that you say it's driver related, because using vsync in sfml has no purpose on amd cards.
No problem here, don't generalize. Must be something with your driver or your card only.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

trilavia

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #7 on: November 12, 2012, 10:12:19 pm »
Nah, as I said it happens on windows 32 bit, linux 64 bit, newest drivers, one year old drivers. It affects every radeon hd 6xxx for sure, maybe older work good. Even 6xxx series is enough to say that there is a problem. Have you tried it btw? Looking at gpu and cpu usage?

Just look at code here http://en.sfml-dev.org/forums/index.php?topic=9603.0 . I'd be surprised if you don't have this bug, because on every amd card i tested it the bug existed.
« Last Edit: November 12, 2012, 10:22:27 pm by trilavia »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #8 on: November 12, 2012, 10:49:35 pm »
Nope no problem here. ;D

I'm on a HD 6470M, GPU usage 1.3%, CPU usage 0.9%, but I think I'm running on an old driver, since HP does their on quirks on the drivers, so one can't use the most recent one.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

trilavia

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #9 on: November 13, 2012, 07:52:41 am »
That's kinda strange, because I'm not the only one with opengl anti aliasing on amd cards problem. Maybe AMD fucked up something in new drivers... Or maybe it is 8xx series chip related, because every card i tested mysefl was 8xx. I don't know, but it makes the bug even harder to track. It for sure exist, but now I see that only on some amd cards. I must try open amd linux driver, I bet using them vsync will work fine. Blame you amd.

edit:
Well, on open amd graphic drivers on linux i get 35% cpu usage and gpu usage is high too. On linux/windows catalyst it's even worse. I have no idea...
I can think that this is only my gpu related bug, but I'm not the only one who experiences this on opengl vsync. No idea :/
« Last Edit: November 13, 2012, 08:08:21 am by trilavia »

didii

  • Full Member
  • ***
  • Posts: 122
    • View Profile
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #10 on: November 13, 2012, 01:08:56 pm »
Maybe AMD fucked up something in new drivers...
Well, AMD generally sucks in my opinion. I have one too and it's the cause of ALL problems on my computer. I get random BSOD and when my pc is going to sleep or hibernate, it will never get past the screen "Windows Resuming" without hanging or giving me another BSOD. And while updating to a newer version of my driver card I always got a BSOD no matter what I did.
I did heard more about AMD and AA that those aren't a good combination. You could search some forums. Chances are less likely to have an expert on this forum :)

Oh and worst of all: AMD knows of these issues but never ever fixes them. The BSOD-"bug" (if you can still call it a bug) is already present since 12.4 I think (now 12.10) and lots of people are complaining about it.

Conan

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #11 on: November 13, 2012, 09:15:07 pm »
I'm not sure I see the problem.  When you don't want the limit, don't set the limit.  It's not like you need to make a choice now and it's set in stone for every application you generate from here on out (or even within a single application.) Also if you don't want to update/render when there are no events processed, don't.

i tried to do it like in your code suggestion. The problem is that it doesn't process expose events. Therefore, when a window or parts of it has to be redrawn (for example because some drag&drop or window moving partially in front of it) i don't get any event for that => the parts of my window that have been lost are not redrawn.

cire

  • Full Member
  • ***
  • Posts: 138
    • View Profile
Re: event-driven rendering (instead of rendering at each main loop iteration)?
« Reply #12 on: November 14, 2012, 12:54:03 am »
i tried to do it like in your code suggestion. The problem is that it doesn't process expose events.

You could keep track of the time since the last time you drew the window and update/redraw periodically if the time is excessive.  Or you could implement an OS-specific solution.

 
   const sf::Time maxTimeNotDisplayed = sf::seconds(1.0/20.0f) ;

    window.display() ;
    sf::Clock lastDisplay ;
    while ( window.isOpen() )
    {
        bool eventsProcessed = false ;
        sf::Event event ;
        while ( window.pollEvent(event) )
        {
            eventsProcessed = true ;
            // process events
        }

        if ( eventsProcessed || lastDisplay.getElapsedTime() > maxTimeNotDisplayed )
        {
            window.clear() ;
            //  stuff ...
            window.display() ;
            lastDisplay.restart() ;
        }
        else
        {
            // ...
        }
    }

 

anything