~aleteoryx/muditaos

65023ca120cd270f5d77734b92cb85493f47d9c2 — Mateusz Grzywacz 5 years ago 6fbd239
[EGD-5256] Eink display - speed up in some scenarios

Causes slight speed-up in specific scenarios
(changing windows, also: then rapid navigation)
also: on a regular basis (shaky temperature measumt.)
M module-bsp/board/linux/eink/ED028TC1.c => module-bsp/board/linux/eink/ED028TC1.c +1 -1
@@ 129,7 129,7 @@ EinkStatus_e EinkResetAndInitialize()
    return EinkOK;
}

EinkStatus_e EinkUpdateWaveform(const EinkWaveFormSettings_t *settings)
EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings)
{
    return EinkOK;
}

M module-bsp/board/linux/eink/ED028TC1.h => module-bsp/board/linux/eink/ED028TC1.h +4 -2
@@ 297,6 297,8 @@ extern "C"
        EinkWaveforms_e mode;
        // temperature of surrounding
        int32_t temperature;
        // use counter to keep track if need to change
        uint32_t useCounter;
        // pointer to lookup table for lut c
        uint8_t *LUTCData;
        // sizeo of lutc data


@@ 305,7 307,7 @@ extern "C"
        uint8_t *LUTDData;
        // size of lutd data
        uint32_t LUTDSize;
    } EinkWaveFormSettings_t;
    } EinkWaveformSettings_t;

    /* Exported constants --------------------------------------------------------*/



@@ 419,7 421,7 @@ extern "C"
     * @param LUTCData [in] - Data
     * @return
     */
    EinkStatus_e EinkUpdateWaveform(const EinkWaveFormSettings_t *settings);
    EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings);

    /**
     * This function converts the ARGB image to the L4 format

M module-bsp/board/rt1051/bsp/eink/ED028TC1.cpp => module-bsp/board/rt1051/bsp/eink/ED028TC1.cpp +8 -17
@@ 65,8 65,6 @@

#define _delay_ms(ms) vTaskDelay(pdMS_TO_TICKS(ms))

#define EINK_SUSPEND_TASK_TILL_EPD_BUSY() BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(1000))

//#define EINK_DEBUG_LOG  1
//
//#if EINK_DEBUG_LOG == 1


@@ 81,14 79,11 @@ using namespace magic_enum;
static std::shared_ptr<drivers::DriverDMA> dma;
static std::shared_ptr<drivers::DriverDMAMux> dmamux;

#define EINK_LUTS_FILE_PATH "/Luts.bin"

/* Internal variable definitions */
static uint8_t s_einkIsPoweredOn = false; //  Variable which contains the state of the power of the EPD display

static EinkWaveforms_e s_einkConfiguredWaveform =
    EinkWaveformGC16;                          //  This variable contains the current waveform set in the display
static int8_t s_einkPreviousTemperature = 127; //  This variable contains the last measured temperature of the ambient

static CACHEABLE_SECTION_SDRAM(uint8_t s_einkServiceRotatedBuf[BOARD_EINK_DISPLAY_RES_X * BOARD_EINK_DISPLAY_RES_Y / 2 +
                                                               2]); // Plus 2 for the EPD command and BPP config


@@ 548,7 543,7 @@ void EinkPowerOn()
            return;
        }

        EINK_SUSPEND_TASK_TILL_EPD_BUSY();
        BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
        s_einkIsPoweredOn = true;
    }
}


@@ 563,7 558,7 @@ void EinkPowerOff()
            return;
        }

        EINK_SUSPEND_TASK_TILL_EPD_BUSY();
        BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
        s_einkIsPoweredOn = false;
    }
}


@@ 590,7 585,7 @@ int16_t EinkGetTemperatureInternal()
        return -1;
    }

    EINK_SUSPEND_TASK_TILL_EPD_BUSY();
    BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));

    if (BSP_EinkReadData(temp, sizeof(temp), SPI_MANUAL_CS) != 0) {
        //        LOG_ERROR("Requesting the temperature FAILED");


@@ 641,8 636,8 @@ static void s_EinkSetInitialConfig()
    }

    tmpbuf[0] = EinkPanelSetting;      // 0x00
    tmpbuf[1] = LUT_SEL | SHL | RST_N; // 0x25 -> _XON _RES0 LUT_SEL _DM - SHL _SPIWM RST_N // If 0x35 (DM - 1 is used
                                       // (2bpp)) the SPI speed can be 25MHz
    tmpbuf[1] = LUT_SEL | SHL | RST_N; // 0x25 -> _XON _RES0 LUT_SEL _DM - SHL _SPIWM RST_N
                                       // If 0x35 (DM - 1 is used (2bpp)) the SPI speed can be 25MHz
    tmpbuf[2] = 0x00;
    if (BSP_EinkWriteData(tmpbuf, 3, SPI_AUTOMATIC_CS) != 0) {
        //         LOG_ERROR("Setting the initial configuration for the Eink failed");


@@ 747,13 742,9 @@ EinkStatus_e EinkResetAndInitialize()
    return EinkOK;
}

EinkStatus_e EinkUpdateWaveform(const EinkWaveFormSettings_t *settings)
EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings)
{
    // If neither the temperature nor the waveform has changed - do nothing
    if ((settings->temperature == s_einkPreviousTemperature) && (settings->mode == s_einkConfiguredWaveform)) {
        return EinkOK;
    }

    /// LUTD
    if (BSP_EinkWriteData(settings->LUTDData, settings->LUTDSize, SPI_AUTOMATIC_CS) != 0) {
        EinkResetAndInitialize();
        return EinkSPIErr;


@@ 1015,7 1006,7 @@ EinkStatus_e EinkRefreshImage(
        return EinkSPIErr;
    }

    EINK_SUSPEND_TASK_TILL_EPD_BUSY();
    BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));

    return EinkOK;
}

M module-bsp/board/rt1051/bsp/eink/ED028TC1.h => module-bsp/board/rt1051/bsp/eink/ED028TC1.h +4 -2
@@ 297,6 297,8 @@ extern "C"
        EinkWaveforms_e mode;
        // temperature of surrounding
        int32_t temperature;
        // counts usage of this waveform (display refreshes)
        uint32_t useCounter;
        // pointer to lookup table for lut c
        uint8_t *LUTCData;
        // sizeo of lutc data


@@ 305,7 307,7 @@ extern "C"
        uint8_t *LUTDData;
        // size of lutd data
        uint32_t LUTDSize;
    } EinkWaveFormSettings_t;
    } EinkWaveformSettings_t;

    /* Exported constants --------------------------------------------------------*/



@@ 419,7 421,7 @@ extern "C"
     * @param LUTCData [in] - Data
     * @return
     */
    EinkStatus_e EinkUpdateWaveform(const EinkWaveFormSettings_t *settings);
    EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings);

    /**
     * This function converts the ARGB image to the L4 format

M module-bsp/board/rt1051/bsp/eink/bsp_eink.h => module-bsp/board/rt1051/bsp/eink/bsp_eink.h +1 -1
@@ 33,7 33,7 @@ extern "C"

    typedef void (*bsp_eink_BusyEvent)(void);

#define BSP_EINK_TRANSFER_TIMEOUT_MS 1000
    inline constexpr auto BSP_EinkBusyTimeout = 3000U;

    status_t BSP_EinkInit(bsp_eink_BusyEvent event);
    void BSP_EinkDeinit(void);

M module-services/service-eink/CMakeLists.txt => module-services/service-eink/CMakeLists.txt +1 -1
@@ 16,7 16,7 @@ set(SOURCES
    ServiceEink.cpp
    EinkDisplay.cpp
    messages/ImageMessage.cpp
    messages/PrepareDisplayRequest.cpp
    messages/PrepareDisplayEarlyRequest.cpp
)

add_library(${PROJECT_NAME} STATIC ${SOURCES})

M module-services/service-eink/EinkDisplay.cpp => module-services/service-eink/EinkDisplay.cpp +102 -47
@@ 17,17 17,23 @@ namespace service::eink
        constexpr auto LutsFileName                  = "Luts.bin";
        constexpr auto LUTDSize                      = 16385;
        constexpr auto LUTCSize                      = 64;
        constexpr auto LUTRSize                      = 256; ///< Needed due to \ref EINK_LUTS_FILE_PATH structure
        constexpr auto LUTRSize                      = 256; ///< Needed due to \ref LutsFileName structure
        constexpr auto LUTSTotalSize                 = LUTDSize + LUTCSize + LUTRSize;
        constexpr auto LUTVersionInterval            = 3;
        constexpr auto LUTSubcritical                = 12;
        constexpr auto LUTCritical                   = 13;

        EinkWaveFormSettings_t createDefaultWaveFormSettings(EinkWaveforms_e waveformMode)
        constexpr auto LUTTemperatureMinimal     = 0;
        constexpr auto LUTTemperatureSubcritical = 38;
        constexpr auto LUTTemperatureCritical    = 43;

        constexpr auto LUTTemperatureOffsetInterval    = 3;
        constexpr auto LUTTemperatureOffsetSubcritical = 12;
        constexpr auto LUTTemperatureOffsetCritical    = 13;

        EinkWaveformSettings_t createDefaultWaveFormSettings(EinkWaveforms_e waveformMode)
        {
            EinkWaveFormSettings_t settings{};
            EinkWaveformSettings_t settings{};
            settings.mode        = waveformMode;
            settings.temperature = DefaultSurroundingTemperature;
            settings.useCounter  = 0;
            settings.LUTCData    = nullptr;
            settings.LUTCSize    = 0;
            settings.LUTDData    = nullptr;


@@ 37,14 43,14 @@ namespace service::eink
    } // namespace

    EinkDisplay::EinkDisplay(::gui::Size screenSize)
        : size{screenSize}, waveformSettings{createDefaultWaveFormSettings(EinkWaveformGC16)},
        : size{screenSize}, currentWaveform{createDefaultWaveFormSettings(EinkWaveformGC16)},
          displayMode{EinkDisplayColorMode_e::EinkDisplayColorModeStandard}
    {}

    EinkDisplay::~EinkDisplay() noexcept
    {
        delete[] waveformSettings.LUTCData;
        delete[] waveformSettings.LUTDData;
        delete[] currentWaveform.LUTCData;
        delete[] currentWaveform.LUTDData;
    }

    EinkStatus_e EinkDisplay::resetAndInit()


@@ 85,27 91,68 @@ namespace service::eink

    EinkBpp_e EinkDisplay::getCurrentBitsPerPixelFormat() const noexcept
    {
        if ((waveformSettings.mode == EinkWaveformA2) || (waveformSettings.mode == EinkWaveformDU2)) {
            return Eink4Bpp; /// this should be 1Bpp, but the OS is not ready for this
        if ((currentWaveform.mode == EinkWaveformA2) || (currentWaveform.mode == EinkWaveformDU2)) {
            return Eink4Bpp; // this should be 1Bpp, but the OS is not ready for this (in 1Bpp → halftones disappear)
        }
        return Eink4Bpp;
    }

    EinkStatus_e EinkDisplay::refresh(EinkDisplayTimingsMode_e refreshMode)
    {
        currentWaveform.useCounter += 1;
        return EinkRefreshImage(pointTopLeft.x, pointTopLeft.y, size.width, size.height, refreshMode);
    }

    bool EinkDisplay::changeWaveform(EinkWaveforms_e mode, std::int32_t temperature)
    bool EinkDisplay::isNewWaveformNeeded(EinkWaveforms_e newMode, std::int32_t newTemperature) const
    {
        constexpr auto lenientTemperatureUseCounter = 50; // arbitrary. not documented
        auto alloweLenientTemperature               = currentWaveform.useCounter < lenientTemperatureUseCounter;

        // at least: modes cannot differ
        if (alloweLenientTemperature && newMode == currentWaveform.mode) {
            bool temperatureFine = false;

            switch (currentWaveform.mode) {
            case EinkWaveformA2:
                [[fallthrough]];
            case EinkWaveformDU2:
                temperatureFine = abs(newTemperature - currentWaveform.temperature) <= 3;
                break;
            case EinkWaveformINIT:
                [[fallthrough]];
            case EinkWaveformGLD16:
                [[fallthrough]];
            case EinkWaveformGC16:
                temperatureFine = abs(newTemperature - currentWaveform.temperature) <= 2;
                break;
            }

            if (temperatureFine) {
                return false;
            }
        }
        return true;
    }

    bool EinkDisplay::setWaveform(EinkWaveforms_e mode, std::int32_t temperature)
    {
        if (temperature == waveformSettings.temperature && mode == waveformSettings.mode) {
            return EinkOK;
        if (!isNewWaveformNeeded(mode, temperature)) {
            return true;
        }
        waveformSettings.temperature = temperature;
        waveformSettings.mode        = mode;

        const auto segment = calculateWaveFormSegment(temperature);
        auto offset        = calculateWaveFormOffset(mode, segment);
        auto currentOffset =
            toWaveformOffset(currentWaveform.mode, toWaveformTemperatureOffset(currentWaveform.temperature));
        // assume it is changed
        currentWaveform.useCounter  = 0;
        currentWaveform.temperature = temperature;
        currentWaveform.mode        = mode;

        auto offset = toWaveformOffset(mode, toWaveformTemperatureOffset(temperature));

        if (offset == currentOffset) {
            // current waveform is still the best fit
            return true;
        }

        auto file = std::fopen(LutsFileName, "rb");
        if (file == nullptr) {


@@ 114,62 161,70 @@ namespace service::eink
        }
        auto fileHandlerCleanup = gsl::finally([&file]() { std::fclose(file); });

        resetWaveFormSettings();
        resetWaveformSettings();
        std::fseek(file, offset, SEEK_SET);
        std::fread(&waveformSettings.LUTDData[1], 1, LUTDSize, file);
        std::fread(&currentWaveform.LUTDData[1], 1, LUTDSize, file);

        // 0x00 - 1 frame, ... , 0x0F - 16 frames
        const uint8_t frameCount = waveformSettings.LUTDData[1] + 1;
        const uint8_t waveformFrameCount = currentWaveform.LUTDData[1] + 1;
        // (frameCount * 64) - size of actual LUT; (+1) - the byte containing frameCount; (+1) - EinkLUTD command
        waveformSettings.LUTDSize = (frameCount * 64) + 1 + 1;
        currentWaveform.LUTDSize = (waveformFrameCount * 64) + 1 + 1;

        offset += LUTDSize;
        std::fseek(file, offset, SEEK_SET);
        std::fread(&waveformSettings.LUTCData[1], 1, LUTCSize, file);
        std::fread(&currentWaveform.LUTCData[1], 1, LUTCSize, file);

        EinkUpdateWaveform(&waveformSettings);
        EinkUpdateWaveform(&currentWaveform);
        return true;
    }

    unsigned int EinkDisplay::calculateWaveFormSegment(std::int32_t temperature) const
    unsigned int EinkDisplay::toWaveformTemperatureOffset(std::int32_t temperature) noexcept
    {
        if (temperature < 38) {
            return temperature / LUTVersionInterval;
        }
        if (temperature < 43) {
            return LUTSubcritical;
        if (temperature >= LUTTemperatureCritical)
            return LUTTemperatureOffsetCritical;
        if (temperature >= LUTTemperatureSubcritical)
            return LUTTemperatureOffsetSubcritical;
        if (temperature < LUTTemperatureMinimal) {
            temperature = 0;
        }
        return LUTCritical;
        return temperature / LUTTemperatureOffsetInterval;
    }

    unsigned int EinkDisplay::toWaveformOffset(unsigned short LUTbank, unsigned int temperatureOffset) noexcept
    {
        constexpr auto singleLUTOffset = (LUTTemperatureOffsetCritical + 1);
        return LUTSTotalSize * (singleLUTOffset * LUTbank + temperatureOffset);
    }

    unsigned int EinkDisplay::calculateWaveFormOffset(EinkWaveforms_e mode, unsigned int segment) const
    unsigned int EinkDisplay::toWaveformOffset(EinkWaveforms_e mode, unsigned int temperatureOffset)
    {
        switch (mode) {
        case EinkWaveformINIT:
            return LUTSTotalSize * segment;
            return toWaveformOffset(0, temperatureOffset);
        case EinkWaveformA2:
            return LUTSTotalSize * (14 + segment);
            return toWaveformOffset(1, temperatureOffset);
        case EinkWaveformDU2:
            return LUTSTotalSize * (28 + segment);
            return toWaveformOffset(2, temperatureOffset);
        case EinkWaveformGLD16:
            return LUTSTotalSize * (42 + segment);
            return toWaveformOffset(3, temperatureOffset);
        case EinkWaveformGC16:
            return LUTSTotalSize * (56 + segment);
            return toWaveformOffset(4, temperatureOffset);
        default:
            throw std::invalid_argument{"Invalid waveform mode."};
        }
        throw std::invalid_argument{"Invalid waveform mode."};
    }

    void EinkDisplay::resetWaveFormSettings()
    void EinkDisplay::resetWaveformSettings()
    {
        delete[] waveformSettings.LUTDData;
        waveformSettings.LUTDSize    = 0;
        waveformSettings.LUTDData    = new std::uint8_t[LUTDSize + 1];
        waveformSettings.LUTDData[0] = EinkLUTD;
        delete[] currentWaveform.LUTDData;
        currentWaveform.LUTDSize    = 0;
        currentWaveform.LUTDData    = new std::uint8_t[LUTDSize + 1];
        currentWaveform.LUTDData[0] = EinkLUTD;

        delete[] waveformSettings.LUTCData;
        waveformSettings.LUTCSize    = LUTCSize;
        waveformSettings.LUTCData    = new std::uint8_t[LUTCSize + 1];
        waveformSettings.LUTCData[0] = EinkLUTC;
        delete[] currentWaveform.LUTCData;
        currentWaveform.LUTCSize    = LUTCSize;
        currentWaveform.LUTCData    = new std::uint8_t[LUTCSize + 1];
        currentWaveform.LUTCData[0] = EinkLUTC;
    }

    void EinkDisplay::setMode(EinkDisplayColorMode_e mode) noexcept

M module-services/service-eink/EinkDisplay.hpp => module-services/service-eink/EinkDisplay.hpp +8 -6
@@ 32,20 32,22 @@ namespace service::eink
        void powerOff();
        void shutdown();

        bool changeWaveform(EinkWaveforms_e mode, std::int32_t temperature);
        bool setWaveform(EinkWaveforms_e mode, std::int32_t temperature);
        void setMode(EinkDisplayColorMode_e mode) noexcept;

        ::gui::Size getSize() const noexcept;

      private:
        unsigned int calculateWaveFormSegment(std::int32_t temperature) const;
        unsigned int calculateWaveFormOffset(EinkWaveforms_e mode, unsigned int segment) const;
        void resetWaveFormSettings();
        EinkBpp_e getCurrentBitsPerPixelFormat() const noexcept;
        static unsigned int toWaveformTemperatureOffset(std::int32_t temperature) noexcept;
        static unsigned int toWaveformOffset(unsigned short LUTbank, unsigned int temperatureOffset) noexcept;
        static unsigned int toWaveformOffset(EinkWaveforms_e mode, unsigned int temperatureOffset);
        bool isNewWaveformNeeded(EinkWaveforms_e newMode, int32_t newTemperature) const;
        void resetWaveformSettings();

        EinkBpp_e getCurrentBitsPerPixelFormat() const noexcept;
        static constexpr ::gui::Point pointTopLeft{0, 0};
        const ::gui::Size size;
        EinkWaveFormSettings_t waveformSettings;
        EinkWaveformSettings_t currentWaveform;
        EinkDisplayColorMode_e displayMode;
    };
} // namespace service::eink

M module-services/service-eink/ServiceEink.cpp => module-services/service-eink/ServiceEink.cpp +11 -11
@@ 3,9 3,9 @@

#include "ServiceEink.hpp"
#include "messages/EinkModeMessage.hpp"
#include "messages/PrepareDisplayRequest.hpp"
#include "messages/PrepareDisplayEarlyRequest.hpp"
#include <service-gui/Common.hpp>
#include <service-gui/messages/EinkReady.hpp>
#include <service-gui/messages/EinkInitialized.hpp>
#include <time/ScopedTime.hpp>

#include <log/log.hpp>


@@ 32,8 32,8 @@ namespace service::eink
        connect(typeid(ImageMessage),
                [this](sys::Message *request) -> sys::MessagePointer { return handleImageMessage(request); });

        connect(typeid(PrepareDisplayRequest),
                [this](sys::Message *request) -> sys::MessagePointer { return handlePrepareRequest(request); });
        connect(typeid(PrepareDisplayEarlyRequest),
                [this](sys::Message *request) -> sys::MessagePointer { return handlePrepareEarlyRequest(request); });
    }

    sys::MessagePointer ServiceEink::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *response)


@@ 51,7 51,7 @@ namespace service::eink

        display.powerOn();

        auto msg = std::make_shared<service::gui::EinkReady>(display.getSize());
        auto msg = std::make_shared<service::gui::EinkInitialized>(display.getSize());
        sys::Bus::SendUnicast(msg, service::name::gui, this);

        return sys::ReturnCodes::Success;


@@ 139,19 139,19 @@ namespace service::eink
    {
        display.powerOn();

        const auto isDeepRefresh = refreshMode == ::gui::RefreshModes::GUI_REFRESH_DEEP;
        if (const auto temperature = EinkGetTemperatureInternal(); isDeepRefresh) {
            display.changeWaveform(EinkWaveforms_e::EinkWaveformGC16, temperature);
        const auto temperature = EinkGetTemperatureInternal();
        if (refreshMode == ::gui::RefreshModes::GUI_REFRESH_DEEP) {
            display.setWaveform(EinkWaveforms_e::EinkWaveformGC16, temperature);
            display.dither();
        }
        else {
            display.changeWaveform(EinkWaveforms_e::EinkWaveformDU2, temperature);
            display.setWaveform(EinkWaveforms_e::EinkWaveformDU2, temperature);
        }
    }

    sys::MessagePointer ServiceEink::handlePrepareRequest(sys::Message *message)
    sys::MessagePointer ServiceEink::handlePrepareEarlyRequest(sys::Message *message)
    {
        const auto waveformUpdateMsg = static_cast<service::eink::PrepareDisplayRequest *>(message);
        const auto waveformUpdateMsg = static_cast<service::eink::PrepareDisplayEarlyRequest *>(message);
        prepareDisplay(waveformUpdateMsg->getRefreshMode());
        return sys::MessageNone{};
    }

M module-services/service-eink/ServiceEink.hpp => module-services/service-eink/ServiceEink.hpp +1 -1
@@ 41,7 41,7 @@ namespace service::eink

        sys::MessagePointer handleEinkModeChangedMessage(sys::Message *message);
        sys::MessagePointer handleImageMessage(sys::Message *message);
        sys::MessagePointer handlePrepareRequest(sys::Message *message);
        sys::MessagePointer handlePrepareEarlyRequest(sys::Message *message);

        EinkDisplay display;
        State currentState;

R module-services/service-eink/messages/PrepareDisplayRequest.cpp => module-services/service-eink/messages/PrepareDisplayEarlyRequest.cpp +3 -3
@@ 1,14 1,14 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PrepareDisplayRequest.hpp"
#include "PrepareDisplayEarlyRequest.hpp"

namespace service::eink
{
    PrepareDisplayRequest::PrepareDisplayRequest(::gui::RefreshModes refreshMode) : refreshMode{refreshMode}
    PrepareDisplayEarlyRequest::PrepareDisplayEarlyRequest(::gui::RefreshModes refreshMode) : refreshMode{refreshMode}
    {}

    auto PrepareDisplayRequest::getRefreshMode() const noexcept -> ::gui::RefreshModes
    auto PrepareDisplayEarlyRequest::getRefreshMode() const noexcept -> ::gui::RefreshModes
    {
        return refreshMode;
    }

R module-services/service-eink/messages/PrepareDisplayRequest.hpp => module-services/service-eink/messages/PrepareDisplayEarlyRequest.hpp +2 -2
@@ 9,10 9,10 @@

namespace service::eink
{
    class PrepareDisplayRequest : public EinkMessage
    class PrepareDisplayEarlyRequest : public EinkMessage
    {
      public:
        explicit PrepareDisplayRequest(::gui::RefreshModes refreshMode);
        explicit PrepareDisplayEarlyRequest(::gui::RefreshModes refreshMode);

        [[nodiscard]] auto getRefreshMode() const noexcept -> ::gui::RefreshModes;


M module-services/service-gui/ServiceGUI.cpp => module-services/service-gui/ServiceGUI.cpp +16 -12
@@ 1,11 1,11 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ServiceGUI.hpp"
#include "WorkerGUI.hpp"

#include "messages/DrawMessage.hpp"
#include "messages/EinkReady.hpp"
#include "messages/EinkInitialized.hpp"

#include <DrawCommand.hpp>
#include <FontManager.hpp>


@@ 14,7 14,7 @@
#include <service-eink/Common.hpp>
#include <service-eink/messages/ImageMessage.hpp>
#include <service-eink/messages/EinkMessage.hpp>
#include <service-eink/messages/PrepareDisplayRequest.hpp>
#include <service-eink/messages/PrepareDisplayEarlyRequest.hpp>
#include <SystemManager/SystemManager.hpp>

#include <gsl/gsl_util>


@@ 27,7 27,9 @@ namespace service::gui
        constexpr auto ServiceGuiStackDepth  = 4096U;
        constexpr auto ContextsCount         = 2;
        constexpr auto CommandsQueueCapacity = 3;
        constexpr std::chrono::milliseconds ContextReleaseTimeout{1000};
        constexpr std::chrono::milliseconds BSPEinkBusyTimeout{3000}; ///< sync with \ref BSP_EinkBusyTimeout
        constexpr std::chrono::milliseconds RTOSMessageRoundtripTimeout{1000};
        constexpr std::chrono::milliseconds ContextReleaseTimeout{BSPEinkBusyTimeout + RTOSMessageRoundtripTimeout};
    } // namespace

    ServiceGUI::ServiceGUI(const std::string &name, std::string parent)


@@ 52,8 54,8 @@ namespace service::gui

    void ServiceGUI::registerMessageHandlers()
    {
        connect(typeid(EinkReady),
                [this](sys::Message *request) -> sys::MessagePointer { return handleEinkReady(request); });
        connect(typeid(EinkInitialized),
                [this](sys::Message *request) -> sys::MessagePointer { return handleEinkInitialized(request); });

        connect(typeid(DrawMessage),
                [this](sys::Message *request) -> sys::MessagePointer { return handleDrawMessage(request); });


@@ 119,15 121,17 @@ namespace service::gui
                setState(State::Suspended);
            }

            prepareDisplay(drawMsg->mode);
            if (!contextPool->isAnyContextLocked()) {
                prepareDisplayEarly(drawMsg->mode);
            }
            notifyRenderer(std::move(drawMsg->commands), drawMsg->mode);
        }
        return sys::MessageNone{};
    }

    void ServiceGUI::prepareDisplay(::gui::RefreshModes refreshMode)
    void ServiceGUI::prepareDisplayEarly(::gui::RefreshModes refreshMode)
    {
        auto msg = std::make_shared<service::eink::PrepareDisplayRequest>(refreshMode);
        auto msg = std::make_shared<service::eink::PrepareDisplayEarlyRequest>(refreshMode);
        sys::Bus::SendUnicast(msg, service::name::eink, this);
    }



@@ 199,9 203,9 @@ namespace service::gui
        cachedRender = std::nullopt;
    }

    sys::MessagePointer ServiceGUI::handleEinkReady(sys::Message *message)
    sys::MessagePointer ServiceGUI::handleEinkInitialized(sys::Message *message)
    {
        const auto msg = static_cast<service::gui::EinkReady *>(message);
        const auto msg = static_cast<service::gui::EinkInitialized *>(message);
        contextPool    = std::make_unique<ContextPool>(msg->getDisplaySize(), ContextsCount);
        setState(State::Idle);
        return sys::MessageNone{};


@@ 246,4 250,4 @@ namespace service::gui
    {
        return currentState == state;
    }
} /* namespace sgui */
} // namespace service::gui

M module-services/service-gui/ServiceGUI.hpp => module-services/service-gui/ServiceGUI.hpp +2 -2
@@ 61,7 61,7 @@ namespace service::gui
        void cacheRender(int contextId, ::gui::RefreshModes refreshMode);
        void invalidateCache();

        void prepareDisplay(::gui::RefreshModes refreshMode);
        void prepareDisplayEarly(::gui::RefreshModes refreshMode);
        void notifyRenderer(std::list<std::unique_ptr<::gui::DrawCommand>> &&commands, ::gui::RefreshModes refreshMode);
        void enqueueDrawCommands(DrawCommandsQueue::QueueItem &&item);
        void sendOnDisplay(::gui::Context *context, int contextId, ::gui::RefreshModes refreshMode);


@@ 74,7 74,7 @@ namespace service::gui

        sys::MessagePointer handleDrawMessage(sys::Message *message);
        sys::MessagePointer handleGUIRenderingFinished(sys::Message *message);
        sys::MessagePointer handleEinkReady(sys::Message *message);
        sys::MessagePointer handleEinkInitialized(sys::Message *message);
        sys::MessagePointer handleImageDisplayedNotification(sys::Message *message);

        std::unique_ptr<ContextPool> contextPool;

R module-services/service-gui/messages/EinkReady.hpp => module-services/service-gui/messages/EinkInitialized.hpp +2 -2
@@ 9,10 9,10 @@

namespace service::gui
{
    class EinkReady : public GUIMessage
    class EinkInitialized : public GUIMessage
    {
      public:
        explicit EinkReady(::gui::Size displaySize) : einkDisplaySize{displaySize}
        explicit EinkInitialized(::gui::Size displaySize) : einkDisplaySize{displaySize}
        {}

        [[nodiscard]] auto getDisplaySize() const noexcept -> ::gui::Size