diff --git a/include/widget/FramebufferWidget.hpp b/include/widget/FramebufferWidget.hpp index b3050929..e7acc32f 100644 --- a/include/widget/FramebufferWidget.hpp +++ b/include/widget/FramebufferWidget.hpp @@ -18,6 +18,8 @@ struct FramebufferWidget : Widget { bool dirty = true; bool bypass = false; float oversample = 1.0; + /** Redraw when the world offset of the FramebufferWidget changes its fractional value. */ + bool dirtyOnSubpixelChange = true; FramebufferWidget(); ~FramebufferWidget(); diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index 07d7729e..aa6b886e 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -71,6 +71,8 @@ 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(); diff --git a/src/widget/FramebufferWidget.cpp b/src/widget/FramebufferWidget.cpp index d9f10a20..7f207775 100644 --- a/src/widget/FramebufferWidget.cpp +++ b/src/widget/FramebufferWidget.cpp @@ -80,7 +80,7 @@ void FramebufferWidget::step() { localBox = getChildrenBoundingBox(); } - // DEBUG("%g %g %g %g, %g %g, %g %g", RECT_ARGS(localBox), VEC_ARGS(internal->fbOffsetF), VEC_ARGS(internal->fbScale)); + // DEBUG("rendering FramebufferWidget localBox (%g %g %g %g) fbOffset (%g %g) fbScale (%g %g)", RECT_ARGS(localBox), VEC_ARGS(internal->fbOffsetF), VEC_ARGS(internal->fbScale)); // Transform to world coordinates, then expand to nearest integer coordinates math::Vec min = localBox.getTopLeft().mult(internal->fbScale).plus(internal->fbOffsetF).floor(); math::Vec max = localBox.getBottomRight().mult(internal->fbScale).plus(internal->fbOffsetF).ceil(); @@ -178,7 +178,7 @@ void FramebufferWidget::draw(const DrawArgs& args) { math::Vec offsetI = offset.floor(); internal->offsetF = offset.minus(offsetI); - if (!math::isNear(internal->offsetF.x, internal->fbOffsetF.x, 0.01f) || !math::isNear(internal->offsetF.y, internal->fbOffsetF.y, 0.01f)) { + 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;