I love "C" memcpy(); 387 fps



  • Re: FB_ILI9341 80fps up to 100fps | memcpy(); 387 fps minimal

    UPDATE 16th Aug

    • Compiled C binary which includes "C include file style bmp" files, shows [ 387 fps ] minimal rate. memcpy() used. (Omega2+)
    • Compiled C binary, memcpy() fill_screen one color 1000 times -> [ 432 fps ]
    • Compiled C binary, memcpy() fill_screen 21 color 1000 times -> [ 439 fps ]


  • How do you measure the FPS? Just the time it takes for the memcpy to complete? The way I understand this works is that by writing into the special screen buffer memory, a page fault is generated, which is handled by the kernel / framebuffer driver. The framebuffer driver will periodically push the framebuffer contents to the display using SPI with the interval dictated by the initially given FPS in the command loading the kernel module (insmod /root/modules/fbtft_device.ko custom name="fb_ili9341" busnum=32766 cs=1 speed=96666000 mode=0x06 fps=100 txbuflen=3145728 buswidth=8 bgr=1 gpios=reset:2,dc:3 width=240 height=320 verbose=3 rotate=90 debug=2). I somewhere read that the framebuffer kernel driver can also measure the FPS, maybe we should take those measurements?



  • @Maximilian-Gerhardt yes you are right, the "fps" is limited with the spi bus speed, and that is at max 100, in the memory it works same speed with the cpu's that one is the 387 for 150Kbytes 16bit embedded bmp. It can't be showing but it is there. In the future if there is much faster spi speed then we can use these rates.

    fill screen function, after first line just memcpy()

    void
    	fillScreen ( struct fb_info *fb_info, unsigned int color )
    	{
    		//~ for ( int i=0; i <= fb_info -> screensize; i++ )
    			//~ putPixelDirectToLocation( fb_info, i, color );
    
    		for ( int i=0; i < fb_info -> var.xres; i++ )
    		{
    			putPixel( fb_info, i, 0, color );
    		}
    		
    		for ( int i=1; i < fb_info -> var.yres; i++ )
    		{
    			memcpy( fb_info -> ptr + ( fb_info -> fix.line_length * i ),
    					fb_info -> ptr,
    					( fb_info -> var.xres * ( fb_info -> var.bits_per_pixel / 8 ) ) );
    		}
    
    		/***********/
    		//~ for ( int i = 0; i < fb_info -> var.yres; i++)
    		//~ {
    			//~ drawHorizontalLine ( fb_info, 0, i, (unsigned int)fb_info -> var.xres, color );
    		//~ }
    	}
    

    this is the embedded bmp push code

    	for (int i=0; i<1000; i++)
    	{
    		/* memcpy() bmp show */
    		memcpy( fb_info.ptr, &logo_bmp[0], logo_bmp_len );
    	}
    

    and this is the simple test code

    date nanoseconds enabled from menuconfig "%N" and bc installed

    #!/usr/bin/env sh
    
    count=1000
    first=$(date +"%s.%N")
    echo -e "started\t"$first
    #for i in `seq $count`; do ./fb-test; done;
    ./fb-test
    last=$(date +"%s.%N")
    echo -e "ended\t"$last
    echo $(echo "$count/($last-$first)" | bc)" fps"
    

    0_1534511196640_c07bb612-aa57-4443-b4be-f918e2596e5a-image.png

    Last one the built in debug, i think it has some kind of bug or it is not an optimized code ( ~3000Kb * ~5 = ~15.000 Kb ) i think this is the equation:

    when you use debug=$((1<<5)) it shows, (~ 3000Kb) * ( ~5 )
    or
    echo -e $((1<<5)) > /sys/class/graphics/fb0/debug
    then, for cancle
    echo -e 0 > /sys/class/graphics/fb0/debug

    0_1534511998105_b69ef583-17f7-47ad-8f66-c4c118795c96-image.png


    Extras

    I wrote something similar Adafruit_GFX, it capable of draw lines, draw triangles, draw squares, draw circles, push 16bit bmps ... but the code has a lots of issue, there is a long way to go for stable. When i clean things up I will push the code to gitlab.

    0_1534513367477_4eff00b9-f5e1-4200-8755-dd4aae253c96-image.png

    if you compile modules builtin, below script activates the display in 10 seconds or so when power up the omega2, i am trying to activate with uboot but no luck for now.

    display init script init.d

    #!/bin/sh /etc/rc.common
    
    START=01
    STOP=99
    
    DEFAULT_ROTATION=3
    ROTATE_ANGLE=270
    
    EXTRA_COMMANDS="rotate"
    EXTRA_HELP="
            rotate Change the display direction to one of the [0 1 2 3] values 0:0, 1:90, 2:180, 3:270
    "
    
    start() {
            insmod fbtft_device custom name="fb_ili9341" busnum=32766 cs=1 speed=96666000 mode=3 fps=100 txbuflen=3145728 buswidth=8 bgr=1 gpios=reset:2,dc:3 width=240 height=320 verbose=0 rotate=$ROTATE_ANGLE debug=0
    }
    
    stop() {
            rmmod fbtft_device
    }
    
    rotate() {
            if [ ! -z $1 ]; then
            stop
                    if [ $1 -eq 0 ]; then
                            ROTATE_ANGLE=0
                            echo "$1 0"
                    elif [ $1 -eq 1 ]; then
                            ROTATE_ANGLE=90
                            echo "$1 90"
                    elif [ $1 -eq 2 ]; then
                            ROTATE_ANGLE=180
                            echo "$1 180"
                    elif [ $1 -eq 3 ]; then
                            ROTATE_ANGLE=270
                            echo "$1 270"
                    else
                            ROTATE_ANGLE=270
                            echo "$1 270"
                    fi
            start
            fi
    }
    
    boot() {
            start
    }
    

Log in to reply
 

Looks like your connection to Community was lost, please wait while we try to reconnect.