MCPcopy Create free account
hub / github.com/VCVRack/Rack / draw

Method draw

src/widget/FramebufferWidget.cpp:84–167  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

82
83
84void FramebufferWidget::draw(const DrawArgs& args) {
85 // Draw directly if bypassed or already drawing in a framebuffer
86 if (bypassed || args.fb) {
87 Widget::draw(args);
88 return;
89 }
90
91 // Get world transform
92 float xform[6];
93 nvgCurrentTransform(args.vg, xform);
94 // Skew and rotate is not supported
95 if (!math::isNear(xform[1], 0.f) || !math::isNear(xform[2], 0.f)) {
96 WARN("Skew and rotation detected but not supported in FramebufferWidget.");
97 return;
98 }
99
100 // Extract scale and offset from world transform
101 math::Vec scale = math::Vec(xform[0], xform[3]);
102 math::Vec offset = math::Vec(xform[4], xform[5]);
103 math::Vec offsetI = offset.floor();
104 math::Vec offsetF = offset.minus(offsetI);
105
106 // Re-render if drawing to a new subpixel location.
107 // Anything less than 0.1 pixels isn't noticeable.
108 math::Vec offsetFDelta = offsetF.minus(internal->fbOffsetF);
109 if (dirtyOnSubpixelChange && APP->window->fbDirtyOnSubpixelChange() && offsetFDelta.square() >= std::pow(0.1f, 2)) {
110 // DEBUG("%p dirty subpixel (%f, %f) (%f, %f)", this, VEC_ARGS(offsetF), VEC_ARGS(internal->fbOffsetF));
111 setDirty();
112 }
113 // Re-render if rescaled.
114 else if (!scale.equals(internal->fbScale)) {
115 // DEBUG("%p dirty scale", this);
116 setDirty();
117 }
118 // Re-render if viewport is outside framebuffer's clipbox when it was rendered.
119 else if (!internal->fbClipBox.contains(args.clipBox)) {
120 setDirty();
121 }
122
123 if (dirty) {
124 // Render only if there is frame time remaining (to avoid lagging frames significantly), or if it's one of the first framebuffers this frame (to avoid framebuffers from never rendering).
125 const int minCount = 1;
126 const double minRemaining = -1 / 60.0;
127 int count = ++APP->window->fbCount();
128 double remaining = APP->window->getFrameDurationRemaining();
129 if (count <= minCount || remaining > minRemaining) {
130 render(scale, offsetF, args.clipBox);
131 }
132 }
133
134 if (!internal->fb)
135 return;
136
137 // Draw framebuffer image, using world coordinates
138 nvgSave(args.vg);
139 nvgResetTransform(args.vg);
140
141 math::Vec scaleRatio = scale.div(internal->fbScale);

Callers

nothing calls this directly

Calls 10

isNearFunction · 0.85
VecClass · 0.85
powFunction · 0.85
floorMethod · 0.80
minusMethod · 0.80
squareMethod · 0.80
containsMethod · 0.80
divMethod · 0.80
equalsMethod · 0.45

Tested by

no test coverage detected