From ad1d10984578326c47cbe42ed9f0cd96250b0104 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sat, 13 Feb 2021 14:02:39 -0500 Subject: [PATCH] Add ContextCreateEvent and ContextDestroyEvent. --- include/widget/FramebufferWidget.hpp | 2 + include/widget/Widget.hpp | 22 +++++++++- src/widget/FramebufferWidget.cpp | 21 ++++++++-- src/window.cpp | 60 +++++++++++++++++----------- standalone/main.cpp | 6 +++ 5 files changed, 82 insertions(+), 29 deletions(-) diff --git a/include/widget/FramebufferWidget.hpp b/include/widget/FramebufferWidget.hpp index 776bdf03..0f08e2d5 100644 --- a/include/widget/FramebufferWidget.hpp +++ b/include/widget/FramebufferWidget.hpp @@ -32,6 +32,8 @@ struct FramebufferWidget : Widget { NVGLUframebuffer* getFramebuffer(); math::Vec getFramebufferSize(); void setScale(math::Vec scale); + void onContextCreate(const ContextCreateEvent& e) override; + void onContextDestroy(const ContextDestroyEvent& e) override; }; diff --git a/include/widget/Widget.hpp b/include/widget/Widget.hpp index ef1fbb49..881270d2 100644 --- a/include/widget/Widget.hpp +++ b/include/widget/Widget.hpp @@ -452,13 +452,33 @@ struct Widget : WeakBase { virtual void onHide(const HideEvent& e) { recurseEvent(&Widget::onHide, e); } + + /** Occurs after the Window, OpenGL context, and Nanovg are created. + Recurses. + */ + struct ContextCreateEvent : BaseEvent { + NVGcontext* vg; + }; + virtual void onContextCreate(const ContextCreateEvent& e) { + recurseEvent(&Widget::onContextCreate, e); + } + + /** Occurs before the Window, OpenGL context, and Nanovg are destroyed. + Recurses. + */ + struct ContextDestroyEvent : BaseEvent { + NVGcontext* vg; + }; + virtual void onContextDestroy(const ContextDestroyEvent& e) { + recurseEvent(&Widget::onContextDestroy, e); + } }; } // namespace widget /** Deprecated Rack v1 event namespace. -Use `FooEvent` instead of `event::Foo` in new code. +Use `FooEvent` (defined in widget::Widget) instead of `event::Foo` in new code. */ namespace event { using Base = widget::BaseEvent; diff --git a/src/widget/FramebufferWidget.cpp b/src/widget/FramebufferWidget.cpp index 8ee12946..6c01deee 100644 --- a/src/widget/FramebufferWidget.cpp +++ b/src/widget/FramebufferWidget.cpp @@ -50,7 +50,7 @@ void FramebufferWidget::setDirty(bool dirty) { void FramebufferWidget::onDirty(const DirtyEvent& e) { - dirty = true; + setDirty(); Widget::onDirty(e); } @@ -71,7 +71,7 @@ void FramebufferWidget::step() { return; // In case we fail drawing the framebuffer, don't try again the next frame, so reset `dirty` here. - dirty = false; + setDirty(false); NVGcontext* vg = APP->window->vg; internal->fbScale = internal->scale; @@ -186,12 +186,12 @@ void FramebufferWidget::draw(const DrawArgs& args) { if (dirtyOnSubpixelChange && !(math::isNear(internal->offsetF.x, internal->fbOffsetF.x, 0.01f) && math::isNear(internal->offsetF.y, internal->fbOffsetF.y, 0.01f))) { // If drawing to a new subpixel location, rerender in the next frame. // DEBUG("%p dirty subpixel", this); - dirty = true; + setDirty(); } if (!internal->scale.equals(internal->fbScale)) { // If rescaled, rerender in the next frame. // DEBUG("%p dirty scale", this); - dirty = true; + setDirty(); } math::Vec scaleRatio = math::Vec(1, 1); @@ -285,5 +285,18 @@ void FramebufferWidget::setScale(math::Vec scale) { } +void FramebufferWidget::onContextCreate(const ContextCreateEvent& e) { + setDirty(); + Widget::onContextCreate(e); +} + + +void FramebufferWidget::onContextDestroy(const ContextDestroyEvent& e) { + if (internal->fb) + nvgluDeleteFramebuffer(internal->fb); + Widget::onContextDestroy(e); +} + + } // namespace widget } // namespace rack diff --git a/src/window.cpp b/src/window.cpp index cdb8510d..e0122b76 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -327,6 +327,11 @@ Window::Window() { // Load default Blendish font uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf")); bndSetFont(uiFont->handle); + + if (APP->scene) { + widget::Widget::ContextCreateEvent e; + APP->scene->onContextCreate(e); + } } @@ -344,6 +349,11 @@ Window::~Window() { settings::windowPos = math::Vec(winX, winY); } + if (APP->scene) { + widget::Widget::ContextDestroyEvent e; + APP->scene->onContextDestroy(e); + } + #if defined NANOVG_GL2 nvgDeleteGL2(vg); #elif defined NANOVG_GL3 @@ -422,30 +432,32 @@ void Window::step() { glfwGetWindowSize(win, &winWidth, &winHeight); windowRatio = (float)fbWidth / winWidth; - // DEBUG("%f %f %d %d", pixelRatio, windowRatio, fbWidth, winWidth); - // Resize scene - APP->scene->box.size = math::Vec(fbWidth, fbHeight).div(pixelRatio); - - // Step scene - APP->scene->step(); - - // Render scene - bool visible = glfwGetWindowAttrib(win, GLFW_VISIBLE) && !glfwGetWindowAttrib(win, GLFW_ICONIFIED); - if (visible) { - // Update and render - nvgBeginFrame(vg, fbWidth, fbHeight, pixelRatio); - nvgScale(vg, pixelRatio, pixelRatio); - - // Draw scene - widget::Widget::DrawArgs args; - args.vg = vg; - args.clipBox = APP->scene->box.zeroPos(); - APP->scene->draw(args); - - glViewport(0, 0, fbWidth, fbHeight); - glClearColor(0.0, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - nvgEndFrame(vg); + if (APP->scene) { + // DEBUG("%f %f %d %d", pixelRatio, windowRatio, fbWidth, winWidth); + // Resize scene + APP->scene->box.size = math::Vec(fbWidth, fbHeight).div(pixelRatio); + + // Step scene + APP->scene->step(); + + // Render scene + bool visible = glfwGetWindowAttrib(win, GLFW_VISIBLE) && !glfwGetWindowAttrib(win, GLFW_ICONIFIED); + if (visible) { + // Update and render + nvgBeginFrame(vg, fbWidth, fbHeight, pixelRatio); + nvgScale(vg, pixelRatio, pixelRatio); + + // Draw scene + widget::Widget::DrawArgs args; + args.vg = vg; + args.clipBox = APP->scene->box.zeroPos(); + APP->scene->draw(args); + + glViewport(0, 0, fbWidth, fbHeight); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + nvgEndFrame(vg); + } } glfwSwapBuffers(win); diff --git a/standalone/main.cpp b/standalone/main.cpp index cf282184..c2f640b5 100644 --- a/standalone/main.cpp +++ b/standalone/main.cpp @@ -223,6 +223,12 @@ int main(int argc, char* argv[]) { INFO("Running window"); APP->window->run(); INFO("Stopped window"); + delete APP->window; + APP->window = NULL; + + INFO("Re-creating window"); + APP->window = new Window; + APP->window->run(); } // Destroy context