|
29 | 29 | #include <ctype.h> |
30 | 30 | #include <math.h> |
31 | 31 | #include <inttypes.h> |
| 32 | +#include <limits.h> |
32 | 33 |
|
33 | 34 | #include "platform.h" |
34 | 35 |
|
@@ -4246,15 +4247,48 @@ uint8_t osdIncElementIndex(uint8_t elementIndex) |
4246 | 4247 | void osdDrawNextElement(void) |
4247 | 4248 | { |
4248 | 4249 | static uint8_t elementIndex = 0; |
4249 | | - // Flag for end of loop, also prevents infinite loop when no elements are enabled |
4250 | | - uint8_t index = elementIndex; |
4251 | | - do { |
4252 | | - elementIndex = osdIncElementIndex(elementIndex); |
4253 | | - } while (!osdDrawSingleElement(elementIndex) && index != elementIndex); |
| 4250 | + static uint8_t activeElements = 0; |
| 4251 | + static unsigned lastLayout = UINT_MAX; |
| 4252 | + |
| 4253 | + // Recount visible elements on layout change |
| 4254 | + if (currentLayout != lastLayout) { |
| 4255 | + lastLayout = currentLayout; |
| 4256 | + activeElements = 0; |
| 4257 | + uint8_t idx = 0; |
| 4258 | + do { |
| 4259 | + idx = osdIncElementIndex(idx); |
| 4260 | + if (OSD_VISIBLE(osdLayoutsConfig()->item_pos[currentLayout][idx])) { |
| 4261 | + activeElements++; |
| 4262 | + } |
| 4263 | + } while (idx > 0); |
| 4264 | + } |
| 4265 | + |
| 4266 | + int8_t framerate_hz = osdConfig()->osd_framerate_hz; |
| 4267 | + |
| 4268 | + uint8_t elementsPerCycle; |
| 4269 | + if (framerate_hz <= 0 || activeElements == 0) { |
| 4270 | + elementsPerCycle = 1; // legacy: one element per cycle |
| 4271 | + } else { |
| 4272 | + elementsPerCycle = ((uint16_t)activeElements * framerate_hz * 2 + 124) / 125; |
| 4273 | + if (elementsPerCycle < 1) elementsPerCycle = 1; |
| 4274 | + if (elementsPerCycle > activeElements) elementsPerCycle = activeElements; |
| 4275 | + } |
| 4276 | + |
| 4277 | + DEBUG_SET(DEBUG_OSD_REFRESH, 0, elementsPerCycle); |
| 4278 | + DEBUG_SET(DEBUG_OSD_REFRESH, 1, activeElements); |
| 4279 | + DEBUG_SET(DEBUG_OSD_REFRESH, 2, elementIndex); |
| 4280 | + DEBUG_SET(DEBUG_OSD_REFRESH, 3, framerate_hz); |
| 4281 | + |
| 4282 | + for (uint8_t i = 0; i < elementsPerCycle; i++) { |
| 4283 | + uint8_t index = elementIndex; |
| 4284 | + do { |
| 4285 | + elementIndex = osdIncElementIndex(elementIndex); |
| 4286 | + } while (!osdDrawSingleElement(elementIndex) && index != elementIndex); |
| 4287 | + } |
4254 | 4288 |
|
4255 | 4289 | // Draw artificial horizon + tracking telemetry last |
4256 | 4290 | osdDrawSingleElement(OSD_ARTIFICIAL_HORIZON); |
4257 | | - if (osdConfig()->telemetry>0){ |
| 4291 | + if (osdConfig()->telemetry > 0) { |
4258 | 4292 | osdDisplayTelemetry(); |
4259 | 4293 | } |
4260 | 4294 | } |
@@ -4305,6 +4339,7 @@ PG_RESET_TEMPLATE(osdConfig_t, osdConfig, |
4305 | 4339 | .video_system = SETTING_OSD_VIDEO_SYSTEM_DEFAULT, |
4306 | 4340 | .row_shiftdown = SETTING_OSD_ROW_SHIFTDOWN_DEFAULT, |
4307 | 4341 | .msp_displayport_fullframe_interval = SETTING_OSD_MSP_DISPLAYPORT_FULLFRAME_INTERVAL_DEFAULT, |
| 4342 | + .osd_framerate_hz = SETTING_OSD_FRAMERATE_HZ_DEFAULT, |
4308 | 4343 |
|
4309 | 4344 | .ahi_reverse_roll = SETTING_OSD_AHI_REVERSE_ROLL_DEFAULT, |
4310 | 4345 | .ahi_max_pitch = SETTING_OSD_AHI_MAX_PITCH_DEFAULT, |
|
0 commit comments