Difference between revisions of "Dev:Adding a Render progress bar"
(Create + 1st part) |
(2nd part) |
||
Line 14: | Line 14: | ||
After all, this is a kind of information! | After all, this is a kind of information! | ||
+ | === How does really a render work? === | ||
+ | '''App''' ([https://github.com/synfig/synfig/blob/master/synfig-studio/src/gui/app.h .h][https://github.com/synfig/synfig/blob/master/synfig-studio/src/gui/app.cpp .cpp]) is the root of everything and used to store globals.<br /> | ||
+ | But we start in fact from '''CanvasView''' ([https://github.com/synfig/synfig/blob/master/synfig-studio/src/gui/canvasview.h .h][https://github.com/synfig/synfig/blob/master/synfig-studio/src/gui/canvasview.cpp .cpp]) which contains the call to display the '''RenderSettings''' Dialog ([https://github.com/synfig/synfig/blob/master/synfig-studio/src/gui/render.h .h][https://github.com/synfig/synfig/blob/master/synfig-studio/src/gui/render.cpp .cpp]).<br /> | ||
+ | Then we press on render button which leads to execute an '''AsyncRender''' ([https://github.com/synfig/synfig/blob/master/synfig-studio/src/gui/asyncrenderer.h .h][https://github.com/synfig/synfig/blob/master/synfig-studio/src/gui/asyncrenderer.cpp .cpp]) (or 2, sequentially, if we have a second pass for Alpha extraction).<br /> | ||
+ | '''AsyncRenderer''' can have 4 types of targets, ''AsyncTarget_Cairo'', AsyncTarget_Cairo_Tile, ''AsyncTarget_Scanline'', AsyncTarget_Tile.<br /> | ||
+ | Only ''AsyncTarget_Cairo'' and ''AsyncTarget_Scanline'' have a ''frame_ready()'' function that we will use to implement our call to update to the Render ProgressBar.<br /> | ||
+ | |||
+ | Note that we can have 2 passes, this has to be considered when displaying the percents of accomplished render.<br /> | ||
== Implementation == | == Implementation == | ||
=== synfig-studio/src/gui/docks/dock_info.h === | === synfig-studio/src/gui/docks/dock_info.h === | ||
* Declare the components and members<br /> | * Declare the components and members<br /> | ||
− | In #include section | + | In #include section: |
#include <gtkmm/progressbar.h> | #include <gtkmm/progressbar.h> | ||
− | In private section | + | In private section: |
Gtk::ProgressBar render_progress; | Gtk::ProgressBar render_progress; | ||
Line 29: | Line 37: | ||
int n_passes_pending; | int n_passes_pending; | ||
− | In public section | + | In public section: |
//! Current render progress - 0.0 to 1.0 | //! Current render progress - 0.0 to 1.0 | ||
// depends on n_passes_requested and current_pass | // depends on n_passes_requested and current_pass | ||
Line 37: | Line 45: | ||
=== synfig-studio/src/gui/docks/dock_info.cpp === | === synfig-studio/src/gui/docks/dock_info.cpp === | ||
+ | * Here we will implement the UI and members | ||
+ | In #include section: | ||
+ | #include "app.h" | ||
+ | #include <gtkmm/progressbar.h> | ||
+ | ''It will permit to access our App::dock_info_ as a static from anywhere in the application'' | ||
+ | |||
+ | In Dock_Info(), at the end: | ||
+ | //Render Progress Bar | ||
+ | table->attach(*manage(new Gtk::Label(_("Render Progress: "))),0,1,5,6,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL); | ||
+ | table->attach(render_progress, 0,5,6,7,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL); | ||
+ | |||
+ | render_progress.set_show_text(true); | ||
+ | render_progress.set_text(strprintf("%.1f%%", 0.0)); | ||
+ | render_progress.set_fraction(0.0); | ||
+ | //Another spacer | ||
+ | table->attach(*manage(new Gtk::Label),0,5,7,8); | ||
+ | |||
+ | ''just before table->show_all();'' | ||
+ | |||
+ | ''and after add(*table);'' | ||
+ | |||
+ | //Render progress | ||
+ | set_n_passes_requested(1); //Default | ||
+ | set_n_passes_pending (1); //Default | ||
+ | set_render_progress (0.0); //Default, 0.0% | ||
+ | |||
+ | Then at the end of the file, we add these 3 functions: | ||
+ | |||
+ | void studio::Dock_Info::set_n_passes_requested(int value) | ||
+ | { | ||
+ | n_passes_requested = value; | ||
+ | } | ||
+ | |||
+ | void studio::Dock_Info::set_n_passes_pending(int value) | ||
+ | { | ||
+ | n_passes_pending = value; | ||
+ | } | ||
+ | |||
+ | void studio::Dock_Info::set_render_progress(float value) | ||
+ | { | ||
+ | float coeff = (1.000 / (float)n_passes_requested); //% of fraction for 1 pass if more than 1 pass | ||
+ | float already_done = coeff * (float)(n_passes_requested - n_passes_pending -1); | ||
+ | float r = ( coeff * value ) + already_done; | ||
+ | |||
+ | render_progress.set_text( strprintf( "%.1f%%", r*100 )); | ||
+ | render_progress.set_fraction(r); | ||
+ | } | ||
+ | |||
+ | The 2 first ones are obvious, the last one does the calculation for the display of the current percents of the WHOLE TASK.<br /> | ||
+ | If we have only 1 pass, value will be reflected directly.<br /> | ||
+ | In case of 2 (or more, who knows what will be implemented later!), each pass will still continue to send its progress as if it was the only one in the world; we will do the adjustments here.<br /> | ||
+ | 100% of pass 1 while be displayed as 50%.<br /> | ||
+ | 100% of pass 2 while be displayed as 100%.<br /> | ||
+ | If we had 3 passes, it would be 33.3%, 66.6% and 100.0%<br /> |
Revision as of 22:52, 3 January 2019
Now let's implement a Render Progress Bar!
It has been requested several time:
Indication needed that rendering is in progress. #383
Feature request: Give feedback when rendering is happening and complete #626
also in Default render parameter are bad #464
Contents
Things to take into account
- Where to place the Progress Bar?
- How does really a render work?
- Where to do calls and implementation?
Where to place the Progress Bar?
I chose to implement it in the Dock_Info panel.
After all, this is a kind of information!
How does really a render work?
App (.h.cpp) is the root of everything and used to store globals.
But we start in fact from CanvasView (.h.cpp) which contains the call to display the RenderSettings Dialog (.h.cpp).
Then we press on render button which leads to execute an AsyncRender (.h.cpp) (or 2, sequentially, if we have a second pass for Alpha extraction).
AsyncRenderer can have 4 types of targets, AsyncTarget_Cairo, AsyncTarget_Cairo_Tile, AsyncTarget_Scanline, AsyncTarget_Tile.
Only AsyncTarget_Cairo and AsyncTarget_Scanline have a frame_ready() function that we will use to implement our call to update to the Render ProgressBar.
Note that we can have 2 passes, this has to be considered when displaying the percents of accomplished render.
Implementation
synfig-studio/src/gui/docks/dock_info.h
- Declare the components and members
In #include section:
#include <gtkmm/progressbar.h>
In private section:
Gtk::ProgressBar render_progress; //! Number of passes request - 1 or 2 (if alpha) int n_passes_requested; //! Number of passes pending - 2,1,0 int n_passes_pending;
In public section:
//! Current render progress - 0.0 to 1.0 // depends on n_passes_requested and current_pass void set_render_progress (float value); void set_n_passes_requested(int value); void set_n_passes_pending (int value);
synfig-studio/src/gui/docks/dock_info.cpp
- Here we will implement the UI and members
In #include section:
#include "app.h" #include <gtkmm/progressbar.h>
It will permit to access our App::dock_info_ as a static from anywhere in the application
In Dock_Info(), at the end:
//Render Progress Bar table->attach(*manage(new Gtk::Label(_("Render Progress: "))),0,1,5,6,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL); table->attach(render_progress, 0,5,6,7,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
render_progress.set_show_text(true); render_progress.set_text(strprintf("%.1f%%", 0.0)); render_progress.set_fraction(0.0); //Another spacer table->attach(*manage(new Gtk::Label),0,5,7,8);
just before table->show_all();
and after add(*table);
//Render progress set_n_passes_requested(1); //Default set_n_passes_pending (1); //Default set_render_progress (0.0); //Default, 0.0%
Then at the end of the file, we add these 3 functions:
void studio::Dock_Info::set_n_passes_requested(int value) { n_passes_requested = value; } void studio::Dock_Info::set_n_passes_pending(int value) { n_passes_pending = value; }
void studio::Dock_Info::set_render_progress(float value) { float coeff = (1.000 / (float)n_passes_requested); //% of fraction for 1 pass if more than 1 pass float already_done = coeff * (float)(n_passes_requested - n_passes_pending -1); float r = ( coeff * value ) + already_done; render_progress.set_text( strprintf( "%.1f%%", r*100 )); render_progress.set_fraction(r); }
The 2 first ones are obvious, the last one does the calculation for the display of the current percents of the WHOLE TASK.
If we have only 1 pass, value will be reflected directly.
In case of 2 (or more, who knows what will be implemented later!), each pass will still continue to send its progress as if it was the only one in the world; we will do the adjustments here.
100% of pass 1 while be displayed as 50%.
100% of pass 2 while be displayed as 100%.
If we had 3 passes, it would be 33.3%, 66.6% and 100.0%