Xinyuan-LilyGO / LilyGo-AMOLED-Series

LilyGo AMOLED Series
MIT License
88 stars 14 forks source link

Partial screen updates: behaviours of pushColors & setAddrWind for 2.4 inch board need clarifying in code/headers #6

Closed scuba-hacker closed 5 months ago

scuba-hacker commented 5 months ago

Please add comments in the LilyGo_AMOLED.h/.cpp files to explain that there are restrictions on the use of pushColors and setAddrWind for the 2.4 inch board. I have come across these issues when using this functions to send TFT_eSprites that are not full screen (ie partial screen updates, as opposed to the TFT_eSPI example which uses full screen updates).

  1. The sprite width must be a multiple of 2, otherwise the sprite is written to the display with a 45 degree skew.
  2. The xs parameter in setAddrWindow must also be a multiple of 2 otherwise output is skewed.

Currently there is no method for writing a sprite to the display that has an odd number of pixels width and/or is pushed to an odd numbered x-pixel location. I understand this might be due to the limitations of the 0x32 SPI command that is used in pushColors due to QSPI being used by this board, but is there not another command that can be used to deal with these conditions?

I don't see anyway of doing a smooth pixel-by-pixel horizontal scroll of any sprite, regardless of width, using partial screen updates.

Here's some example code to illustrate the problem. The top sprite output is good and the bottom sprite output is skewed.


#include "esp_arduino_version.h"
#if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3,0,0)
#include <LilyGo_AMOLED.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();
LilyGo_AMOLED amoled;

#define WIDTH  amoled.height()
#define HEIGHT amoled.width()

TFT_eSprite* blackBackground=nullptr, *tile=nullptr;

const int backgroundWidth=370;    // sprite width has to be divisible by 2 or sprite will be skewed
const int backgroundHeight=255;   // sprite height can be odd or even

void setup()
{
  amoled.begin();

  blackBackground = new TFT_eSprite(&tft);
  blackBackground->createSprite(backgroundWidth,backgroundHeight);   

  // create a graphic that can illustrate the skew for bad writes
  tile = new TFT_eSprite(&tft);
  tile->createSprite(200,250);

  tile->fillCircle(100,100,50,TFT_WHITE);
  tile->fillCircle(100,190,30,TFT_RED);
  tile->drawRect(0,0,199,249,TFT_GREEN);
}

const int maxLateralShift=150, minLateralShift=0;
int lateralShift=minLateralShift;
int step=1;

void loop()
{
    // black out the background sprite
    blackBackground->fillSprite(TFT_BLACK);
    // write the tile graphic to the background sprite
    tile->pushToSprite(blackBackground,lateralShift,0);

    int spriteOffsetX=30;      // x offset has to be divisible by 2 or sprite write will be skewed.
    int spriteOffsetY=19;      // y offset can be odd or even

    // demo good write (only good if backgroundWidth is divisible by 2)
    amoled.setAddrWindow(spriteOffsetX, spriteOffsetY, backgroundWidth+spriteOffsetX-1, backgroundHeight+spriteOffsetY-1);
    amoled.pushColors((uint16_t*)(blackBackground->getPointer()),backgroundWidth * backgroundHeight);

    // demo bad write (skewed) with odd X spriteOffsetX (always skews regardless of backgroundWidth)
    spriteOffsetX++;
    spriteOffsetY = spriteOffsetY + 300;

    amoled.setAddrWindow(spriteOffsetX, spriteOffsetY, backgroundWidth+spriteOffsetX-1, backgroundHeight+spriteOffsetY-1);
    amoled.pushColors((uint16_t*)(blackBackground->getPointer()),backgroundWidth * backgroundHeight);

    if (lateralShift == maxLateralShift)
      step=-1;
    else if(lateralShift == minLateralShift)
      step=1;

    lateralShift+=step;
}
#endif```
lewisxhe commented 5 months ago

Hi , @scuba-hacker

The work I do is limited, most of it is based on lvgl. For what you mentioned, can you submit a PR?

scuba-hacker commented 5 months ago

Hi , @scuba-hacker

The work I do is limited, most of it is based on lvgl. For what you mentioned, can you submit a PR?

Sure, will do!