From 1af952dcda9f532b0616f083241689b49b248752 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 13 Oct 2026 14:08:36 -1000 Subject: [PATCH] Put a compatible block into the buffer when a writer owns one, so the update flush keeps it --- esphome/components/mipi_dsi/mipi_dsi.cpp | 13 +++++++++++++ esphome/components/mipi_rgb/mipi_rgb.cpp | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/esphome/components/mipi_dsi/mipi_dsi.cpp b/esphome/components/mipi_dsi/mipi_dsi.cpp index 9753b6db609..82f8c31c9f1 100644 --- a/esphome/components/mipi_dsi/mipi_dsi.cpp +++ b/esphome/components/mipi_dsi/mipi_dsi.cpp @@ -4,6 +4,7 @@ #include "esphome/core/helpers.h" #include +#include namespace esphome::mipi_dsi { @@ -228,6 +229,18 @@ void MipiDsi::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8 this->flush_dirty_(); return; } + if (this->buffer_ != nullptr) { + // A writer is drawing into the buffer, which the end of update() flushes over the panel; the + // block goes into the buffer too, or that flush would paint the old contents over it. + const size_t bytes_per_pixel = 3 - this->color_depth_; + const size_t stride = x_offset + w + x_pad; + for (int y = 0; y != h; y++) { + memcpy(this->buffer_ + ((y_start + y) * this->width_ + x_start) * bytes_per_pixel, + ptr + ((y_offset + y) * stride + x_offset) * bytes_per_pixel, w * bytes_per_pixel); + } + this->mark_dirty_(x_start, y_start, w, h); + return; + } this->write_to_display_(x_start, y_start, w, h, ptr, x_offset, y_offset, x_pad); } diff --git a/esphome/components/mipi_rgb/mipi_rgb.cpp b/esphome/components/mipi_rgb/mipi_rgb.cpp index 08bbf31282c..98a95098782 100644 --- a/esphome/components/mipi_rgb/mipi_rgb.cpp +++ b/esphome/components/mipi_rgb/mipi_rgb.cpp @@ -6,6 +6,7 @@ #include "esphome/core/log.h" #include +#include #include #include #include @@ -226,6 +227,15 @@ void MipiRgb::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8 Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset, x_pad); this->mark_dirty_(x_start, y_start, w, h); this->flush_dirty_(); + } else if (this->buffer_ != nullptr) { + // A writer is drawing into the buffer, which the end of update() flushes over the panel; the + // block goes into the buffer too, or that flush would paint the old contents over it. + const size_t stride = x_offset + w + x_pad; + for (int y = 0; y != h; y++) { + memcpy(this->buffer_ + (y_start + y) * this->width_ + x_start, ptr + ((y_offset + y) * stride + x_offset) * 2, + w * 2); + } + this->mark_dirty_(x_start, y_start, w, h); } else { this->write_to_display_(x_start, y_start, w, h, ptr, x_offset, y_offset, x_pad); }