diff --git a/Mixer.cpp b/Mixer.cpp index c806d98..1831164 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -139,7 +139,7 @@ static void saveSession(const std::string& filename, Session *session) sessionThreadActive_ = false; } -Mixer::Mixer() : session_(nullptr), back_session_(nullptr), current_view_(nullptr), fps_(60.f) +Mixer::Mixer() : session_(nullptr), back_session_(nullptr), current_view_(nullptr), dt_(0.f) { // unsused initial empty session session_ = new Session; @@ -183,10 +183,8 @@ void Mixer::update() if (update_time_ == GST_CLOCK_TIME_NONE) update_time_ = gst_util_get_timestamp (); gint64 current_time = gst_util_get_timestamp (); - // dt is in mulisecond, with fractional precision (from micro seconds) - float dt = static_cast( GST_TIME_AS_USECONDS(current_time - update_time_) * 0.001f); - if (dt > 0.1f) - fps_ = 0.9f * fps_ + 100.f / dt; + // dt is in milisecond, with fractional precision (from micro seconds) + dt_ = static_cast( GST_TIME_AS_USECONDS(current_time - update_time_) * 0.001f); update_time_ = current_time; // insert source candidate for this session @@ -196,16 +194,16 @@ void Mixer::update() } // update session and associated sources - session_->update(dt); + session_->update(dt_); // delete failed sources (one by one) if (session()->failedSource() != nullptr) deleteSource(session()->failedSource()); // update views - mixing_.update(dt); - geometry_.update(dt); - layer_.update(dt); + mixing_.update(dt_); + geometry_.update(dt_); + layer_.update(dt_); // optimize the reordering in depth for views; // deep updates shall be performed only 1 frame diff --git a/Mixer.h b/Mixer.h index 6d5babb..339974a 100644 --- a/Mixer.h +++ b/Mixer.h @@ -38,7 +38,7 @@ public: // draw session and current view void draw(); - inline float frameRate() const { return fps_;} + inline float dt() const { return dt_;} // creation of sources Source * createSourceFile (std::string path); @@ -97,7 +97,7 @@ protected: View *current_view_; gint64 update_time_; - float fps_; + float dt_; }; #endif // MIXER_H diff --git a/RenderingManager.cpp b/RenderingManager.cpp index 59bf33e..dc6f26f 100644 --- a/RenderingManager.cpp +++ b/RenderingManager.cpp @@ -349,13 +349,38 @@ void Rendering::requestScreenshot() request_screenshot_ = true; } -RenderingWindow::RenderingWindow() : window_(nullptr), master_(nullptr), id_(-1), dpi_scale_(1.f) + +// custom surface with a new VAO +class WindowSurface : public Primitive { + +public: + WindowSurface(Shader *s = new ImageShader); +}; + +WindowSurface::WindowSurface(Shader *s) : Primitive(s) +{ + points_ = std::vector { glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ), + glm::vec3( 1.f, -1.f, 0.f ), glm::vec3( 1.f, 1.f, 0.f ) }; + colors_ = std::vector { glm::vec4( 1.f, 1.f, 1.f , 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ), + glm::vec4( 1.f, 1.f, 1.f, 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ) }; + texCoords_ = std::vector { glm::vec2( 0.f, 1.f ), glm::vec2( 0.f, 0.f ), + glm::vec2( 1.f, 1.f ), glm::vec2( 1.f, 0.f ) }; + indices_ = std::vector { 0, 1, 2, 3 }; + drawMode_ = GL_TRIANGLE_STRIP; +} + + +RenderingWindow::RenderingWindow() : window_(nullptr), master_(nullptr), + id_(-1), dpi_scale_(1.f), textureid_(0), fbo_(0), surface_(nullptr) { } RenderingWindow::~RenderingWindow() -{ - +{ + if (surface_ != nullptr) + delete surface_; + if (fbo_ != 0) + glDeleteFramebuffers(1, &fbo_); } void RenderingWindow::setTitle(const std::string &title) @@ -602,25 +627,6 @@ void RenderingWindow::show() } -// custom surface with a new VAO -class WindowSurface : public Primitive { - -public: - WindowSurface(Shader *s = new ImageShader); -}; - -WindowSurface::WindowSurface(Shader *s) : Primitive(s) -{ - points_ = std::vector { glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ), - glm::vec3( 1.f, -1.f, 0.f ), glm::vec3( 1.f, 1.f, 0.f ) }; - colors_ = std::vector { glm::vec4( 1.f, 1.f, 1.f , 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ), - glm::vec4( 1.f, 1.f, 1.f, 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ) }; - texCoords_ = std::vector { glm::vec2( 0.f, 1.f ), glm::vec2( 0.f, 0.f ), - glm::vec2( 1.f, 1.f ), glm::vec2( 1.f, 0.f ) }; - indices_ = std::vector { 0, 1, 2, 3 }; - drawMode_ = GL_TRIANGLE_STRIP; -} - void RenderingWindow::makeCurrent() { @@ -659,19 +665,19 @@ void RenderingWindow::draw(FrameBuffer *fb) // blit framebuffer if (Settings::application.render_blit) { - static int attached_textureid_fbo_ = 0; - static uint local_fbo_ = 0; - if ( attached_textureid_fbo_ != fb->texture()) { + + if ( textureid_ != fb->texture()) { + + textureid_ = fb->texture(); // create a new fbo in this opengl context - if (local_fbo_ != 0) - glDeleteFramebuffers(1, &local_fbo_); - glGenFramebuffers(1, &local_fbo_); - glBindFramebuffer(GL_FRAMEBUFFER, local_fbo_); + if (fbo_ != 0) + glDeleteFramebuffers(1, &fbo_); + glGenFramebuffers(1, &fbo_); + glBindFramebuffer(GL_FRAMEBUFFER, fbo_); // attach the 2D texture to local FBO - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture(), 0); - attached_textureid_fbo_ = fb->texture(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0); Log::Info("Blit to output window enabled."); } @@ -694,12 +700,12 @@ void RenderingWindow::draw(FrameBuffer *fb) } // select fbo texture read target - glBindFramebuffer(GL_READ_FRAMEBUFFER, local_fbo_); + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_); // select screen target glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - // glBlitFramebuffer(0, 0, fb->width(), fb->height(), 0, 0, window_attributes_.viewport.x, window_attributes_.viewport.y, GL_COLOR_BUFFER_BIT, GL_NEAREST); + // blit operation from fbo (containing texture) to screen glBlitFramebuffer(0, fb->height(), fb->width(), 0, rx, ry, rw, rh, GL_COLOR_BUFFER_BIT, GL_LINEAR); } @@ -708,8 +714,8 @@ void RenderingWindow::draw(FrameBuffer *fb) { // VAO is not shared between multiple contexts of different windows // so we have to create a new VAO for rendering the surface in this window - static WindowSurface *surface = new WindowSurface; - static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); + if (surface_ == 0) + surface_ = new WindowSurface; // calculate scaling factor of frame buffer inside window float windowAspectRatio = aspectRatio(); @@ -720,13 +726,16 @@ void RenderingWindow::draw(FrameBuffer *fb) else scale = glm::vec3(renderingAspectRatio / windowAspectRatio, 1.f, 1.f); - // draw + // make sure previous shader in another glcontext is disabled ShadingProgram::enduse(); + + // draw glBindTexture(GL_TEXTURE_2D, fb->texture()); // surface->shader()->color.a = 0.4f; // TODO alpha blending ? - surface->draw(glm::scale(glm::identity(), scale), projection); + static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); + surface_->draw(glm::scale(glm::identity(), scale), projection); - // done drawing + // done drawing (unload shader from this glcontext) ShadingProgram::enduse(); glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/RenderingManager.h b/RenderingManager.h index 100ca0a..3cbcaa3 100644 --- a/RenderingManager.h +++ b/RenderingManager.h @@ -28,6 +28,11 @@ class RenderingWindow int id_; float dpi_scale_; + // objects to render + int textureid_; + uint fbo_; + class WindowSurface *surface_; + // get monitor in which the window is GLFWmonitor *monitor(); diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index fd441ff..1a0f47a 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -699,36 +699,31 @@ void ToolBox::Render() } ImVec2 plot_size = ImGui::GetContentRegionAvail(); - plot_size.y *= 0.5; + plot_size.y *= 0.45; - static float mixer_framerate_values[120] = {60.f}; - static float io_framerate_values[120] = {60.f}; - static int values_offset = 0; - values_offset = (values_offset+1) % IM_ARRAYSIZE(mixer_framerate_values); - mixer_framerate_values[values_offset] = Mixer::manager().frameRate(); - io_framerate_values[values_offset] = ImGui::GetIO().Framerate; +#define NUM_VALUES_PLOT 120 + static float framerate_values[2][NUM_VALUES_PLOT] = {{}}; + static int values_index = 0; + framerate_values[0][values_index] = MINI(ImGui::GetIO().Framerate, 100.f); + framerate_values[1][values_index] = MINI(Mixer::manager().dt(), 500.f); - // plot FPS graph - { - float average = 0.0f; - for (int n = 0; n < IM_ARRAYSIZE(mixer_framerate_values); n++) - average += mixer_framerate_values[n]; - average /= (float)IM_ARRAYSIZE(mixer_framerate_values); - char overlay[32]; - sprintf(overlay, "Mixer FPS %.2f", average); - ImGui::PlotLines("LinesMixer", mixer_framerate_values, IM_ARRAYSIZE(mixer_framerate_values), values_offset, overlay, 40.0f, 65.0f, plot_size); - } - { - float average = 0.0f; - for (int n = 0; n < IM_ARRAYSIZE(mixer_framerate_values); n++) - average += mixer_framerate_values[n]; - average /= (float)IM_ARRAYSIZE(mixer_framerate_values); - char overlay[32]; - sprintf(overlay, "Render FPS %.2f", average); - ImGui::PlotLines("LinesRender", io_framerate_values, IM_ARRAYSIZE(io_framerate_values), values_offset, overlay, 40.0f, 65.0f, plot_size); + float average[2] = {}; + for (int n = 0; n < NUM_VALUES_PLOT; ++n) { + average[0] += framerate_values[0][n]; + average[1] += framerate_values[1][n]; } + average[0] /= NUM_VALUES_PLOT; + average[1] /= NUM_VALUES_PLOT; - ImGui::End(); // "v-mix" + char overlay[128]; + sprintf(overlay, "Rendering %.2f FPS", average[0]); + ImGui::PlotLines("LinesRender", framerate_values[0], NUM_VALUES_PLOT, values_index, overlay, 40.0f, 65.0f, plot_size); + sprintf(overlay, "Update time %.1f ms (%.1f FPS)", average[1], 1000.f / average[1]); + ImGui::PlotHistogram("LinesMixer", framerate_values[1], NUM_VALUES_PLOT, values_index, overlay, 0.0f, 50.0f, plot_size); + + values_index = (values_index+1) % NUM_VALUES_PLOT; + + ImGui::End(); // About and other utility windows if (show_icons_window) @@ -736,8 +731,6 @@ void ToolBox::Render() if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window); - - } //static void Square(ImGuiSizeCallbackData* data) { @@ -778,7 +771,7 @@ void UserInterface::RenderPreview() draw_list->AddRectFilled(draw_pos, ImVec2(draw_pos.x + width, draw_pos.y + ImGui::GetTextLineHeightWithSpacing()), IM_COL32(55, 55, 55, 200)); ImGui::SetCursorScreenPos(draw_pos); - ImGui::Text(" %d x %d px, %.1f fps", output->width(), output->height(), Mixer::manager().frameRate() ); + ImGui::Text(" %d x %d px, %.1f fps", output->width(), output->height(), 1000.f / Mixer::manager().dt() ); } ImGui::End();