Browse Source

Clean up FramebufferWidget, Window.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
915e3fcdb9
7 changed files with 40 additions and 48 deletions
  1. +2
    -3
      include/widget/FramebufferWidget.hpp
  2. +1
    -1
      include/window.hpp
  3. +21
    -21
      src/app/RackWidget.cpp
  4. +1
    -1
      src/app/Scene.cpp
  5. +5
    -13
      src/widget/FramebufferWidget.cpp
  6. +2
    -1
      src/widget/event.cpp
  7. +8
    -8
      src/window.cpp

+ 2
- 3
include/widget/FramebufferWidget.hpp View File

@@ -6,9 +6,8 @@ namespace rack {
namespace widget { namespace widget {




/** Caches a widget's draw() result to a framebuffer so it is called less frequently.
When `dirty` is true, its children will be re-rendered on the next call to step().
Events are not passed to the underlying scene.
/** Caches its children's draw() result to a framebuffer image.
When dirty, its children will be re-rendered on the next call to step().
*/ */
struct FramebufferWidget : Widget { struct FramebufferWidget : Widget {
struct Internal; struct Internal;


+ 1
- 1
include/window.hpp View File

@@ -82,7 +82,7 @@ struct Window {
void setFullScreen(bool fullScreen); void setFullScreen(bool fullScreen);
bool isFullScreen(); bool isFullScreen();
double getMonitorRefreshRate(); double getMonitorRefreshRate();
double getLastFrameTime();
double getFrameTime();
double getLastFrameDuration(); double getLastFrameDuration();
double getFrameTimeOverdue(); double getFrameTimeOverdue();




+ 21
- 21
src/app/RackWidget.cpp View File

@@ -73,17 +73,17 @@ struct CableContainer : widget::TransparentWidget {




RackWidget::RackWidget() { RackWidget::RackWidget() {
railFb = new widget::FramebufferWidget;
railFb->box.size = math::Vec();
railFb->oversample = 1.0;
// Don't redraw when the world offset of the rail FramebufferWidget changes its fractional value.
railFb->dirtyOnSubpixelChange = false;
{
RackRail* rail = new RackRail;
rail->box.size = math::Vec();
railFb->addChild(rail);
}
addChild(railFb);
// railFb = new widget::FramebufferWidget;
// railFb->box.size = math::Vec();
// railFb->oversample = 1.0;
// // Don't redraw when the world offset of the rail FramebufferWidget changes its fractional value.
// railFb->dirtyOnSubpixelChange = false;
// {
// RackRail* rail = new RackRail;
// rail->box.size = math::Vec();
// railFb->addChild(rail);
// }
// addChild(railFb);


moduleContainer = new ModuleContainer; moduleContainer = new ModuleContainer;
addChild(moduleContainer); addChild(moduleContainer);
@@ -106,16 +106,16 @@ void RackWidget::draw(const DrawArgs& args) {
nvgGlobalTint(args.vg, nvgRGBAf(b, b, b, 1)); nvgGlobalTint(args.vg, nvgRGBAf(b, b, b, 1));


// Resize and reposition the RackRail to align on the grid. // Resize and reposition the RackRail to align on the grid.
math::Rect railBox;
railBox.pos = args.clipBox.pos.div(BUS_BOARD_GRID_SIZE).floor().mult(BUS_BOARD_GRID_SIZE);
railBox.size = args.clipBox.size.div(BUS_BOARD_GRID_SIZE).ceil().plus(math::Vec(1, 1)).mult(BUS_BOARD_GRID_SIZE);
if (!railFb->box.size.equals(railBox.size)) {
railFb->dirty = true;
}
railFb->box = railBox;
RackRail* rail = railFb->getFirstDescendantOfType<RackRail>();
rail->box.size = railFb->box.size;
// math::Rect railBox;
// railBox.pos = args.clipBox.pos.div(BUS_BOARD_GRID_SIZE).floor().mult(BUS_BOARD_GRID_SIZE);
// railBox.size = args.clipBox.size.div(BUS_BOARD_GRID_SIZE).ceil().plus(math::Vec(1, 1)).mult(BUS_BOARD_GRID_SIZE);
// if (!railFb->box.size.equals(railBox.size)) {
// railFb->dirty = true;
// }
// railFb->box = railBox;
// RackRail* rail = railFb->getFirstDescendantOfType<RackRail>();
// rail->box.size = railFb->box.size;


Widget::draw(args); Widget::draw(args);
} }


+ 1
- 1
src/app/Scene.cpp View File

@@ -111,7 +111,7 @@ void Scene::step() {


// Autosave periodically // Autosave periodically
if (settings::autosaveInterval > 0.0) { if (settings::autosaveInterval > 0.0) {
double time = glfwGetTime();
double time = system::getTime();
if (time - lastAutosaveTime >= settings::autosaveInterval) { if (time - lastAutosaveTime >= settings::autosaveInterval) {
lastAutosaveTime = time; lastAutosaveTime = time;
APP->patch->saveAutosave(); APP->patch->saveAutosave();


+ 5
- 13
src/widget/FramebufferWidget.cpp View File

@@ -95,10 +95,6 @@ void FramebufferWidget::draw(const DrawArgs& args) {
if (APP->window->getFrameTimeOverdue() > 0.0) if (APP->window->getFrameTimeOverdue() > 0.0)
return; return;


// Check that scale has been set by `draw()` yet.
if (scale.isZero())
return;

// In case we fail drawing the framebuffer, don't try again the next frame, so reset `dirty` here. // In case we fail drawing the framebuffer, don't try again the next frame, so reset `dirty` here.
dirty = false; dirty = false;
NVGcontext* vg = APP->window->vg; NVGcontext* vg = APP->window->vg;
@@ -134,8 +130,8 @@ void FramebufferWidget::draw(const DrawArgs& args) {
} }
// Create a framebuffer // Create a framebuffer
if (internal->fbSize.isFinite() && !internal->fbSize.isZero()) { if (internal->fbSize.isFinite() && !internal->fbSize.isZero()) {
// DEBUG("Creating framebuffer of size (%f, %f)", VEC_ARGS(internal->fbSize));
internal->fb = nvgluCreateFramebuffer(vg, internal->fbSize.x, internal->fbSize.y, 0); internal->fb = nvgluCreateFramebuffer(vg, internal->fbSize.x, internal->fbSize.y, 0);
// DEBUG("Created framebuffer of size (%f, %f)", VEC_ARGS(internal->fbSize));
} }
} }
if (!internal->fb) { if (!internal->fb) {
@@ -143,7 +139,7 @@ void FramebufferWidget::draw(const DrawArgs& args) {
return; return;
} }


DEBUG("Drawing to framebuffer of size (%f, %f)", VEC_ARGS(internal->fbSize));
// DEBUG("Drawing to framebuffer of size (%f, %f)", VEC_ARGS(internal->fbSize));


// Render to framebuffer // Render to framebuffer
if (oversample == 1.0) { if (oversample == 1.0) {
@@ -156,6 +152,7 @@ void FramebufferWidget::draw(const DrawArgs& args) {
NVGLUframebuffer* fb = internal->fb; NVGLUframebuffer* fb = internal->fb;
// If oversampling, create another framebuffer and copy it to actual size. // If oversampling, create another framebuffer and copy it to actual size.
math::Vec oversampledFbSize = internal->fbSize.mult(oversample).ceil(); math::Vec oversampledFbSize = internal->fbSize.mult(oversample).ceil();
// DEBUG("Creating %0.fx oversampled framebuffer of size (%f, %f)", oversample, VEC_ARGS(internal->fbSize));
NVGLUframebuffer* oversampledFb = nvgluCreateFramebuffer(fbVg, oversampledFbSize.x, oversampledFbSize.y, 0); NVGLUframebuffer* oversampledFb = nvgluCreateFramebuffer(fbVg, oversampledFbSize.x, oversampledFbSize.y, 0);


if (!oversampledFb) { if (!oversampledFb) {
@@ -170,9 +167,8 @@ void FramebufferWidget::draw(const DrawArgs& args) {
internal->fb = fb; internal->fb = fb;
nvgluBindFramebuffer(NULL); nvgluBindFramebuffer(NULL);


// Use NanoVG for resizing framebuffers
// Use NanoVG for copying oversampled framebuffer to normal framebuffer
nvgluBindFramebuffer(internal->fb); nvgluBindFramebuffer(internal->fb);

nvgBeginFrame(fbVg, internal->fbBox.size.x, internal->fbBox.size.y, 1.0); nvgBeginFrame(fbVg, internal->fbBox.size.x, internal->fbBox.size.y, 1.0);


// Draw oversampled framebuffer // Draw oversampled framebuffer
@@ -205,11 +201,7 @@ void FramebufferWidget::draw(const DrawArgs& args) {
nvgSave(args.vg); nvgSave(args.vg);
nvgResetTransform(args.vg); nvgResetTransform(args.vg);


math::Vec scaleRatio = math::Vec(1, 1);
if (!internal->fbScale.isZero() && !scale.equals(internal->fbScale)) {
// Continue to draw with the last framebuffer, but stretch it to rescale.
scaleRatio = scale.div(internal->fbScale);
}
math::Vec scaleRatio = scale.div(internal->fbScale);
// DEBUG("%f %f %f %f", scaleRatio.x, scaleRatio.y, offsetF.x, offsetF.y); // DEBUG("%f %f %f %f", scaleRatio.x, scaleRatio.y, offsetF.x, offsetF.y);


// DEBUG("%f %f %f %f, %f %f", RECT_ARGS(internal->fbBox), VEC_ARGS(internal->fbSize)); // DEBUG("%f %f %f %f, %f %f", RECT_ARGS(internal->fbBox), VEC_ARGS(internal->fbSize));


+ 2
- 1
src/widget/event.cpp View File

@@ -2,6 +2,7 @@
#include <widget/Widget.hpp> #include <widget/Widget.hpp>
#include <context.hpp> #include <context.hpp>
#include <window.hpp> #include <window.hpp>
#include <system.hpp>




namespace rack { namespace rack {
@@ -159,7 +160,7 @@ bool EventState::handleButton(math::Vec pos, int button, int action, int mods) {


if (action == GLFW_PRESS) { if (action == GLFW_PRESS) {
const double doubleClickDuration = 0.3; const double doubleClickDuration = 0.3;
double clickTime = glfwGetTime();
double clickTime = system::getTime();
if (clickedWidget if (clickedWidget
&& clickTime - lastClickTime <= doubleClickDuration && clickTime - lastClickTime <= doubleClickDuration
&& lastClickedWidget == clickedWidget) { && lastClickedWidget == clickedWidget) {


+ 8
- 8
src/window.cpp View File

@@ -81,8 +81,8 @@ struct Window::Internal {
bool ignoreNextMouseDelta = false; bool ignoreNextMouseDelta = false;
int frameSwapInterval = -1; int frameSwapInterval = -1;
double monitorRefreshRate = 0.0; double monitorRefreshRate = 0.0;
double frameTime = 0.0;
double lastFrameDuration = 0.0; double lastFrameDuration = 0.0;
double lastFrameTime = 0.0;


math::Vec lastMousePos; math::Vec lastMousePos;


@@ -387,10 +387,10 @@ void Window::run() {




void Window::step() { void Window::step() {
double frameTime = glfwGetTime();
internal->lastFrameDuration = frameTime - internal->lastFrameTime;
double lastFrameTime = internal->frameTime;
internal->frameTime = system::getTime();
internal->lastFrameDuration = internal->frameTime - lastFrameTime;
// DEBUG("%.2lf Hz", 1.0 / internal->lastFrameDuration); // DEBUG("%.2lf Hz", 1.0 / internal->lastFrameDuration);
internal->lastFrameTime = frameTime;


// Make event handlers and step() have a clean NanoVG context // Make event handlers and step() have a clean NanoVG context
nvgReset(vg); nvgReset(vg);
@@ -540,7 +540,7 @@ void Window::screenshotModules(const std::string& screenshotsDir, float zoom) {
zw->addChild(mw); zw->addChild(mw);


// HACK: Set the frame time so FramebufferWidgets are never overdue and therefore guaranteed to draw // HACK: Set the frame time so FramebufferWidgets are never overdue and therefore guaranteed to draw
internal->lastFrameTime = INFINITY;
internal->frameTime = INFINITY;


// Draw to framebuffer // Draw to framebuffer
fbw->step(); fbw->step();
@@ -636,8 +636,8 @@ double Window::getMonitorRefreshRate() {
} }




double Window::getLastFrameTime() {
return internal->lastFrameTime;
double Window::getFrameTime() {
return internal->frameTime;
} }




@@ -648,7 +648,7 @@ double Window::getLastFrameDuration() {


double Window::getFrameTimeOverdue() { double Window::getFrameTimeOverdue() {
double desiredFrameDuration = internal->frameSwapInterval / internal->monitorRefreshRate; double desiredFrameDuration = internal->frameSwapInterval / internal->monitorRefreshRate;
double frameDuration = glfwGetTime() - internal->lastFrameTime;
double frameDuration = system::getTime() - internal->frameTime;
return frameDuration - desiredFrameDuration; return frameDuration - desiredFrameDuration;
} }




Loading…
Cancel
Save