#include "./Renderer.h" #include "./Display.h" #include #ifndef __NOINIT_ATTR // Pre-defined on esp32 #define __NOINIT_ATTR __attribute__ ((section (".noinit"))) #endif __NOINIT_ATTR const char* s_lastFigmentName; const char* Renderer::lastFigmentName() { return s_lastFigmentName; } void Renderer::loop() { m_powerState.update(); m_brightness.update(); uint16_t totalPower = 0; for(Display* dpy : m_displays) { totalPower += calculate_unscaled_power_mW(dpy->pixelBacking(), dpy->pixelCount()); for(Figment* figment : m_figments) { if (figment->state == Task::Running) { #if defined(BOARD_ESP32) or defined(BOARD_ESP8266) unsigned int frameStart = ESP.getCycleCount(); #endif Log.verbose("Render %s", figment->name); s_lastFigmentName = figment->name; figment->render(dpy); #if defined(BOARD_ESP32) or defined(BOARD_ESP8266) unsigned int runtime = (ESP.getCycleCount() - frameStart) / 160000; #else unsigned int runtime = 0; #endif if (runtime >= 8) { Log.warning("SLOW RENDER: %s took %dms!", figment->name, runtime); } } }; } const uint8_t videoBrightness = brighten8_video(m_powerState); FastLED.show(powerScale(videoBrightness, totalPower)); FastLED.countFPS(); } void Renderer::handleEvent(const InputEvent& evt) { switch (evt.intent) { case InputEvent::PowerToggle: m_powerState = m_powerState.value() <= 128 ? 255 : 0; Log.notice("Power toggled to %t", m_powerState); break; case InputEvent::SetPower: m_powerState = evt.asInt() == 0 ? 0 : 255; Log.notice("Power state is now %t", m_powerState); break; case InputEvent::SetBrightness: m_brightness = evt.asInt(); break; } } uint8_t Renderer::powerScale(uint8_t target, uint32_t totalPower) const { if (m_powerManaged) { uint32_t requested = ((uint32_t)totalPower * target) / 256; if (requested > totalPower) { return (uint32_t)((uint8_t)(target) * (uint32_t)(totalPower)) / ((uint32_t)(requested)); } } return target; } void Renderer::onStart() { for(Display* dpy : m_displays) { dpy->clear(); } FastLED.show(); } void Renderer::doOn(Args& args, Print& print) { m_powerState = 100; } void Renderer::doOff(Args& args, Print& print) { m_powerState = 0; } void Renderer::doBrightness(Args& args, Print& print) { m_brightness = atoi(args[1].c_str()); } const std::vector& Renderer::commands() const { static const std::vector _commands = { Command{"brightness", &Renderer::doBrightness}, Command{"on", &Renderer::doOn}, Command{"off", &Renderer::doOff} }; return _commands; }