Fastest 2D rendering method? (laziness)

Discussion and questions about programming with Ultibo.
NoshBar
Posts: 17
Joined: Thu Mar 23, 2017 8:58 pm
Location: Stockholm
Contact:

Fastest 2D rendering method? (laziness)

Postby NoshBar » Sun Jul 29, 2018 6:17 pm

Hi again.

Excuses:
It's been a while, but I'm going to be changing jobs soon, meaning I'll have a period where I don't have any restrictions on what I do in my free time.
So for now, I'm just thinking about stuff, but can't test what's best.

Question:
If I have a frame buffer from a library, let's say it's ARGB, what would be fastest:
1) just blitting it to the Ultibo FrameBuffer one line at a time with pitch wrap-round
2) setting up OpenGL and changing a texture on a fullscreen quad
3) some sort of fullscreen video functionality I don't know about in e.g., VC4?

I'm _really_ enjoying using Ultibo, and I'm pretty sure I'll finally be able to get an emulator ported over.
Just thank you so much for all your work, it's such a joy to use.
Gavinmc42
Posts: 1367
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Fastest 2D rendering method? (laziness)

Postby Gavinmc42 » Mon Jul 30, 2018 2:42 am

For 2D try OpenVG, it is easier than you think.
Start with the Videocore OpenVG example.
https://github.com/ultibohub/Examples/t ... eIV/OpenVG

A search on the forum will find more info, including a few of my experiments on github.
User avatar
Ultibo
Site Admin
Posts: 1932
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: Fastest 2D rendering method? (laziness)

Postby Ultibo » Mon Jul 30, 2018 10:49 am

NoshBar wrote:Question:
If I have a frame buffer from a library, let's say it's ARGB, what would be fastest:
1) just blitting it to the Ultibo FrameBuffer one line at a time with pitch wrap-round
2) setting up OpenGL and changing a texture on a fullscreen quad
3) some sort of fullscreen video functionality I don't know about in e.g., VC4?

I'm not completely sure if you mean fastest as in performance or fastest as in easiest, either way the obvious answer would be to say that OpenGL or OpenVG should give the best frame rate when rendering scenes etc.

But if you have a library that is able to render pixels into a memory buffer to create the output then it might be that the time required to blit those pixels onto the screen eliminates any gain from the OpenGL/VG acceleration.

A different option that might work well is to use the virtual framebuffer capability that is provided by the Pi and supported by Ultibo so your library renders directly to the screen memory and the result is displayed simply by switching virtual buffers without the need to blit at all.

The Bouncing Boxes example demonstrates the virtual framebuffer functionality, of course you don't need to use it for high frame rate animation you can use it just as a way to keep two buffers and switch between them as required. That example also shows 8 bit color but the technique works with 16, 24 or 32 bit including ARGB etc.

Beyond that the only real answer might be to do some simple tests to work out which method gives the fastest (or best) results.

NoshBar wrote:I'm _really_ enjoying using Ultibo, and I'm pretty sure I'll finally be able to get an emulator ported over.
Just thank you so much for all your work, it's such a joy to use.

Thanks, it's really great to hear. We believe in what we are doing but it does take a lot of work.
Ultibo.org | Make something amazing
https://ultibo.org
pik33
Posts: 710
Joined: Fri Sep 30, 2016 6:30 pm
Location: Poland
Contact:

Re: Fastest 2D rendering method? (laziness)

Postby pik33 » Wed Aug 01, 2018 7:40 am

The fastest method is to pogram a DMA channel to blit the rectangle to the framebuffer area.

The problem and the biggest disadvantage of this metod is the CPU cache: the CPU doesn't know that the DMA channel changed the memory. So you have to cope with the CPU cache integrity which causes the performance to drop.

So in my project I decided to use CPU to blit the pixels, using the assembler to gain the performance. This is near the same speed as with DMA, but much simpler.

Some examples:

- a rectangle in 8 bits per pixel

Code: Select all


//  ---------------------------------------------------------------------
//   box(x,y,l,h,color)
//   asm procedure - draw a filled rectangle, upper left at position (x,y)
//   length l, height h
//   rev. 20170111
//  ---------------------------------------------------------------------


procedure box(x,y,l,h,c:integer);

label p101,p102,p999;

var screenptr:cardinal;
    xr:integer;

begin

screenptr:=displaystart;
xr:=xres;
if x<0 then begin l:=l+x; x:=0; if l<1 then goto p999; end;
if x>=xres then goto p999;
if y<0 then begin h:=h+y; y:=0; if h<1 then goto p999; end;
if y>=yres then goto p999;
if x+l>=xres then l:=xres-x;
if y+h>=yres then h:=yres-y;


             asm
             push {r0-r7}
             ldr r2,y
             ldr r7,xr
             mov r3,r7
             ldr r1,x
             mul r3,r3,r2
             ldr r4,l
             add r3,r1
             ldr r0,screenptr
             add r0,r3
             ldrb r3,c
             ldr r6,h

p102:        mov r5,r4
p101:        strb r3,[r0],#1  // inner loop
             subs r5,#1
             bne p101
             add r0,r7
             sub r0,r4
             subs r6,#1
             bne p102

             pop {r0-r7}
             end;

p999:
end;



- a rectangle blit (also at 8 bits per pixel)

Code: Select all


procedure blit8(from,x,y,too,x2,y2,length,lines,bpl1,bpl2:integer);

// --- rev 21070509

label p101,p999;

begin
if (length<=0) or (lines<=0) then goto p999;

                  asm
                  push {r0-r7}
                  ldr r0,from
                  ldr r1,x
                  add r0,r1
                  ldr r2,y
                  ldr r3,bpl1         //r3=bpl1
                  mul r4,r3,r2
                  add r0,r4           //r0=src start
                  ldr r1,too
                  ldr r2,x2
                  add r1,r2
                  ldr r4,y2
                  ldr r5,bpl2         //r5=bpl2
                  ldr r2,lines        //r2=lines
                  mul r6,r5,r4
                  add r1,r6           //r1=dest start
                  ldr r4,length       //r4=length

                  add r7,r1,r4

p101:             ldrb r6,[r0],#1
                  strb r6,[r1],#1
                  cmps r1,r7
                  blt  p101

                  add r0,r3
                  sub r0,r4
                  add r1,r5
                  mov r7,r1
                  sub r1,r4
                  subs r2,#1
                  bgt p101
                  pop {r0-r7}
                  end;
p999:
end;
 

Return to “General”

Who is online

Users browsing this forum: No registered users and 1 guest