High speed vector graphics engine. 3.2" TFT Lcd screen.

I use the same screen in my project so I'm watching with interest!

I can't wait to see the sources.

Great results. Anxious here too..

I've only just finished some major improvements, and started tidying up the source. I have to work today, but over the next 2-3 days I'll try and have the first version ready. I have just embedded Henning Karlsens UTouch library into it, with a few speedups via port mapping and an additional control mode.

I'm almost finished adding rotation to the code ( why utouch was embedded, it needs to rotate as well ). By using the building blocks I've provided, it will be easy to control orientation with an accelerometer for instance, like android.

I'm going to focus on text rendering now so there is a more 'complete' release for everyone to try. But regardless of completion, I'll post something by Thursday night.

Cheers.

Sounds great. How are you going to handle text rendering? I guess you are not going for truetype fonts.. Then maybe use utft fonts, just because they already exist and there are couple of fonts already available..
Or are you planning on going with a slimmer design for that too?

Sounds great. How are you going to handle text rendering? I guess you are not going for truetype fonts.. Then maybe use utft fonts, just because they already exist and there are couple of fonts already available..

Yes, For now I'm going to take the easiest route for font data, utft and u8glib are my first choice for this. My main focus is getting pixels to the display as fast as possible. I've been thinking about a vector style font which would be my own interpretation of a truetype font just without control point distortion hints, or very limited hints. Even still, having a pixel map decompressed from program memory might possibly be faster.

From observation, vector style fonts may be faster for larger font sizes, as a new line algorithm that is suitable for the display can calculate multiple pixel runs, but will need a transformation to screen space. Whereas pixel maps don't need calculating but may not be able to benefit from runs.

Or are you planning on going with a slimmer design for that too?

Maybe if suitable, slimmer/smaller isn't really my goal, the design aspects of my library are selected on how well they perform. If a handful of extra bytes will increase performance dramatically, then I'll go for the larger. But don't worry, I have plans for a full config where you can select what parts are small ( code reuse ) and what parts are allowed to trade off size for speed ( specific routines for different drawing functionality).

And on a note for the future,
I also dug out my second display, which turns out to be a HX8347A?? ( TFT_320QVT ). Once the ball is rolling I may look into supporting a few other displays, however this may be an unrealistic move as my library is tailored to the SSD1289. It really seems like a few manufacturers have the monopoly on TFT production like the TV market. Same screens, different firmware/driver.

I'm gonna hit post now as lack of sleep will cause me to keep rambling on for pages. Its nice to see a lot of interest, I'm keen to see what creations people will cook up.

I'm learning the DUE and I have just obtained a SainSmart 3.2" 320x240 TFT (with the SSD1289 driver). Have you (or anyone) done anything with porting/testing your graphics library to the DUE from the Mega 2560? I would guess that your code should work with a DUE without too much change. Any code that I could download and get started with? Thanks!

Similar note -- is this Arduino (library) specific, or would it work in GNU AVR world too? I've put some graphic-LCD projects on the back burner because performance has always been a bit of a hindrance. Tenfold improvements are a cool drink of water sir.

Well, well done.

really waiting to get handle and to test that ! 8)

Hi all,
I'm also eager to see the version of pYro_65.

In the meantime, here is a simple method for optimizing (a little bit) the current version: First download the latest version from the site "henningkarlsen" which dates from January 2013 and contains some optimizations,
then remove all the tests on display_transfer_mode especially in methods such as LCD_Writ_Bus or LCD_Write_COM.
For example, my LCD_Writ_Bus method :

void UTFT::LCD_Writ_Bus(char VH,char VL)
{
PORTA = VH;
PORTC = VL;
pulse_low(P_WR, B_WR);
}

With this modification, some methods are twice as fast : drawpixel (100µs instead of 200µs), print, DrawBitmap, DrawLine, etc.
Of course my TFT version only works with screen SSD1289 but no problem since it is the only one I have.
This is far from what announces pYro_65 but in the meantime it helps.

hi mael,

already done on my side to clean all the unnecessary code in UTFT :smiley:

but still far of what this post promise .

news?

blackmaster:
news?

Some news ????

I'm waiting for this "Library Mod" !! 8)

dead

pYro, you gave up, or.. ? :slight_smile:

vincent13:
hi mael,

already done on my side to clean all the unnecessary code in UTFT :smiley:

but still far of what this post promise .

Hi Vincent13,
I coded a workbench to compare my optimizations with the original version.
Here are my results :

start...
Initial version time - optimized version time - opération
724576 us     - 37248 us   : clrScr
200 us        - 24 us      : DrawPixel
2020 us       - 232 us     : DrawPixel x 10
4 us          - 4          : SetColor
4 us          - 4          : SetBackColor
19856 us      - 5804 us    : FillRoundRect 40x40
2652 us       - 636 us     : DrawRoundRect 40x40
4928 us       - 916 us     : drawLine 40x40
604 us        - 152 us     : draw Vertical Line 40
612 us        - 144 us     : draw Horizontal Line 40
27836 us      - 1480 us    : FillRect 40x40
8 us          - 8          : SetSmallFont
7764 us       - 2300 us    : Print 001
7640 us       - 2300 us    : Print Abc
7892 us       - 2580 us    : printNumI(123)
8 us          - 8          : SetBigFont
14912 us      - 4332 us    : Print 001
15048 us      - 4424 us    : printNumI(123)
11668 us      - 2412 us    : draw bitmap 32x32

Do you have better results ? (do you want my WorkBench sketch ?)

Quite impressive numbers here! Well done!

yep why not compare :wink:

give me access to your bench code using mp :sweat_smile:

Mael hello, can you share your optimised library please? :slight_smile:

This is my bench sketch :

//Bench.ino
//Maël - 01/03/2013
//Mesure le temps de différentes methodes des lib UTFT et UTouch et envoi les temps sur le port Serie (115200 bauds)

#include <UTFT.h>
#include <UTouch.h>

#include "icon.h"

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

// Tft, touchscreen for Arduino Mega
UTFT myGLCD(ITDB32S,38,39,40,41);  
UTouch myTouch(6,5,4,3,2);

extern unsigned int icon[0x400];

//pointeur de fonction simple
typedef void TFunction(void);

typedef struct  
{
  TFunction * process; //pointeur sur la methode à chronometrer
  String text;         //nom du test (apparaitra sur la console)
} TProcessInfo;

void InitTFT()
{
// Setup the LCD, touch screen
  myGLCD.InitLCD(LANDSCAPE);
  myTouch.InitTouch(LANDSCAPE);
  myTouch.setPrecision(PREC_LOW); //PREC_MEDIUM
  
  myGLCD.clrScr();
}

void MeasureDrawPixel(void)
{
  myGLCD.drawPixel(0,0);
}

void MeasureDraw10Pixels(void)
{
  for (int i = 0; i < 10; i++)
    myGLCD.drawPixel(i,i);
}

void MeasureSetColor()
{
  myGLCD.setColor(255, 255, 255);
}

void MeasureSetBackColor()
{
  myGLCD.setBackColor(64, 64, 64);
}

void MeasureFillRoundRect()
{
  myGLCD.fillRoundRect(10, 10, 50, 50);
}

void MeasureDrawRoundRect()
{
  myGLCD.drawRoundRect(110, 10, 150, 50);
}

void MeasureDrawLine()
{
  myGLCD.drawLine(210, 10, 250, 50);
}

void MeasureDrawVLine()
{
  myGLCD.drawLine(270, 10, 270, 50);
}

void MeasureDrawHLine()
{
  myGLCD.drawLine(230, 20, 270, 20);
}

void MeasureFillRect()
{
  myGLCD.fillRect(100, 100, 50, 150);
}

void MeasureSetSmallFont()
{
  myGLCD.setFont(SmallFont);
}

void MeasurePrintText()
{
  myGLCD.print("001", 1, 1);    
}

void MeasurePrintTextAbc()
{
  myGLCD.print("Abc", 1, 1);    
}

void MeasureSetBigFont()
{
  myGLCD.setFont(BigFont);
}

void MeasureclrScr()
{
  myGLCD.clrScr();
}

void MeasureBitmap()
{
 myGLCD.drawBitmap (200, 10, 32, 32, icon);
}

void MeasurePrintNum()
{
  int num = 123;
  myGLCD.printNumI(num, 200, 100);
}

void MeasureTouch_dataAvailable()
{
  boolean b = myTouch.dataAvailable();
}

void MeasureTouch_read()
{
  myTouch.read();
}

void MeasureTouch_getxy()
{
  int x=myTouch.getX();
  int y=myTouch.getY();
}

//Liste des méthodes à mesurer
#define LIST_COUNT 22
TProcessInfo ListOfMeasures[LIST_COUNT] = {
  { MeasureclrScr, "clrScr" },
  { MeasureDrawPixel, "DrawPixel" },
  { MeasureDraw10Pixels, "DrawPixel x 10" },
  { MeasureSetColor, "SetColor" },
  { MeasureSetBackColor, "SetBackColor" },
  { MeasureFillRoundRect, "FillRoundRect 40x40" },
  { MeasureDrawRoundRect, "DrawRoundRect 40x40" },
  { MeasureDrawLine, "drawLine 40x40" },
  { MeasureDrawVLine, "draw Vertical Line 40" },
  { MeasureDrawHLine, "draw Horizontal Line 40" },
  { MeasureFillRect, "FillRect 40x40" },
  { MeasureSetSmallFont, "SetSmallFont" },
  { MeasurePrintText, "Print 001" },
  { MeasurePrintTextAbc, "Print Abc" },
  { MeasurePrintNum, "printNumI(123)" },
  { MeasureSetBigFont, "SetBigFont" },
  { MeasurePrintText, "Print 001" },
  { MeasurePrintNum, "printNumI(123)" },
  { MeasureBitmap, "draw bitmap 32x32" },
  //Mesure des optimisations sur UTouch (en debogage)
  { MeasureTouch_dataAvailable, "Touch Screen DataAvailable"},
  { MeasureTouch_read, "Touch Screen Read"},
  { MeasureTouch_getxy, "Touch Screen getX, getY"}
  };

void Measure()
{
  Serial.println("start...");
  unsigned long ChronoAll = micros();
  for (int i = 0; i < LIST_COUNT; i++)
  {
    if ( ListOfMeasures[i].process != NULL)
    {
      unsigned long ChronoOne = micros();
      ListOfMeasures[i].process();
      ChronoOne = micros() - ChronoOne;
      Serial.print(ChronoOne, DEC);
      Serial.print(" us : ");
      Serial.println(ListOfMeasures[i].text);
    }
  }
  ChronoAll = micros() - ChronoAll;
  Serial.print("finish in ");
  Serial.print(ChronoAll, DEC);
  Serial.println(" us.");
}

void setup()
{
  Serial.begin(115200);
  Serial.println("ready.");
  InitTFT();
  
  Measure();
}

void loop()
{
}

Maël.