generated from Projetos/RaspberryPi_app
Implement shadow buffer to stora changes in memory until update() method is called
This commit is contained in:
@@ -55,10 +55,14 @@ bool LinuxFBDisplay::open(const char* device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
shadow_ = new uint8_t[line_len_ * static_cast<uint32_t>(rawHeight())]();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LinuxFBDisplay::close() {
|
||||
delete[] shadow_;
|
||||
shadow_ = nullptr;
|
||||
if (buf_) {
|
||||
munmap(buf_, map_size_);
|
||||
buf_ = nullptr;
|
||||
@@ -69,6 +73,16 @@ void LinuxFBDisplay::close() {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Update — flush shadow buffer to the mmap'd framebuffer
|
||||
// ---------------------------------------------------------------------------
|
||||
void LinuxFBDisplay::update() {
|
||||
if (!buf_ || !shadow_) return;
|
||||
std::memcpy(buf_, shadow_,
|
||||
line_len_ * static_cast<uint32_t>(rawHeight()));
|
||||
fsync(fd_);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Pixel format conversion
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -98,8 +112,8 @@ void LinuxFBDisplay::writePixel(uint8_t* dst, Color color) const {
|
||||
void LinuxFBDisplay::drawPixelImpl(int16_t x, int16_t y, Color color) {
|
||||
if (!buf_) return;
|
||||
if (bpp_ == 1) {
|
||||
uint8_t* p = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) / 8;
|
||||
uint8_t* p = shadow_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) / 8;
|
||||
uint8_t bit = static_cast<uint32_t>(x) & 7u;
|
||||
if (color) *p |= (1u << bit);
|
||||
else *p &= ~(1u << bit);
|
||||
@@ -107,7 +121,7 @@ void LinuxFBDisplay::drawPixelImpl(int16_t x, int16_t y, Color color) {
|
||||
}
|
||||
uint32_t offset = static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * (bpp_ / 8);
|
||||
writePixel(buf_ + offset, color);
|
||||
writePixel(shadow_ + offset, color);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -118,7 +132,7 @@ void LinuxFBDisplay::drawHLineImpl(int16_t x, int16_t y,
|
||||
if (!buf_ || w <= 0) return;
|
||||
|
||||
if (bpp_ == 1) {
|
||||
uint8_t* row = buf_ + static_cast<uint32_t>(y) * line_len_;
|
||||
uint8_t* row = shadow_ + static_cast<uint32_t>(y) * line_len_;
|
||||
uint32_t x0 = static_cast<uint32_t>(x);
|
||||
uint32_t x1 = x0 + static_cast<uint32_t>(w) - 1;
|
||||
uint32_t b0 = x0 >> 3;
|
||||
@@ -147,8 +161,8 @@ void LinuxFBDisplay::drawHLineImpl(int16_t x, int16_t y,
|
||||
}
|
||||
|
||||
uint32_t bytes_pp = bpp_ / 8;
|
||||
uint8_t* row = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * bytes_pp;
|
||||
uint8_t* row = shadow_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * bytes_pp;
|
||||
|
||||
if (bpp_ == 32) {
|
||||
// For XRGB8888, use 32-bit fill.
|
||||
@@ -182,8 +196,8 @@ void LinuxFBDisplay::drawVLineImpl(int16_t x, int16_t y,
|
||||
|
||||
if (bpp_ == 1) {
|
||||
uint8_t bit = static_cast<uint32_t>(x) & 7u;
|
||||
uint8_t* p = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) / 8;
|
||||
uint8_t* p = shadow_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) / 8;
|
||||
for (int16_t i = 0; i < h; ++i) {
|
||||
if (color) *p |= (1u << bit);
|
||||
else *p &= ~(1u << bit);
|
||||
@@ -193,8 +207,8 @@ void LinuxFBDisplay::drawVLineImpl(int16_t x, int16_t y,
|
||||
}
|
||||
|
||||
uint32_t bytes_pp = bpp_ / 8;
|
||||
uint8_t* p = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * bytes_pp;
|
||||
uint8_t* p = shadow_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * bytes_pp;
|
||||
|
||||
// Pre-encode the pixel once.
|
||||
uint8_t pixel_buf[4];
|
||||
@@ -224,7 +238,7 @@ void LinuxFBDisplay::fillRectImpl(int16_t x, int16_t y,
|
||||
|
||||
if (h == 1) return;
|
||||
|
||||
uint8_t* src = buf_ + static_cast<uint32_t>(y) * line_len_ + b0;
|
||||
uint8_t* src = shadow_ + static_cast<uint32_t>(y) * line_len_ + b0;
|
||||
uint32_t span = b1 - b0 + 1;
|
||||
|
||||
if ((x0 & 7u) == 0 && (x1 & 7u) == 7u) {
|
||||
@@ -249,8 +263,8 @@ void LinuxFBDisplay::fillRectImpl(int16_t x, int16_t y,
|
||||
|
||||
uint32_t bytes_pp = bpp_ / 8;
|
||||
uint32_t row_bytes = static_cast<uint32_t>(w) * bytes_pp;
|
||||
uint8_t* first_row = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * bytes_pp;
|
||||
uint8_t* first_row = shadow_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * bytes_pp;
|
||||
|
||||
// Optimized path: if all bytes of the pixel are the same value,
|
||||
// the entire rect can be filled with memset.
|
||||
|
||||
@@ -28,6 +28,9 @@ public:
|
||||
// Is the framebuffer currently open and mapped?
|
||||
bool isOpen() const { return buf_ != nullptr; }
|
||||
|
||||
// Copy the internal shadow buffer to the framebuffer, triggering a display refresh.
|
||||
void update();
|
||||
|
||||
protected:
|
||||
// Mandatory HAL: single pixel write.
|
||||
void drawPixelImpl(int16_t x, int16_t y, Color color) override;
|
||||
@@ -40,7 +43,8 @@ protected:
|
||||
|
||||
private:
|
||||
int fd_ = -1;
|
||||
uint8_t* buf_ = nullptr;
|
||||
uint8_t* buf_ = nullptr; // mmap'd framebuffer
|
||||
uint8_t* shadow_ = nullptr; // internal draw target
|
||||
size_t map_size_ = 0;
|
||||
uint32_t bpp_ = 0;
|
||||
uint32_t line_len_ = 0;
|
||||
|
||||
Reference in New Issue
Block a user