Merge pull request #240 from joaquimorg/ScreenCorruptionFIX

FIX screen corruption (Issue #213)
This commit is contained in:
JF002 2021-03-20 18:10:13 +01:00 committed by GitHub
commit a3ff2e46ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 80 deletions

View file

@ -17,9 +17,8 @@ void Gfx::ClearScreen() {
state.busy = true; state.busy = true;
state.action = Action::FillRectangle; state.action = Action::FillRectangle;
state.taskToNotify = xTaskGetCurrentTaskHandle(); state.taskToNotify = xTaskGetCurrentTaskHandle();
lcd.BeginDrawBuffer(0, 0, width, height); lcd.DrawBuffer(0, 0, width, height, reinterpret_cast<const uint8_t *>(buffer), width * 2);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(buffer), width * 2);
WaitTransferFinished(); WaitTransferFinished();
} }
@ -34,8 +33,7 @@ void Gfx::FillRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t col
state.color = color; state.color = color;
state.taskToNotify = xTaskGetCurrentTaskHandle(); state.taskToNotify = xTaskGetCurrentTaskHandle();
lcd.BeginDrawBuffer(x, y, w, h); lcd.DrawBuffer(x, y, w, h, reinterpret_cast<const uint8_t *>(buffer), width * 2);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(buffer), width * 2);
WaitTransferFinished(); WaitTransferFinished();
} }
@ -48,8 +46,7 @@ void Gfx::FillRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t* b)
state.color = 0x00; state.color = 0x00;
state.taskToNotify = xTaskGetCurrentTaskHandle(); state.taskToNotify = xTaskGetCurrentTaskHandle();
lcd.BeginDrawBuffer(x, y, w, h); lcd.DrawBuffer(x, y, w, h, reinterpret_cast<const uint8_t *>(b), width * 2);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(b), width * 2);
WaitTransferFinished(); WaitTransferFinished();
} }
@ -120,8 +117,7 @@ void Gfx::DrawChar(const FONT_INFO *font, uint8_t c, uint8_t *x, uint8_t y, uint
state.color = color; state.color = color;
state.taskToNotify = xTaskGetCurrentTaskHandle(); state.taskToNotify = xTaskGetCurrentTaskHandle();
lcd.BeginDrawBuffer(*x, y, bytes_in_line*8, font->height); lcd.DrawBuffer(*x, y, bytes_in_line*8, font->height, reinterpret_cast<const uint8_t *>(&buffer), bytes_in_line*8*2);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(&buffer), bytes_in_line*8*2);
WaitTransferFinished(); WaitTransferFinished();
*x += font->charInfo[char_idx].widthBits + font->spacePixels; *x += font->charInfo[char_idx].widthBits + font->spacePixels;

View file

@ -67,65 +67,47 @@ void LittleVgl::SetFullRefresh(FullRefreshDirections direction) {
} }
void LittleVgl::FlushDisplay(const lv_area_t *area, lv_color_t *color_p) { void LittleVgl::FlushDisplay(const lv_area_t *area, lv_color_t *color_p) {
uint16_t y1, y2, width, height = 0;
ulTaskNotifyTake(pdTRUE, 500); ulTaskNotifyTake(pdTRUE, 500);
// Notification is still needed (even if there is a mutex on SPI) because of the DataCommand pin // Notification is still needed (even if there is a mutex on SPI) because of the DataCommand pin
// which cannot be set/clear during a transfer. // which cannot be set/clear during a transfer.
if( (scrollDirection == LittleVgl::FullRefreshDirections::Down) && (area->y2 == visibleNbLines - 1)) {
writeOffset = ((writeOffset + totalNbLines) - visibleNbLines) % totalNbLines;
} else if( (scrollDirection == FullRefreshDirections::Up) && (area->y1 == 0) ) {
writeOffset = (writeOffset + visibleNbLines) % totalNbLines;
}
// TODO refactore and remove duplicated code y1 = (area->y1 + writeOffset) % totalNbLines;
y2 = (area->y2 + writeOffset) % totalNbLines;
width = (area->x2 - area->x1) + 1;
height = (area->y2 - area->y1) + 1;
uint16_t x, y, y1, y2, width, height = 0;
if(scrollDirection == LittleVgl::FullRefreshDirections::Down) { if(scrollDirection == LittleVgl::FullRefreshDirections::Down) {
if(area->y2 == visibleNbLines-1) {
writeOffset = ((writeOffset + totalNbLines) - visibleNbLines) % totalNbLines;
}
x = area->x1;
width = (area->x2 - area->x1) + 1;
y1 = (area->y1 + writeOffset) % totalNbLines;
y2 = (area->y2 + writeOffset) % totalNbLines;
y = y1;
height = (y2 - y1) + 1;
if(area->y2 < visibleNbLines - 1) { if(area->y2 < visibleNbLines - 1) {
uint16_t toScroll = 0; uint16_t toScroll = 0;
if(area->y1 == 0) { if(area->y1 == 0) {
toScroll = height*2; toScroll = height * 2;
scrollDirection = FullRefreshDirections::None; scrollDirection = FullRefreshDirections::None;
lv_disp_set_direction(lv_disp_get_default(), 0); lv_disp_set_direction(lv_disp_get_default(), 0);
} else { } else {
toScroll = height; toScroll = height;
} }
if(scrollOffset >= toScroll) if(scrollOffset >= toScroll)
scrollOffset -= toScroll; scrollOffset -= toScroll;
else { else {
toScroll -= scrollOffset; toScroll -= scrollOffset;
scrollOffset = (totalNbLines) - toScroll; scrollOffset = (totalNbLines) - toScroll;
} }
lcd.VerticalScrollDefinition(0, 320, 0);
lcd.VerticalScrollStartAddress(scrollOffset); lcd.VerticalScrollStartAddress(scrollOffset);
} }
lcd.BeginDrawBuffer(x, y, width, height);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height*2) ;
} else if(scrollDirection == FullRefreshDirections::Up) { } else if(scrollDirection == FullRefreshDirections::Up) {
if(area->y1 == 0) {
writeOffset = (writeOffset + visibleNbLines) % totalNbLines;
}
x = area->x1;
width = (area->x2 - area->x1) + 1;
y1 = (area->y1 + writeOffset) % totalNbLines;
y2 = (area->y2 + writeOffset) % totalNbLines;
y = y1;
height = (y2 - y1) + 1;
if(area->y1 > 0) { if(area->y1 > 0) {
if(area->y2 == visibleNbLines -1) { if(area->y2 == visibleNbLines - 1) {
scrollOffset += (height * 2); scrollOffset += (height * 2);
scrollDirection = FullRefreshDirections::None; scrollDirection = FullRefreshDirections::None;
lv_disp_set_direction(lv_disp_get_default(), 0); lv_disp_set_direction(lv_disp_get_default(), 0);
@ -133,36 +115,27 @@ void LittleVgl::FlushDisplay(const lv_area_t *area, lv_color_t *color_p) {
scrollOffset += height; scrollOffset += height;
} }
scrollOffset = scrollOffset % totalNbLines; scrollOffset = scrollOffset % totalNbLines;
lcd.VerticalScrollDefinition(0, 320, 0);
lcd.VerticalScrollStartAddress(scrollOffset); lcd.VerticalScrollStartAddress(scrollOffset);
} }
lcd.BeginDrawBuffer(x, y, width, height);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height*2);
} else {
x = area->x1;
width = (area->x2 - area->x1) + 1;
y1 = (area->y1 + writeOffset) % totalNbLines;
y2 = (area->y2 + writeOffset) % totalNbLines;
y = y1;
height = (y2 - y1) + 1;
if (y2 < y1) {
height = (totalNbLines - 1) - y1;
lcd.BeginDrawBuffer(x, y1, width, height);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height * 2);
ulTaskNotifyTake(pdTRUE, 500);
height = y2;
lcd.BeginDrawBuffer(x, 0, width, height);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height * 2);
} else {
lcd.BeginDrawBuffer(x, y, width, height);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height * 2);
}
} }
/* IMPORTANT!!! if (y2 < y1) {
* Inform the graphics library that you are ready with the flushing*/ height = totalNbLines - y1;
if ( height > 0 ) {
lcd.DrawBuffer(area->x1, y1, width, height, reinterpret_cast<const uint8_t *>(color_p), width * height * 2);
ulTaskNotifyTake(pdTRUE, 320);
}
uint16_t pixOffset = width * height;
height = y2 + 1;
lcd.DrawBuffer(area->x1, 0, width, height, reinterpret_cast<const uint8_t *>(color_p + pixOffset), width * height * 2);
} else {
lcd.DrawBuffer(area->x1, y1, width, height, reinterpret_cast<const uint8_t *>(color_p), width * height * 2);
}
// IMPORTANT!!!
// Inform the graphics library that you are ready with the flushing
lv_disp_flush_ready(&disp_drv); lv_disp_flush_ready(&disp_drv);
} }

View file

@ -153,16 +153,9 @@ void St7789::DrawPixel(uint16_t x, uint16_t y, uint32_t color) {
WriteSpi(reinterpret_cast<const uint8_t *>(&color), 2); WriteSpi(reinterpret_cast<const uint8_t *>(&color), 2);
} }
void St7789::BeginDrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { void St7789::DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *data, size_t size) {
if((x >= Width) || (y >= Height)) return; SetAddrWindow(x, y, x + width - 1, y + height - 1);
if((x + width - 1) >= Width) width = Width - x;
if((y + height - 1) >= Height) height = Height - y;
SetAddrWindow(0+x, ST7789_ROW_OFFSET+y, x+width-1, y+height-1);
nrf_gpio_pin_set(pinDataCommand); nrf_gpio_pin_set(pinDataCommand);
}
void St7789::NextDrawBuffer(const uint8_t *data, size_t size) {
WriteSpi(data, size); WriteSpi(data, size);
} }

View file

@ -20,9 +20,7 @@ namespace Pinetime {
void VerticalScrollDefinition(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines); void VerticalScrollDefinition(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines);
void VerticalScrollStartAddress(uint16_t line); void VerticalScrollStartAddress(uint16_t line);
void DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *data, size_t size);
void BeginDrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
void NextDrawBuffer(const uint8_t* data, size_t size);
void DisplayOn(); void DisplayOn();
void DisplayOff(); void DisplayOff();