Frame buffer off-screen and vertical sync

General discussion about anything related to Ultibo.
mark
Posts: 1325
Joined: Mon Oct 03, 2016 2:12 am
Location: Indianapolis, US

Frame buffer off-screen and vertical sync

Postby mark » Wed Apr 03, 2019 2:06 am

I’m having trouble finding the notes on how to write to a an off-screen frame buffer and then swap it onto the screen. I’m also looking for how to sync with a screen’s vertical sync. Does anyone have links to these things? Thanks, Mark.
User avatar
Ultibo
Site Admin
Posts: 2217
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: Frame buffer off-screen and vertical sync

Postby Ultibo » Wed Apr 03, 2019 10:01 am

mark wrote:I’m having trouble finding the notes on how to write to a an off-screen frame buffer and then swap it onto the screen. I’m also looking for how to sync with a screen’s vertical sync. Does anyone have links to these things? Thanks, Mark.

Hi Mark,

Both the virtual framebuffer and vertical sync are covered in the Bouncing Boxes example.

The primary items of interest would be FramebufferDeviceAllocate, FramebufferDeviceSetOffset and FramebufferDeviceWaitSync, it's also worth noting that while the example uses 8 bit color the virtual frame buffer works with any supported color depth including 8, 16, 24 and 32.
Ultibo.org | Make something amazing
https://ultibo.org
pik33
Posts: 858
Joined: Fri Sep 30, 2016 6:30 pm
Location: Poland
Contact:

Re: Frame buffer off-screen and vertical sync

Postby pik33 » Fri Apr 05, 2019 6:20 am

I use this stuff in the GUI project. In this project I have

- an offscreen 8-bit framebuffer in the CPU memory space
- a dual 32-bit framebuffer in the GPU memory space
- a procedure which converts the 8-bit framebuffer to 32-bit framebuffer every frame and then switches 32-bit framebuffer halves every vblank

Let's go :) The example is copied (and modified/simplified) from https://github.com/pik33/ultibo_retro_g ... malina.pas

Code: Select all

// (...)

begin
// first, wait until Ultibo initializes the framebuffer

repeat fb:=FramebufferDevicegetdefault until fb<>nil;

// then get the native resolution

FramebufferDeviceGetProperties(fb,@FramebufferProperties);
nativex:=FramebufferProperties.PhysicalWidth;
nativey:=FramebufferProperties.PhysicalHeight;

// and destroy the framebuffer as you will need a new one

FramebufferDeviceRelease(fb);

// your new fb may have the native resolution.. or maybe not, so I used another variables for a new fb

 xres:=nativex;
 yres:=nativey;

// now create a new fb. Physical is what you can see on the screen, virtual is the full framebuffer
// warning! max virtual size is 3840x2400


FramebufferProperties.Depth:=32;
FramebufferProperties.PhysicalWidth:=xres;
FramebufferProperties.PhysicalHeight:=yres;
FramebufferProperties.VirtualWidth:=xres;
FramebufferProperties.VirtualHeight:=yres*2;
FramebufferProperties.mode:=0;
FramebufferDeviceAllocate(fb,@FramebufferProperties);

// now wait some time until it initializes

threadsleep(300);

// and get a pointer to your new framebuffer

FramebufferDeviceGetProperties(fb,@FramebufferProperties);
p2:=Pointer(FramebufferProperties.Address);

// now start the frame refreshing thread

thread:=tretro.create(true);
thread.start;

end;



The frame refreshing thread should look like this:

Code: Select all

//(declarations, etc...)

repeat
  begin
 
  draw_your_screen_at_p2;   

  FramebufferDeviceSetOffset(fb,0,0,True);
  FramebufferDeviceWaitSync(fb);

  draw_your_screen_at_(p2+xres*yres);  // p2 is a pointer to cardinal, so you don't have to multiply xres*yres*4
 
  FramebufferDeviceSetOffset(fb,0,yres,True);
  FramebufferDeviceWaitSync(fb);


  end;
until terminated;

Return to “Discussion”

Who is online

Users browsing this forum: No registered users and 0 guests