HVS, Hardware Vector Scaler

Anything and everything about programming graphics with Ultibo
Gavinmc42
Posts: 1589
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

HVS, Hardware Vector Scaler

Postby Gavinmc42 » Wed Mar 13, 2019 11:57 am

The VC4 has lots of stuff in it, one is the Hardware Vector Scaler
I noticed the HVS registers when looking at Eric Anholt's VC4 driver source.

Has anyone used the HVS yet in Ultibo? Simple example please pik33.
I was able to shrink my Steampunk OpenVG objects down to icon size with just a scale multiplier in code.
Would the HVS do it quicker?
pik33
Posts: 857
Joined: Fri Sep 30, 2016 6:30 pm
Location: Poland
Contact:

Re: HVS, Hardware Vector Scaler

Postby pik33 » Wed Mar 13, 2019 12:48 pm

As I can understand, OpenVG uses HVS/Dispmanx layer to display its stuff, so using another HVS objects to display OpenVG object can be non-trivial task. However, you can display your own object on top of OpenVG using HVS, and move/resize it as you want in the real time. It can be treated as a sprite which you can resize and move with no heavy CPU load, as moving and resizing is done via HVS.

---------------------------------------

I have to go to my older commits and find the HVS related code as I don't use it now, except for OpenGL stuff.

It is controlled by DispmanX library.

The example below is for a mouse cursor.

You have to make some declarations:

Code: Select all

var
     display:  DISPMANX_DISPLAY_HANDLE_T; 
     mouse_element:DISPMANX_ELEMENT_HANDLE_T;
     mouse_resource: DISPMANX_RESOURCE_HANDLE_T;
     mouse_src_rect,mouse_dst_rect:VC_RECT_T;
     mouse_update:   DISPMANX_UPDATE_HANDLE_T;   
     mouse_layer:integer;
     mouse_alpha:VC_DISPMANX_ALPHA_T;
     mousetype:VC_IMAGE_TYPE_T;
     mousepitch:integer;
     mousealigned_height:integer;
     mousedata:TSprite;        // this is array[0..1023] of cardinal for 32x32 pixel sprite
     


Now init a BCM host and dispmanx display

Code: Select all


bcmhostinit;
display := vc_dispmanx_display_open(0);  // todo: detect lcd



then init a dispmanx element for a mouse cursor

Code: Select all


// init mouse cursor as dispmanx element

   mouse_alpha.flags:=0;    // opaciy from pixels
   mouse_alpha.opacity:=0;  //opaque
   mouse_alpha.mask:=0;
   mousetype:=VC_IMAGE_ARGB8888;
   mousedata:=mysz;         // a bitmap, array [0..1023] of cardinal
   for i:=0 to 1023 do if mousedata[i]<>0 then mousedata[i]:=mousedata[i] or $FF000000;  // clear alpha channel
   image:=@mousedata;
   
   mouse_resource:=vc_dispmanx_resource_create(mousetype, 32, 32, @dummy );
   vc_dispmanx_rect_set(@mouse_dst_rect, 0, 0, 32, 32);
   vc_dispmanx_resource_write_data(mouse_resource,mousetype,128,image,@mouse_dst_rect);
 


Now you have to set parameters and add the element to the list.

Code: Select all

   mouse_update:=vc_dispmanx_update_start(10);
   vc_dispmanx_rect_set( @mouse_src_rect, 0, 0, 32 shl 16, 32 shl 16 );
   vc_dispmanx_rect_set( @mouse_dst_rect, xres div 2, yres div 2, 32,32);
   mouse_element:=vc_dispmanx_element_add(mouse_update,
                                          display,
                                          256, // mouse cursor is on top of all the rest
                                          @mouse_dst_rect,
                                          mouse_resource,
                                          @mouse_src_rect,
                                          DISPMANX_PROTECTION_NONE,
                                          @mouse_alpha,
                                           nil,             // clamp
                                                  0 );
     vc_dispmanx_update_submit_sync(mouse_update);
     
 



After this, you can modify your object. Here is moving the mouse cursor. Pay attention to these ifs: dispmanx objects cannot reach under the screen or you will see something strange:

Code: Select all

mouse_update:=vc_dispmanx_update_start(11);
if mousey>yres-32 then vc_dispmanx_rect_set(@mouse_dst_rect, mousex, mousey, 32, 32-mousey+yres) else vc_dispmanx_rect_set(@mouse_dst_rect, mousex,mousey, 32,32);
if mousey>yres-32 then vc_dispmanx_rect_set(@mouse_src_rect, 0, 0, 32 shl 16, (32-mousey+yres) shl 16 ) else  vc_dispmanx_rect_set(@mouse_src_rect, 0, 0, 32 shl 16, 32 shl 16 );

//change flags: bit 0 layer, bit 1 opacity, bit 2 dest rect, bit 3 src rect, bit 4 mask, bit 5 transform
vc_dispmanx_element_change_attributes(mouse_update, mouse_element, 12, 0,0,@mouse_dst_rect,@mouse_src_rect,0,0);
vc_dispmanx_update_submit(mouse_update,nil,nil); 


Some remarks:

- Dispmanx objects eat the memory bandwidth, avoid big, fullscreen layers. If you use opengl or openvg, you have already two layers used: one for accelerated graphics, one for the framebuffer. 4 fullscreen, fullHD layers and non overclocked RPi3 will stop responding
- You can have up to 26 objects on the screen. Adding 27th causes all of previous objects disappear, including the framebuffer.
- This:

Code: Select all

 vc_dispmanx_update_submit_sync
waits for vbl, this:

Code: Select all

vc_dispmanx_update_submit
doesn't

This is all I can remember now.
Gavinmc42
Posts: 1589
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: HVS, Hardware Vector Scaler

Postby Gavinmc42 » Thu Mar 14, 2019 4:19 am

Thanks pik33, simple must mean something else to you :D
I will try to figure all that out ;)
Just knowing it has been done helps.
pik33
Posts: 857
Joined: Fri Sep 30, 2016 6:30 pm
Location: Poland
Contact:

Re: HVS, Hardware Vector Scaler

Postby pik33 » Thu Mar 14, 2019 9:15 am

There is no simple way to handle this kind of things. You have to put several lines of code to simply initialize all needed things. I don't like this, too

What is good is you have to write your init and modify code only once, wrap it in procedures and then call them

Code: Select all

//pseudocode
init_dispmanx;
add_hvs_ovject(width, height, pixeldata);

and then
// at the start
show_hvs_object;
//in the main loop
move_hvs_object(x,y,scalex,scaley);
// at the end
hide_hvs_object;
close_dispmanx;


As I don't use dispmanx anymore (as it is now) I didn't write those procedures but if I need to return to this, I will write something similar

Return to “Graphics”

Who is online

Users browsing this forum: No registered users and 1 guest