Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose pause and resume in studio #2096

Merged
merged 2 commits into from
Jun 27, 2018

Conversation

oktomus
Copy link
Member

@oktomus oktomus commented Jun 19, 2018

The new stopwatch model:

It contains following values:

  • m_start is the time when the user call start or resume
  • m_pause_time is the time when the user call pause
  • m_elapsed is the spent time of the current run + previous runs
  • m_committed is the spent time of previous runs

Actions:

  • Pressing start will set the starting time
  • Pressing start again will act as a restart, it will set the starting time again and clear the watch. start will also clear the paused state
  • Pressing pause change the state of the stopwatch. Call not allowed if the watch is already paused. This also stores the current time in m_pause_time for future measures.
  • Pressing resume change the state of the stopwatch and sets the starting time. Call not allowed if the watch isn't in the paused state. It also update start time and committed spent time
    committed time = committed_time + (now - start) - (now - pause_time)
  • Pressing clear will set all spent times to 0 but the watch will keep running if it's not paused
  • When calling measure, the watch stores the elapsed time. The whole spend time is computed as following
    whole spent time = committed_time + (now - start) - (now - pause_time)
  • get_ticks returns the whole spent time (elapsed) adjusted by the overhead

@@ -217,7 +227,8 @@ void RenderingManager::start_rendering(

bool RenderingManager::is_rendering() const
{
return m_master_renderer.get() != nullptr;
return m_master_renderer.get() != nullptr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be problematic.

When a render is paused, we're still rendering in the sense that a lot of operations (such as editing the scene) are still forbidden.

This probably needs to be reverted.

@@ -95,6 +103,10 @@ class Stopwatch

template <typename Timer>
Stopwatch<Timer>::Stopwatch(const size_t overhead_measures)
: m_paused(false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialization order must follow declaration order.

@@ -83,6 +89,8 @@ class Stopwatch
uint64 m_overhead; // measured overhead of calling start() + measure()
uint64 m_start; // timer value when start() is called
uint64 m_elapsed; // elapsed time when measure() is called, adjusted for overhead
uint64 m_stock; // elapsed time until pause() is called, adjusted for overhead
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean (in French maybe) by stock?

Copy link
Member Author

@oktomus oktomus Jun 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the time spent before calling pause

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, we'll need to find a better, more explicit name. I could help with naming but I need to fully understand how it works.

Can we call pause() multiple times?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we can't, I added an assert. But once you resume, you can call pause again

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that's what I meant. It's fine to assert if pause() is called while already in pause, but of course we should allow calling pause() and resume() multiple times. If that's what we do then great.

So, here's an idea:

  1. In measure(), you we accumulate (add) elapsed time to m_elapsed.
  2. We move the overhead subtraction to get_ticks().
  3. We get rid of m_stock.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the idea, I haven't tried to use the overhead in get_ticks which is why I had problems.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only issue with that, is that we won't be able to call measure if the timer is paused. Otherwise ticks would be wrong

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless measure() doesn't do anything if paused?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I implemented :) pushing tomorrow

@@ -155,7 +183,10 @@ inline Stopwatch<Timer>& Stopwatch<Timer>::measure()
template <typename Timer>
inline uint64 Stopwatch<Timer>::get_ticks() const
{
return m_elapsed;
if (m_paused)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest writing a bunch of unit tests to make sure that pausing a stopwatch works in all cases. You can use a custom timer that returns predetermined values to make your test deterministic and robust.

@@ -59,6 +59,9 @@ class APPLESEED_DLLSYMBOL DefaultRendererController
// This method is called after rendering was aborted.
void on_rendering_abort() override;

void on_rendering_paused() override;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add docs.

@@ -62,6 +62,9 @@ class QtRendererController
// This method is called after rendering was aborted.
void on_rendering_abort() override;

void on_rendering_paused() override;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add docs.

@@ -1630,6 +1638,14 @@ void MainWindow::slot_start_rendering_once(const QString& filepath, const QStrin
}
}

void MainWindow::slot_pause_or_resume_rendering()
{
if (m_rendering_manager.is_rendering() && !m_rendering_manager.is_rendering_paused())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need an advice for this. I suppose the slot will be called only while rendering (otherwise the widget is disabled). So the first condition is_rendering can be removed. What do you think ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, yes. You can check is_rendering() in an assert.

@@ -404,6 +405,14 @@
<string>F5</string>
</property>
</action>
<action name="action_rendering_pause_rendering">
<property name="text">
<string>Pause &amp;Rendering</string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That conflicts with &Rendering Settings. I suggest putting the & on the P of Pause.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by the way, what's the purpose of & ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It creates a keyboard shortcut: the character following the & gets underlined:

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That way you can do Alt+F followed by N to create a new project.

}

template <typename Timer>
inline void Stopwatch<Timer>::start()
{
m_paused = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From your description, start() cannot be called in pause state. This should be an assert.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I would prefer updating my description because it's really convenient to call start to restart everything

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

{
assert(m_paused);

// Update comitted time.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: committed

@@ -59,6 +59,12 @@ class APPLESEED_DLLSYMBOL DefaultRendererController
// This method is called after rendering was aborted.
void on_rendering_abort() override;

// This method is called after rendering was paused.
void on_rendering_paused() override;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with the other slots, should be on_rendering_pause() and on_rendering_resume().

@dictoon dictoon merged commit a11da58 into appleseedhq:master Jun 27, 2018
@oktomus oktomus deleted the resumable-renders branch July 10, 2018 06:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants