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.
This commit is contained in:
whitequark 2016-11-16 06:14:22 +00:00
parent 156fe73bee
commit 9db50ed077
5 changed files with 26 additions and 28 deletions

View File

@ -751,8 +751,6 @@ void GraphicsWindow::Paint() {
havePainted = true; havePainted = true;
auto renderStartTime = std::chrono::high_resolution_clock::now();
int w, h; int w, h;
GetGraphicsWindowSize(&w, &h); GetGraphicsWindowSize(&w, &h);
width = w; width = w;
@ -772,13 +770,20 @@ void GraphicsWindow::Paint() {
ForceTextWindowShown(); ForceTextWindowShown();
} }
canvas->BeginFrame(); auto renderStartTime = std::chrono::high_resolution_clock::now();
canvas->NewFrame();
canvas->SetCamera(camera); canvas->SetCamera(camera);
canvas->SetLighting(lighting); canvas->SetLighting(lighting);
Draw(canvas.get()); Draw(canvas.get());
canvas->EndFrame(); canvas->FlushFrame();
auto renderEndTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> renderTime = renderEndTime - renderStartTime;
camera.LoadIdentity(); camera.LoadIdentity();
camera.offset.x = -(double)camera.width / 2.0;
camera.offset.y = -(double)camera.height / 2.0;
canvas->SetCamera(camera); canvas->SetCamera(camera);
UiCanvas uiCanvas = {}; UiCanvas uiCanvas = {};
@ -788,29 +793,22 @@ void GraphicsWindow::Paint() {
// rectangle, as an outline and a transparent fill. // rectangle, as an outline and a transparent fill.
if(pending.operation == Pending::DRAGGING_MARQUEE) { if(pending.operation == Pending::DRAGGING_MARQUEE) {
Point2d begin = ProjectPoint(orig.marqueePoint); Point2d begin = ProjectPoint(orig.marqueePoint);
uiCanvas.DrawRect((int)orig.mouse.x, (int)begin.x, uiCanvas.DrawRect((int)orig.mouse.x + (int)camera.width / 2,
(int)orig.mouse.y, (int)begin.y, (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), /*fillColor=*/Style::Color(Style::HOVERED).WithAlpha(25),
/*outlineColor=*/Style::Color(Style::HOVERED)); /*outlineColor=*/Style::Color(Style::HOVERED));
canvas->EndFrame();
} }
// And finally the toolbar. // And finally the toolbar.
if(SS.showToolbar) { if(SS.showToolbar) {
camera.offset = {};
camera.offset.x = -(double)camera.width / 2.0;
camera.offset.y = -(double)camera.height / 2.0;
canvas->SetCamera(camera); canvas->SetCamera(camera);
ToolbarDraw(&uiCanvas); ToolbarDraw(&uiCanvas);
} }
// If we display UI elements, also display an fps counter. // If we display UI elements, also display an fps counter.
if(SS.showToolbar) { if(SS.showToolbar) {
canvas->EndFrame();
auto renderEndTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> renderTime = renderEndTime - renderStartTime;
RgbaColor renderTimeColor; RgbaColor renderTimeColor;
if(1000 / renderTime.count() < 60) { if(1000 / renderTime.count() < 60) {
// We aim for a steady 60fps; draw the counter in red when we're slower. // 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); 5, 5, renderTimeColor);
} }
canvas->EndFrame(); canvas->FlushFrame();
canvas->Clear(); canvas->Clear();
} }

View File

@ -175,8 +175,8 @@ public:
virtual void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) = 0; virtual void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) = 0;
virtual void SetLighting(const Lighting &lighting) = 0; virtual void SetLighting(const Lighting &lighting) = 0;
virtual void BeginFrame() = 0; virtual void NewFrame() = 0;
virtual void EndFrame() = 0; virtual void FlushFrame() = 0;
virtual std::shared_ptr<Pixmap> ReadFrame() = 0; virtual std::shared_ptr<Pixmap> ReadFrame() = 0;
virtual void GetIdent(const char **vendor, const char **renderer, const char **version) = 0; virtual void GetIdent(const char **vendor, const char **renderer, const char **version) = 0;

View File

@ -220,8 +220,8 @@ public:
void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) override; void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) override;
void SetLighting(const Lighting &lighting) override; void SetLighting(const Lighting &lighting) override;
void BeginFrame() override; void NewFrame() override;
void EndFrame() override; void FlushFrame() override;
std::shared_ptr<Pixmap> ReadFrame() override; std::shared_ptr<Pixmap> ReadFrame() override;
void GetIdent(const char **vendor, const char **renderer, const char **version) 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); glClear(GL_DEPTH_BUFFER_BIT);
} }
void OpenGl1Renderer::BeginFrame() { void OpenGl1Renderer::NewFrame() {
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -791,7 +791,7 @@ void OpenGl1Renderer::BeginFrame() {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
} }
void OpenGl1Renderer::EndFrame() { void OpenGl1Renderer::FlushFrame() {
UnSelectPrimitive(); UnSelectPrimitive();
glFlush(); glFlush();

View File

@ -134,8 +134,8 @@ public:
void SetCamera(const Camera &c, bool flip) override; void SetCamera(const Camera &c, bool flip) override;
void SetLighting(const Lighting &l) override; void SetLighting(const Lighting &l) override;
void BeginFrame() override; void NewFrame() override;
void EndFrame() override; void FlushFrame() override;
std::shared_ptr<Pixmap> ReadFrame() override; std::shared_ptr<Pixmap> ReadFrame() override;
void GetIdent(const char **vendor, const char **renderer, const char **version) 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); glClear(GL_DEPTH_BUFFER_BIT);
} }
void OpenGl2Renderer::BeginFrame() { void OpenGl2Renderer::NewFrame() {
if(!initialized) { if(!initialized) {
Init(); Init();
initialized = true; initialized = true;
@ -632,7 +632,7 @@ void OpenGl2Renderer::BeginFrame() {
glPolygonOffset(2.0, 1.0); glPolygonOffset(2.0, 1.0);
} }
void OpenGl2Renderer::EndFrame() { void OpenGl2Renderer::FlushFrame() {
for(SMeshListItem &li : meshes) { for(SMeshListItem &li : meshes) {
Fill *fill = SelectFill(li.h); Fill *fill = SelectFill(li.h);

View File

@ -865,7 +865,7 @@ void TextWindow::Paint() {
camera.offset.x = -(double)camera.width / 2.0; camera.offset.x = -(double)camera.width / 2.0;
camera.offset.y = -(double)camera.height / 2.0; camera.offset.y = -(double)camera.height / 2.0;
canvas->BeginFrame(); canvas->NewFrame();
canvas->SetCamera(camera); canvas->SetCamera(camera);
UiCanvas uiCanvas = {}; UiCanvas uiCanvas = {};
@ -992,7 +992,7 @@ void TextWindow::Paint() {
// And we may show a color picker for certain editable fields // And we may show a color picker for certain editable fields
DrawOrHitTestColorPicker(&uiCanvas, PAINT, false, 0, 0); DrawOrHitTestColorPicker(&uiCanvas, PAINT, false, 0, 0);
canvas->EndFrame(); canvas->FlushFrame();
canvas->Clear(); canvas->Clear();
} }