Split Canvas::FinishFrame out of Canvas::FlushFrame.

When drawing the graphics window, we flush it twice: once to draw
the geometry, and another time to draw the UI overlay (toolbar,
selection marquee, and FPS counter). Calling glFinish() each time
is (on most platforms) just pointlessly slow, but on macOS Catalina,
without offscreen rendering, it causes the toolbar to flicker.

Instead of calling glFinish() twice per frame in that case, call
glFlush() twice and then glFinish() once we really are done.
pull/507/head
whitequark 2019-11-23 13:35:12 +00:00
parent ec3056773e
commit 65d0bdffdb
7 changed files with 28 additions and 11 deletions

View File

@ -845,7 +845,7 @@ void GraphicsWindow::Paint() {
canvas->SetLighting(lighting);
canvas->SetCamera(camera);
canvas->NewFrame();
canvas->StartFrame();
Draw(canvas.get());
canvas->FlushFrame();
@ -902,6 +902,7 @@ void GraphicsWindow::Paint() {
5, 5, renderTimeColor);
canvas->FlushFrame();
canvas->FinishFrame();
canvas->Clear();
}

View File

@ -208,9 +208,10 @@ static bool RunCommand(const std::vector<std::string> args) {
pixmapCanvas.SetCamera(camera);
pixmapCanvas.Init();
pixmapCanvas.NewFrame();
pixmapCanvas.StartFrame();
SS.GW.Draw(&pixmapCanvas);
pixmapCanvas.FlushFrame();
pixmapCanvas.FinishFrame();
pixmapCanvas.ReadFrame()->WritePng(output, /*flip=*/true);
pixmapCanvas.Clear();

View File

@ -186,8 +186,9 @@ public:
virtual void SetCamera(const Camera &camera) = 0;
virtual void SetLighting(const Lighting &lighting) = 0;
virtual void NewFrame() = 0;
virtual void StartFrame() = 0;
virtual void FlushFrame() = 0;
virtual void FinishFrame() = 0;
virtual std::shared_ptr<Pixmap> ReadFrame() = 0;
virtual void GetIdent(const char **vendor, const char **renderer, const char **version) = 0;
@ -342,8 +343,9 @@ public:
void Clear() override;
void NewFrame() override {}
void StartFrame() override {}
void FlushFrame() override;
void FinishFrame() override {}
std::shared_ptr<Pixmap> ReadFrame() override;
void GetIdent(const char **vendor, const char **renderer, const char **version) override;

View File

@ -220,8 +220,9 @@ public:
void SetCamera(const Camera &camera) override;
void SetLighting(const Lighting &lighting) override;
void NewFrame() override;
void StartFrame() override;
void FlushFrame() override;
void FinishFrame() override;
std::shared_ptr<Pixmap> ReadFrame() override;
void GetIdent(const char **vendor, const char **renderer, const char **version) override;
@ -751,7 +752,7 @@ void OpenGl1Renderer::UpdateProjection() {
glClear(GL_DEPTH_BUFFER_BIT);
}
void OpenGl1Renderer::NewFrame() {
void OpenGl1Renderer::StartFrame() {
glEnable(GL_NORMALIZE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -806,6 +807,7 @@ void OpenGl1Renderer::NewFrame() {
void OpenGl1Renderer::FlushFrame() {
UnSelectPrimitive();
glFlush();
GLenum error = glGetError();
@ -814,6 +816,10 @@ void OpenGl1Renderer::FlushFrame() {
}
}
void OpenGl1Renderer::FinishFrame() {
glFinish();
}
std::shared_ptr<Pixmap> OpenGl1Renderer::ReadFrame() {
int width = camera.width * camera.pixelRatio;
int height = camera.height * camera.pixelRatio;

View File

@ -134,8 +134,9 @@ public:
void SetCamera(const Camera &c) override;
void SetLighting(const Lighting &l) override;
void NewFrame() override;
void StartFrame() override;
void FlushFrame() override;
void FinishFrame() override;
void Clear() override;
std::shared_ptr<Pixmap> ReadFrame() override;
@ -618,7 +619,7 @@ void OpenGl3Renderer::UpdateProjection() {
glClear(GL_DEPTH_BUFFER_BIT);
}
void OpenGl3Renderer::NewFrame() {
void OpenGl3Renderer::StartFrame() {
if(!initialized) {
Init();
initialized = true;
@ -667,7 +668,7 @@ void OpenGl3Renderer::FlushFrame() {
}
points.Clear();
glFinish();
glFlush();
GLenum error = glGetError();
if(error != GL_NO_ERROR) {
@ -675,6 +676,10 @@ void OpenGl3Renderer::FlushFrame() {
}
}
void OpenGl3Renderer::FinishFrame() {
glFinish();
}
void OpenGl3Renderer::Clear() {
ViewportCanvas::Clear();
pixmapCache.CleanupUnused();

View File

@ -924,7 +924,7 @@ void TextWindow::Paint() {
canvas->SetLighting(lighting);
canvas->SetCamera(camera);
canvas->NewFrame();
canvas->StartFrame();
UiCanvas uiCanvas = {};
uiCanvas.canvas = canvas;
@ -1041,6 +1041,7 @@ void TextWindow::Paint() {
DrawOrHitTestColorPicker(&uiCanvas, PAINT, false, 0, 0);
canvas->FlushFrame();
canvas->FinishFrame();
canvas->Clear();
}

View File

@ -255,9 +255,10 @@ bool Test::Helper::CheckRender(const char *file, int line, const char *reference
pixmapCanvas.SetCamera(camera);
pixmapCanvas.Init();
pixmapCanvas.NewFrame();
pixmapCanvas.StartFrame();
SS.GW.Draw(&pixmapCanvas);
pixmapCanvas.FlushFrame();
pixmapCanvas.FinishFrame();
std::shared_ptr<Pixmap> frame = pixmapCanvas.ReadFrame();
pixmapCanvas.Clear();