From d08511c5dc0ec8a7377cb456588f2caa9a99bacd Mon Sep 17 00:00:00 2001 From: Victor Oliveira Date: Tue, 27 Oct 2020 23:54:30 -0300 Subject: [PATCH] Color UI circular task queue (#19918) --- Marlin/src/lcd/tft/tft_queue.cpp | 52 ++++++++++++++++++-------------- Marlin/src/lcd/tft/tft_queue.h | 7 +++++ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/Marlin/src/lcd/tft/tft_queue.cpp b/Marlin/src/lcd/tft/tft_queue.cpp index e178a59a2..43628706a 100644 --- a/Marlin/src/lcd/tft/tft_queue.cpp +++ b/Marlin/src/lcd/tft/tft_queue.cpp @@ -32,6 +32,7 @@ uint8_t TFT_Queue::queue[]; uint8_t *TFT_Queue::end_of_queue = queue; uint8_t *TFT_Queue::current_task = nullptr; uint8_t *TFT_Queue::last_task = nullptr; +uint8_t *TFT_Queue::last_parameter = nullptr; void TFT_Queue::reset() { tft.abort(); @@ -39,6 +40,7 @@ void TFT_Queue::reset() { end_of_queue = queue; current_task = nullptr; last_task = nullptr; + last_parameter = nullptr; } void TFT_Queue::async() { @@ -113,49 +115,28 @@ void TFT_Queue::canvas(queueTask_t *task) { switch (*item) { case CANVAS_SET_BACKGROUND: Canvas.SetBackground(((parametersCanvasBackground_t *)item)->color); - item += sizeof(parametersCanvasBackground_t); break; case CANVAS_ADD_TEXT: Canvas.AddText(((parametersCanvasText_t *)item)->x, ((parametersCanvasText_t *)item)->y, ((parametersCanvasText_t *)item)->color, item + sizeof(parametersCanvasText_t), ((parametersCanvasText_t *)item)->maxWidth); - item += sizeof(parametersCanvasText_t) + ((parametersCanvasText_t *)item)->stringLength; break; case CANVAS_ADD_IMAGE: MarlinImage image; uint16_t *colors; - colorMode_t color_mode; image = ((parametersCanvasImage_t *)item)->image; colors = (uint16_t *)(item + sizeof(parametersCanvasImage_t)); Canvas.AddImage(((parametersCanvasImage_t *)item)->x, ((parametersCanvasImage_t *)item)->y, image, colors); - - item = (uint8_t *)colors; - color_mode = Images[image].colorMode; - - switch (color_mode) { - case GREYSCALE1: - item += sizeof(uint16_t); - break; - case GREYSCALE2: - item += sizeof(uint16_t) * 3; - break; - case GREYSCALE4: - item += sizeof(uint16_t) * 15; - break; - default: - break; - } break; case CANVAS_ADD_BAR: Canvas.AddBar(((parametersCanvasBar_t *)item)->x, ((parametersCanvasBar_t *)item)->y, ((parametersCanvasBar_t *)item)->width, ((parametersCanvasBar_t *)item)->height, ((parametersCanvasBar_t *)item)->color); - item += sizeof(parametersCanvasBar_t); break; case CANVAS_ADD_RECTANGLE: Canvas.AddRectangle(((parametersCanvasRectangle_t *)item)->x, ((parametersCanvasRectangle_t *)item)->y, ((parametersCanvasRectangle_t *)item)->width, ((parametersCanvasRectangle_t *)item)->height, ((parametersCanvasRectangle_t *)item)->color); - item += sizeof(parametersCanvasRectangle_t); break; } + item = ((parametersCanvasBackground_t *)item)->nextParameter; } if (Canvas.ToScreen()) task->state = TASK_STATE_COMPLETED; @@ -172,6 +153,7 @@ void TFT_Queue::fill(uint16_t x, uint16_t y, uint16_t width, uint16_t height, ui parametersFill_t *task_parameters = (parametersFill_t *)end_of_queue; end_of_queue += sizeof(parametersFill_t); + last_parameter = end_of_queue; task_parameters->x = x; task_parameters->y = y; task_parameters->width = width; @@ -201,6 +183,7 @@ void TFT_Queue::canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height) parametersCanvas_t *task_parameters = (parametersCanvas_t *)end_of_queue; end_of_queue += sizeof(parametersCanvas_t); + last_parameter = end_of_queue; task_parameters->x = x; task_parameters->y = y; task_parameters->width = width; @@ -211,19 +194,33 @@ void TFT_Queue::canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height) } void TFT_Queue::set_background(uint16_t color) { + handle_queue_overflow(sizeof(parametersCanvasBackground_t)); parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); parametersCanvasBackground_t *parameters = (parametersCanvasBackground_t *)end_of_queue; + last_parameter = end_of_queue; parameters->type = CANVAS_SET_BACKGROUND; parameters->color = color; end_of_queue += sizeof(parametersCanvasBackground_t); task_parameters->count++; + parameters->nextParameter = end_of_queue; +} + +#define QUEUE_SAFETY_FREE_SPACE 100 + +void TFT_Queue::handle_queue_overflow(uint16_t sizeNeeded) { + if (uintptr_t(end_of_queue) + sizeNeeded + (QUEUE_SAFETY_FREE_SPACE) - uintptr_t(queue) >= QUEUE_SIZE) { + end_of_queue = queue; + ((parametersCanvasText_t *)last_parameter)->nextParameter = end_of_queue; + } } void TFT_Queue::add_text(uint16_t x, uint16_t y, uint16_t color, uint8_t *string, uint16_t maxWidth) { + handle_queue_overflow(sizeof(parametersCanvasText_t) + maxWidth); parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); parametersCanvasText_t *parameters = (parametersCanvasText_t *)end_of_queue; + last_parameter = end_of_queue; uint8_t *pointer = string; @@ -239,13 +236,16 @@ void TFT_Queue::add_text(uint16_t x, uint16_t y, uint16_t color, uint8_t *string /* TODO: Deal with maxWidth */ while ((*(end_of_queue++) = *pointer++) != 0x00); + parameters->nextParameter = end_of_queue; parameters->stringLength = pointer - string; task_parameters->count++; } void TFT_Queue::add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *colors) { + handle_queue_overflow(sizeof(parametersCanvasImage_t)); parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); parametersCanvasImage_t *parameters = (parametersCanvasImage_t *)end_of_queue; + last_parameter = end_of_queue; parameters->type = CANVAS_ADD_IMAGE; parameters->x = x; @@ -254,6 +254,7 @@ void TFT_Queue::add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *col end_of_queue += sizeof(parametersCanvasImage_t); task_parameters->count++; + parameters->nextParameter = end_of_queue; colorMode_t color_mode = Images[image].colorMode; @@ -275,6 +276,7 @@ void TFT_Queue::add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *col } end_of_queue = (uint8_t *)color; + parameters->nextParameter = end_of_queue; } uint16_t gradient(uint16_t colorA, uint16_t colorB, uint16_t factor) { @@ -314,8 +316,10 @@ void TFT_Queue::add_image(int16_t x, int16_t y, MarlinImage image, uint16_t colo } void TFT_Queue::add_bar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { + handle_queue_overflow(sizeof(parametersCanvasBar_t)); parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); parametersCanvasBar_t *parameters = (parametersCanvasBar_t *)end_of_queue; + last_parameter = end_of_queue; parameters->type = CANVAS_ADD_BAR; parameters->x = x; @@ -326,11 +330,14 @@ void TFT_Queue::add_bar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, end_of_queue += sizeof(parametersCanvasBar_t); task_parameters->count++; + parameters->nextParameter = end_of_queue; } void TFT_Queue::add_rectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { + handle_queue_overflow(sizeof(parametersCanvasRectangle_t)); parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t)); parametersCanvasRectangle_t *parameters = (parametersCanvasRectangle_t *)end_of_queue; + last_parameter = end_of_queue; parameters->type = CANVAS_ADD_RECTANGLE; parameters->x = x; @@ -341,6 +348,7 @@ void TFT_Queue::add_rectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t h end_of_queue += sizeof(parametersCanvasRectangle_t); task_parameters->count++; + parameters->nextParameter = end_of_queue; } #endif // HAS_GRAPHICAL_TFT diff --git a/Marlin/src/lcd/tft/tft_queue.h b/Marlin/src/lcd/tft/tft_queue.h index 9aa0d5b6c..6cb3caf4a 100644 --- a/Marlin/src/lcd/tft/tft_queue.h +++ b/Marlin/src/lcd/tft/tft_queue.h @@ -73,11 +73,13 @@ typedef struct __attribute__((__packed__)) { typedef struct __attribute__((__packed__)) { CanvasSubtype type; + uint8_t *nextParameter; uint16_t color; } parametersCanvasBackground_t; typedef struct __attribute__((__packed__)) { CanvasSubtype type; + uint8_t *nextParameter; uint16_t x; uint16_t y; uint16_t color; @@ -88,6 +90,7 @@ typedef struct __attribute__((__packed__)) { typedef struct __attribute__((__packed__)) { CanvasSubtype type; + uint8_t *nextParameter; int16_t x; int16_t y; MarlinImage image; @@ -95,6 +98,7 @@ typedef struct __attribute__((__packed__)) { typedef struct __attribute__((__packed__)) { CanvasSubtype type; + uint8_t *nextParameter; uint16_t x; uint16_t y; uint16_t width; @@ -104,6 +108,7 @@ typedef struct __attribute__((__packed__)) { typedef struct __attribute__((__packed__)) { CanvasSubtype type; + uint8_t *nextParameter; uint16_t x; uint16_t y; uint16_t width; @@ -117,10 +122,12 @@ class TFT_Queue { static uint8_t *end_of_queue; static uint8_t *current_task; static uint8_t *last_task; + static uint8_t *last_parameter; static void finish_sketch(); static void fill(queueTask_t *task); static void canvas(queueTask_t *task); + static void handle_queue_overflow(uint16_t sizeNeeded); public: static void reset();