Page 3 of 6

Re: TextOut y value

Posted: 08 Feb 2012, 07:03
by mspall
This might be a better way to report this data, average ticks /TextOut()
.344 ticks/TextOut()
.430 ticks/TextOut()
1.08 ticks/TextOut()

How fast vs flexible do we want or need TextOut() to be?

Re: TextOut y value

Posted: 08 Feb 2012, 07:12
by mattallen37
Well, I'm fine with half the speed it used to be. John said he used a crude method of setting the bits in the latest FW, that's probably why it's so slow. Now that he will be using bit-math on the whole 16 bits at once, it should be significantly faster than 1.08 ticks per draw.

I'm curious though, what if you set all the y values to LCD_LINE1-1, so to speak. Offset them all to some degree, and see if that effects the speed.

Re: TextOut y value

Posted: 08 Feb 2012, 09:14
by HaWe
...and BTW the speed when using ric fonts instead would be also interestring to see :)

Re: TextOut y value

Posted: 08 Feb 2012, 19:14
by afanofosc
On my NXT with the not yet uploaded firmware image using Nicolas' code I get 5931. Latest compiler, optimization level 3. That seems pretty respectable.

John Hansen

Re: TextOut y value

Posted: 08 Feb 2012, 19:25
by afanofosc
With this code I get 5931 followed much later by 63062:

Code: Select all

#download "tahoma8.ric"

task main()
{
  unsigned int i, s, f, diff;
  s = CurrentTick();
  for(int i=0; i<1000; i++) {
    TextOut(0,LCD_LINE1,"Cicero scripsit:");
    TextOut(0,LCD_LINE2,"Neque porro quisquam");
    TextOut(0,LCD_LINE3,"est, qui dolorem");
    TextOut(0,LCD_LINE4,"ipsum,quia dolor sit");
    TextOut(0,LCD_LINE5,"amet, consectetur,");
    TextOut(0,LCD_LINE6,"adipisci con velit-");
    TextOut(0,LCD_LINE7,"Sed Cicero");
    TextOut(0,LCD_LINE8,"erat iniuriam:");

    TextOut(0,LCD_LINE1,"Neque porro quisquam");
    TextOut(0,LCD_LINE2,"est, qui dolorem");
    TextOut(0,LCD_LINE3,"ipsum,quia dolor sit");
    TextOut(0,LCD_LINE4,"amet, consectetur,");
    TextOut(0,LCD_LINE5,"adipisci con velit-");
    TextOut(0,LCD_LINE6,"Sed Cicero");
    TextOut(0,LCD_LINE7,"erat iniuriam:");
    TextOut(0,LCD_LINE8,"Redundant est!");
  }
  f = CurrentTick();
  diff = f - s;
  ClearScreen();
  NumOut(0,LCD_LINE1,diff);
  Wait(SEC_5);
  s = CurrentTick();
  for(int i=0; i<1000; i++) {
    FontTextOut(0,LCD_LINE1,"tahoma8.ric", "Cicero scripsit:");
    FontTextOut(0,LCD_LINE2,"tahoma8.ric", "Neque porro quisquam");
    FontTextOut(0,LCD_LINE3,"tahoma8.ric", "est, qui dolorem");
    FontTextOut(0,LCD_LINE4,"tahoma8.ric", "ipsum,quia dolor sit");
    FontTextOut(0,LCD_LINE5,"tahoma8.ric", "amet, consectetur,");
    FontTextOut(0,LCD_LINE6,"tahoma8.ric", "adipisci con velit-");
    FontTextOut(0,LCD_LINE7,"tahoma8.ric", "Sed Cicero");
    FontTextOut(0,LCD_LINE8,"tahoma8.ric", "erat iniuriam:");

    FontTextOut(0,LCD_LINE1,"tahoma8.ric", "Neque porro quisquam");
    FontTextOut(0,LCD_LINE2,"tahoma8.ric", "est, qui dolorem");
    FontTextOut(0,LCD_LINE3,"tahoma8.ric", "ipsum,quia dolor sit");
    FontTextOut(0,LCD_LINE4,"tahoma8.ric", "amet, consectetur,");
    FontTextOut(0,LCD_LINE5,"tahoma8.ric", "adipisci con velit-");
    FontTextOut(0,LCD_LINE6,"tahoma8.ric", "Sed Cicero");
    FontTextOut(0,LCD_LINE7,"tahoma8.ric", "erat iniuriam:");
    FontTextOut(0,LCD_LINE8,"tahoma8.ric", "Redundant est!");
  }
  f = CurrentTick();
  diff = f - s;
  ClearScreen();
  NumOut(0,LCD_LINE1,diff);
  while(true);
}
FontTextOut is definitely much slower - but more flexible, for certain.

With offsets such as -1, -2, or -4 from the standard lines the TextOut result was around 6050.

John Hansen

Re: TextOut y value

Posted: 08 Feb 2012, 21:36
by schodet
afanofosc wrote:If you have any ideas what I might be doing wrong with my JMPABSVAR opcode (and almost certainly the BRCMPABSVAR and BRTSTABSVAR opcodes) I'd be grateful for the assistance there as well. I'll check in the code later on tonight so you can have a look at it, if you are interested.
I think my compiler is generating the right value for the absolute address to jump to (which I am trying to convert into a relative jump offset) but I wind up getting a ERR_INSTR file abort.
This seems much more complicated than some bit logic :) but I can give it a try if I understand what it is supposed to do.

Re: TextOut y value

Posted: 08 Feb 2012, 22:36
by afanofosc
I think it might be possible to speed up the copybits code for drawing RIC sprites. This is where I got the "iterate through each bit in the current font byte" logic from but the routine is structured in a way that makes it a little harder to switch to Nicolas' code inside the nested for loops. I think, though, that with a little thought we could improve this in a similar fashion. It may not need to use any masking across 2 lines like with the text drawing - except perhaps on the top row of the sprite data and the bottom row of the sprite data when that row is drawn at a Y value that is not a multiple of 8.

Code: Select all

void cCmdCopyBitMapBits(
  SLONG dst_x,  // left pixel on LCD
  SLONG dst_y,  // bottom pixel on LCD
  SLONG src_x,  // starting pixel x coordinate from source map
  SLONG src_y,  // starting pixel y coordinate from source map
  SLONG src_width, // width in pixels to the right (negative implies to the left)
  SLONG src_height, // height in pixels down (negative implies down)
  IMG_OP_SPRITE * pSprite, UBYTE InvertMode, UBYTE LogicalMode, UBYTE FillMode)
{
  SLONG dy;  // Location in the destination pixmap , the screen that is
  SLONG sx;
  SLONG sy;  // Location in the source pixmap.
  SLONG trim, last_x, last_y, rowbytes;
  UBYTE *pSrcByte;
  UBYTE srcByte;      //JJR
  UBYTE *pDstBytes;
  UBYTE *pDstByte, *pFirstDstByte;
  UBYTE *pLastDstByte;
  UBYTE bit_y;                //JJR
  UBYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

  // Data in the image file is row major 8 pixels per byte. top row first.
  // src and dst coordinates treat the bottom left most pixel as (0,0)

  if (!pSprite || pSprite->OpCode!=IMG_SPRITE_ID)
    return;

  pDstBytes = DISP_BUFFER_P;

  // Clip the edges. Modify the source and width as well.
  if (dst_x < 0) {        // bounds check start of x
    trim = (0 - dst_x);
    dst_x = 0;
    src_x += trim;
    src_width -= trim;
    }

  last_x = dst_x + src_width;
  if (last_x > DISPLAY_WIDTH)   // bound check end of x
    last_x = DISPLAY_WIDTH;

  if (dst_y < 0) {        // bound check start of y
    trim  = (0 - dst_y);
    dst_y = 0;
    src_y += trim;  // fix up source as well since we are clipping the start of the loop
    src_height -= trim;
    }

  last_y = dst_y + src_height;
  if (last_y > DISPLAY_HEIGHT)  // bound check end of y
    last_y = DISPLAY_HEIGHT;

  // Convert the 0,0 bottom left origin to the top left 0,0 used by the actual
  // buffer
  last_y = TRANSLATE_Y(last_y);
  dst_y = TRANSLATE_Y(dst_y);

  // The last row is the top most scan line in the LCD Buffer
  // so limit if the copy would copy into memory before the buffer.
  // The first row copied will be the one closest to the bottom of the LCD
  // If that is off screen then limit as well and adjust the start point on the start

  // Copy bits top to top moving down.
  sy = src_y;
  rowbytes = pSprite->RowBytes;

  pSrcByte = pSprite->Bytes + ((pSprite->Rows - 1 - sy) * rowbytes);
  pFirstDstByte =  pDstBytes + ((dst_y >> 3) * DISPLAY_REALWIDTH) + dst_x;
  for (dy = dst_y;  dy > last_y; dy--)
  {
    sx = src_x;
    bit_y = masks[7 - (dy & 0x07)];
    // not_bit_y = ~ bit_y;          //JJR
    pDstByte = pFirstDstByte;
    pLastDstByte = pDstByte + (last_x - dst_x);
    for (; pDstByte < pLastDstByte; pDstByte++)
    {
      //Read source byte:
      //If fill mode is on, pretend the source bitmap is solid:
      if (FillMode==DRAW_SHAPE_FILLED)
        srcByte = 0xff;
      else
        srcByte =  *(pSrcByte + (sx >> 3));                     //JJR
      
      //If invert mode is on, invert the source byte:
      if (InvertMode==DRAW_BITMAP_INVERT) srcByte = ~srcByte;   //JJR

      //Test the pixel in the source byte:
      if ( srcByte & masks[sx & 0x07] )                         //JJR
      {
        //If pixel is set in source image:
        switch (LogicalMode)
        {
          case DRAW_LOGICAL_AND:
            break;
          case DRAW_LOGICAL_XOR:
            *pDstByte ^= bit_y;
            break;
          case DRAW_LOGICAL_OR:
          case DRAW_LOGICAL_COPY:
          default:
            *pDstByte |= bit_y;
            break;
        }
      }
      else
      {
        //If pixel is clear in source image:
        switch (LogicalMode)
        {
          case DRAW_LOGICAL_OR:
          case DRAW_LOGICAL_XOR:
            break;
          case DRAW_LOGICAL_AND:
          case DRAW_LOGICAL_COPY:
          default:
            *pDstByte &= ~bit_y;
            break;
        }
      }
//JJR
      sx ++;
    }
    pSrcByte -= rowbytes;
    sy ++;
    if ((dy & 0x07) == 0) // bump back the scan line start point at rollover
      pFirstDstByte -= DISPLAY_REALWIDTH;
  }

}
I will get the code checked in tonight and upload a new firmware image to the test_releases folder.

John Hansen

Re: TextOut y value

Posted: 11 Feb 2012, 15:37
by schodet
afanofosc wrote:I think it might be possible to speed up the copybits code for drawing RIC sprites.[...]
This should be possible improve this code, but things are much more complicated because bytes are in lines in sprites, but columns on the screen! May be with a lot of scratch registers...

Re: TextOut y value

Posted: 11 Feb 2012, 16:40
by afanofosc
Ah, yes. I see that now. I was getting confused by all the sx and sy, etc.. Thanks for looking at it, anyway. I still need to upload a new image, which I keep forgetting to do.

John Hansen

Re: TextOut y value

Posted: 11 Feb 2012, 16:52
by HaWe
when taking all the efforts for printing buitl-in fonts at any x,y,
what about having also 4-5 different font sizes like in RobotC ?
(there you can print several font sizes of built-in fonts at any x,y)