From 9db50ed0771678ba93821319942e7f7b2f00a638 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 16 Nov 2016 06:14:22 +0000 Subject: [PATCH] Refactor the renderer frame flush functionality. This commit does three things: * Recognizes that BeginFrame()/EndFrame() are badly named, since BeginFrame() sets up framebuffer, and EndFrame() flushes a frame, and they do not have to be called in pairs; and so renames them to NewFrame()/FlushFrame(). * Reduces the amount of frame flushes in GraphicsWindow::Paint() to two, which is the minimum since we use two different cameras for geometry and UI; * Changes the FPS measurement code to only take into account the time spent rendering our main geometry, and not the UI rendering or window system interaction time. --- src/draw.cpp | 30 ++++++++++++++---------------- src/render/render.h | 4 ++-- src/render/rendergl1.cpp | 8 ++++---- src/render/rendergl2.cpp | 8 ++++---- src/textwin.cpp | 4 ++-- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/draw.cpp b/src/draw.cpp index dea1840e..548df024 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -751,8 +751,6 @@ void GraphicsWindow::Paint() { havePainted = true; - auto renderStartTime = std::chrono::high_resolution_clock::now(); - int w, h; GetGraphicsWindowSize(&w, &h); width = w; @@ -772,13 +770,20 @@ void GraphicsWindow::Paint() { ForceTextWindowShown(); } - canvas->BeginFrame(); + auto renderStartTime = std::chrono::high_resolution_clock::now(); + + canvas->NewFrame(); canvas->SetCamera(camera); canvas->SetLighting(lighting); Draw(canvas.get()); - canvas->EndFrame(); + canvas->FlushFrame(); + + auto renderEndTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration renderTime = renderEndTime - renderStartTime; camera.LoadIdentity(); + camera.offset.x = -(double)camera.width / 2.0; + camera.offset.y = -(double)camera.height / 2.0; canvas->SetCamera(camera); UiCanvas uiCanvas = {}; @@ -788,29 +793,22 @@ void GraphicsWindow::Paint() { // rectangle, as an outline and a transparent fill. if(pending.operation == Pending::DRAGGING_MARQUEE) { Point2d begin = ProjectPoint(orig.marqueePoint); - uiCanvas.DrawRect((int)orig.mouse.x, (int)begin.x, - (int)orig.mouse.y, (int)begin.y, + uiCanvas.DrawRect((int)orig.mouse.x + (int)camera.width / 2, + (int)begin.x + (int)camera.width / 2, + (int)orig.mouse.y + (int)camera.height / 2, + (int)begin.y + (int)camera.height / 2, /*fillColor=*/Style::Color(Style::HOVERED).WithAlpha(25), /*outlineColor=*/Style::Color(Style::HOVERED)); - canvas->EndFrame(); } // And finally the toolbar. if(SS.showToolbar) { - camera.offset = {}; - camera.offset.x = -(double)camera.width / 2.0; - camera.offset.y = -(double)camera.height / 2.0; canvas->SetCamera(camera); ToolbarDraw(&uiCanvas); } // If we display UI elements, also display an fps counter. if(SS.showToolbar) { - canvas->EndFrame(); - - auto renderEndTime = std::chrono::high_resolution_clock::now(); - std::chrono::duration renderTime = renderEndTime - renderStartTime; - RgbaColor renderTimeColor; if(1000 / renderTime.count() < 60) { // We aim for a steady 60fps; draw the counter in red when we're slower. @@ -824,6 +822,6 @@ void GraphicsWindow::Paint() { 5, 5, renderTimeColor); } - canvas->EndFrame(); + canvas->FlushFrame(); canvas->Clear(); } diff --git a/src/render/render.h b/src/render/render.h index 0b6cfcde..1717f832 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -175,8 +175,8 @@ public: virtual void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) = 0; virtual void SetLighting(const Lighting &lighting) = 0; - virtual void BeginFrame() = 0; - virtual void EndFrame() = 0; + virtual void NewFrame() = 0; + virtual void FlushFrame() = 0; virtual std::shared_ptr ReadFrame() = 0; virtual void GetIdent(const char **vendor, const char **renderer, const char **version) = 0; diff --git a/src/render/rendergl1.cpp b/src/render/rendergl1.cpp index e3f8c5dc..95decf9e 100644 --- a/src/render/rendergl1.cpp +++ b/src/render/rendergl1.cpp @@ -220,8 +220,8 @@ public: void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) override; void SetLighting(const Lighting &lighting) override; - void BeginFrame() override; - void EndFrame() override; + void NewFrame() override; + void FlushFrame() override; std::shared_ptr ReadFrame() override; void GetIdent(const char **vendor, const char **renderer, const char **version) override; @@ -738,7 +738,7 @@ void OpenGl1Renderer::UpdateProjection(bool flip) { glClear(GL_DEPTH_BUFFER_BIT); } -void OpenGl1Renderer::BeginFrame() { +void OpenGl1Renderer::NewFrame() { glEnable(GL_NORMALIZE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -791,7 +791,7 @@ void OpenGl1Renderer::BeginFrame() { glClear(GL_DEPTH_BUFFER_BIT); } -void OpenGl1Renderer::EndFrame() { +void OpenGl1Renderer::FlushFrame() { UnSelectPrimitive(); glFlush(); diff --git a/src/render/rendergl2.cpp b/src/render/rendergl2.cpp index e4b81da0..740ec926 100644 --- a/src/render/rendergl2.cpp +++ b/src/render/rendergl2.cpp @@ -134,8 +134,8 @@ public: void SetCamera(const Camera &c, bool flip) override; void SetLighting(const Lighting &l) override; - void BeginFrame() override; - void EndFrame() override; + void NewFrame() override; + void FlushFrame() override; std::shared_ptr ReadFrame() override; void GetIdent(const char **vendor, const char **renderer, const char **version) override; @@ -611,7 +611,7 @@ void OpenGl2Renderer::UpdateProjection(bool flip) { glClear(GL_DEPTH_BUFFER_BIT); } -void OpenGl2Renderer::BeginFrame() { +void OpenGl2Renderer::NewFrame() { if(!initialized) { Init(); initialized = true; @@ -632,7 +632,7 @@ void OpenGl2Renderer::BeginFrame() { glPolygonOffset(2.0, 1.0); } -void OpenGl2Renderer::EndFrame() { +void OpenGl2Renderer::FlushFrame() { for(SMeshListItem &li : meshes) { Fill *fill = SelectFill(li.h); diff --git a/src/textwin.cpp b/src/textwin.cpp index 77322f0d..78fafafe 100644 --- a/src/textwin.cpp +++ b/src/textwin.cpp @@ -865,7 +865,7 @@ void TextWindow::Paint() { camera.offset.x = -(double)camera.width / 2.0; camera.offset.y = -(double)camera.height / 2.0; - canvas->BeginFrame(); + canvas->NewFrame(); canvas->SetCamera(camera); UiCanvas uiCanvas = {}; @@ -992,7 +992,7 @@ void TextWindow::Paint() { // And we may show a color picker for certain editable fields DrawOrHitTestColorPicker(&uiCanvas, PAINT, false, 0, 0); - canvas->EndFrame(); + canvas->FlushFrame(); canvas->Clear(); }