Skip to content

Commit

Permalink
Improved graphics performance
Browse files Browse the repository at this point in the history
  • Loading branch information
chregu82 committed Aug 8, 2020
1 parent fd5560f commit b3fd200
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 40 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,20 @@ There's a [example](shapes/anim_dinos.bin) for a moving dinosaur (after first lo

There is no collision detection yet.

## Graphics performance

If you want to do graphics, get a Pi Zero. Multi core Pi's like the models 2 - 4 are much slower if only one core is used like PiGFX does.

Graphics which are drawn on a multiple of 4 pixels x-position draw much faster than on a multiple of 2 or 1. You will also get more speed if your image has a width of a multiple of 4. Drawing solid is faster than drawing transparent.

This is a table that shows the time for drawing a 400x300 pixel image on different x-positions.

|Pi Gen. |Aligned 4 px |Aligned 2 px |unaligned
|------- |------------ |------------ |---------
|1 (zero) |20.8ms |40.4ms |53.0ms
|2 |46.9ms |90.8ms |114.5ms
|3 |50.1ms |93.9ms |122.1ms
|4 |33.4ms |64.9ms |144.4ms

## Compiling on Mac / Linux

Expand Down
Binary file modified bin/kernel.img
Binary file not shown.
Binary file modified bin/kernel7.img
Binary file not shown.
Binary file modified bin/kernel8-32.img
Binary file not shown.
Binary file modified bin/recovery7l.img
Binary file not shown.
2 changes: 1 addition & 1 deletion pigfx_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

#define PIGFX_MAJVERSION 1 /* Major version number */
#define PIGFX_MINVERSION 7 /* Minor version number */
#define PIGFX_BUILDVERSION 1 /* Build version. */
#define PIGFX_BUILDVERSION 2 /* Build version. */

/** Versions:

Expand Down
44 changes: 44 additions & 0 deletions src/c_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,50 @@ void *qmemcpy(void *dest, void *src, size_t n)
return pigfx_memcpy(dest, src, n);
}

void veryfastmemcpy(void *dest, void* src, unsigned int n)
{
//ee_printf("veryfast\n");
if ((((unsigned int)dest & 0x3) == 0) && (((unsigned int)src & 0x3) == 0))
{
// both 4 byte aligned
int single = n & 0x3;
int singpos = n - single;
int quad = singpos / 4;
unsigned int* qdest = dest;
unsigned int* qsrc = src;
unsigned char* sdest = (unsigned char*)dest+singpos;
unsigned char* ssrc = (unsigned char*)src+singpos;
for (int q=0; q<quad; q++)
{
qdest[q] = qsrc[q];
}
for (int s=0; s<single; s++)
{
sdest[s] = ssrc[s];
}
}
else if ((((unsigned int)dest & 0x1) == 0) && (((unsigned int)src & 0x1) == 0))
{
// both 2 byte aligned
int single = n & 0x1;
int singpos = n - single;
int dbl = singpos / 2;
unsigned short int* ddest = dest;
unsigned short int* dsrc = src;
unsigned char* sdest = (unsigned char*)dest + singpos;
unsigned char* ssrc = (unsigned char*)src + singpos;
for (int d=0; d<dbl; d++)
{
ddest[d] = dsrc[d];
}
if (single) *sdest = *ssrc;
}
else
{
pigfx_memcpy(dest, src, n);
}
}

void *pigfx_memcpy (void *pDest, const void *pSrc, size_t nLength)
{
char *pd = (char *) pDest;
Expand Down
1 change: 1 addition & 0 deletions src/c_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ typedef unsigned long size_t;

void *pigfx_memset (void *pBuffer, int nValue, size_t nLength);
void *qmemcpy(void *dest, void *src, size_t n);
void veryfastmemcpy(void *dest, void* src, unsigned int n);
void *pigfx_memcpy (void *pDest, const void *pSrc, size_t nLength);
char *pigfx_strcpy (char *pDest, const char *pSrc);
size_t pigfx_strlen (const char *pString);
Expand Down
63 changes: 24 additions & 39 deletions src/gfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "console.h"
#include "dma.h"
#include "utils.h"
#include "c_utils.h"
#include "timer.h"
#include "nmalloc.h"
#include "ee_printf.h"
Expand Down Expand Up @@ -177,22 +178,11 @@ state_fun state_fun_ignore_digit;
#include "framebuffer.h"

// Global static to store the screen variables.
/*static*/ FRAMEBUFFER_CTX ctx;
FRAMEBUFFER_CTX ctx;

// DMA communication and command buffer
unsigned int __attribute__((aligned(0x100))) mem_buff_dma[16];

// local memset
void local_memset (void *pBuffer, int nValue, unsigned int nLength)
{
char *p = (char *) pBuffer;

while (nLength--)
{
*p++ = (char) nValue;
}
}

// Forward declarations
void gfx_term_render_cursor();
void gfx_term_save_cursor_content();
Expand Down Expand Up @@ -248,7 +238,7 @@ void gfx_compute_font()
ctx.cursor_buffer_ready = 0;
}
ctx.cursor_buffer = (unsigned char*)nmalloc_malloc(ctx.cursor_buffer_size);
local_memset(ctx.cursor_buffer, 0, ctx.cursor_buffer_size);
pigfx_memset(ctx.cursor_buffer, 0, ctx.cursor_buffer_size);

// set logical terminal size
ctx.term.WIDTH = ctx.W / ctx.term.FONTWIDTH;
Expand All @@ -270,7 +260,7 @@ void gfx_set_env( void* p_framebuffer, unsigned int width, unsigned int height,
dma_init();

// Set ctx memory to 0
local_memset(&ctx, 0, sizeof(ctx));
pigfx_memset(&ctx, 0, sizeof(ctx));

// set default font
if (ctx.term.FONT == 0) {
Expand Down Expand Up @@ -366,7 +356,7 @@ void gfx_put_sprite_NORMAL( unsigned char* p_sprite, unsigned int x, unsigned in
unsigned int width = *p_spr_32; p_spr_32++;
unsigned int height = *p_spr_32; p_spr_32++;

unsigned int i,j;
unsigned int i;
unsigned char* pspr = (unsigned char*)p_spr_32;

// limit bitmap size to screen
Expand All @@ -376,12 +366,9 @@ void gfx_put_sprite_NORMAL( unsigned char* p_sprite, unsigned int x, unsigned in

for( i=0; i<height; ++i )
{
for( j=0; j<usedwidth; ++j )
{
*pf++ = *pspr++;
}
pf += ctx.Pitch - usedwidth;
pspr += width - usedwidth;
veryfastmemcpy(pf, pspr, usedwidth);
pf += ctx.Pitch;
pspr += width;
}
}
/** Draw a sprite in normal mode.
Expand Down Expand Up @@ -492,7 +479,7 @@ void gfx_save_background(tSprite* pSprite, unsigned char* pBitmap, unsigned int
*pH = pSprite->height;
// Write pixel data to saved background
unsigned char* pScreen = PFB(x,y);
unsigned int i,j;
unsigned int i/*, j*/;
unsigned char* pSave = pSprite->pBackground+8;
unsigned int height = *pH;
unsigned int width = *pW;
Expand All @@ -504,12 +491,9 @@ void gfx_save_background(tSprite* pSprite, unsigned char* pBitmap, unsigned int

for( i=0; i<height; ++i )
{
for( j=0; j<usedwidth; ++j )
{
*pSave++ = *pScreen++;
}
pScreen += ctx.Pitch - usedwidth;
pSave += width - usedwidth;
veryfastmemcpy(pSave, pScreen, usedwidth);
pScreen += ctx.Pitch;
pSave += width;
}
}

Expand Down Expand Up @@ -537,10 +521,11 @@ void gfx_clear()
dma_execute_queue();
while( DMA_CHAN0_BUSY ); // Busy wait for DMA
#else
unsigned char* pf = ctx.pfb;
unsigned char* pfb_end = pf + ctx.size;
while(pf < pfb_end)
*pf++ = ctx.bg;
unsigned int* pf = (unsigned int*)ctx.pfb;
for (unsigned int i=0; i< ctx.size/4; i++)
{
pf[i] = ctx.bg32;
}
#endif
}

Expand Down Expand Up @@ -802,7 +787,6 @@ void gfx_draw_hor_line(int x0, int y0, unsigned int width)
for (i=0;i<width;i++)
{
*pfb++ = ctx.fg;
//pfb++;
}
}

Expand Down Expand Up @@ -831,12 +815,10 @@ void gfx_draw_filled_circle(unsigned int x0, unsigned int y0, unsigned int rad)
balance += xoff+xoff+1;
xoff++;

//if ((balance += xoff++ + xoff)>= 0)
if (balance>= 0)
{
yoff--;
balance -= yoff+yoff;
//balance-=--yoff+yoff;
}
}
}
Expand Down Expand Up @@ -1141,7 +1123,7 @@ void gfx_term_render_cursor()

/** Fill cursor buffer with the current background and framebuffer with fg.
*/
void gfx_term_render_cursor_newline_dma()
void gfx_term_render_cursor_newline()
{
//
const unsigned int BG = ctx.bg32; // 4 pixels
Expand All @@ -1153,7 +1135,7 @@ void gfx_term_render_cursor_newline_dma()
}

if( ctx.term.cursor_visible )
gfx_fill_rect_dma( ctx.term.cursor_col * ctx.term.FONTWIDTH, ctx.term.cursor_row * ctx.term.FONTHEIGHT, ctx.term.FONTWIDTH, ctx.term.FONTHEIGHT );
gfx_fill_rect( ctx.term.cursor_col * ctx.term.FONTWIDTH, ctx.term.cursor_row * ctx.term.FONTHEIGHT, ctx.term.FONTWIDTH, ctx.term.FONTHEIGHT );
}

// check if loading bitmap
Expand Down Expand Up @@ -1210,8 +1192,9 @@ void gfx_term_putstring( const char* str )
{
while( *str )
{
#if ENABLED(GFX_USE_DMA)
while( DMA_CHAN0_BUSY ); // Busy wait for DMA

#endif
int checkscroll = 1;
switch( *str )
{
Expand Down Expand Up @@ -1273,8 +1256,10 @@ void gfx_term_putstring( const char* str )
--ctx.term.cursor_row;

gfx_scroll_down(ctx.term.FONTHEIGHT);
gfx_term_render_cursor_newline_dma();
gfx_term_render_cursor_newline();
#if ENABLED(GFX_USE_DMA)
dma_execute_queue();
#endif
}

++str;
Expand Down

0 comments on commit b3fd200

Please sign in to comment.