Page 1 of 1

HVS, Hardware Vector Scaler

Posted: Wed Mar 13, 2019 11:57 am
by Gavinmc42
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?

Re: HVS, Hardware Vector Scaler

Posted: Wed Mar 13, 2019 12:48 pm
by pik33
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

     mouse_resource: DISPMANX_RESOURCE_HANDLE_T;
     mouse_update:   DISPMANX_UPDATE_HANDLE_T;   
     mousedata:TSprite;        // this is array[0..1023] of cardinal for 32x32 pixel sprite

Now init a BCM host and dispmanx display

Code: Select all

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
   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
   mouse_resource:=vc_dispmanx_resource_create(mousetype, 32, 32, @dummy );
   vc_dispmanx_rect_set(@mouse_dst_rect, 0, 0, 32, 32);

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

Code: Select all

   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);
                                          256, // mouse cursor is on top of all the rest
                                           nil,             // clamp
                                                  0 );

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

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);

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

waits for vbl, this:

Code: Select all


This is all I can remember now.

Re: HVS, Hardware Vector Scaler

Posted: Thu Mar 14, 2019 4:19 am
by Gavinmc42
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.

Re: HVS, Hardware Vector Scaler

Posted: Thu Mar 14, 2019 9:15 am
by pik33
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

add_hvs_ovject(width, height, pixeldata);

and then
// at the start
//in the main loop
// at the end

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