mpegavc1
Posts: 11
Joined: Thu Jan 24, 2013 12:17 pm

Dispmanx - number of elements issue

Mon Jun 23, 2014 2:22 pm

Hi,

I realized that there is a dispmanx issue related to the number of elements. For screens with too many elements, dispmanx becomes unstable and it begins to erase some elements or to blink the screen for each update.

So, I've edited the /boot/config.txt file, adding "dispmanx_offline=1", and it improves a little bit, but there is still some issues.

Does anyone know how to improve the stability of dispmanx for this case?

Thanks in advance

mimi123
Posts: 583
Joined: Thu Aug 22, 2013 3:32 pm

Re: Dispmanx - number of elements issue

Mon Jun 23, 2014 2:49 pm

There is a start_dispmanx1024.elf somewhere in the GitHub bug tracker for the firmware.
It does work with 256 visible elements.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 24556
Joined: Sat Jul 30, 2011 7:41 pm

Re: Dispmanx - number of elements issue

Mon Jun 23, 2014 2:58 pm

mpegavc1 wrote:Hi,

I realized that there is a dispmanx issue related to the number of elements. For screens with too many elements, dispmanx becomes unstable and it begins to erase some elements or to blink the screen for each update.

So, I've edited the /boot/config.txt file, adding "dispmanx_offline=1", and it improves a little bit, but there is still some issues.

Does anyone know how to improve the stability of dispmanx for this case?

Thanks in advance
How many elements have you got and how big are they?
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
“I own the world’s worst thesaurus. Not only is it awful, it’s awful."

mpegavc1
Posts: 11
Joined: Thu Jan 24, 2013 12:17 pm

Re: Dispmanx - number of elements issue

Mon Jun 23, 2014 3:46 pm

Hi mimi123,

I've searched for start_dispmanx1024.elf and I found some links for it in https://github.com/raspberrypi/firmware/issues/84, but the link is not valid anymore.

Hi jamesh,
Without the dispmanx_offline=1 line in /boot/config.txt, I tried to render 32 rectangles (50x50), but only 27 rectangles appears OK.
Using dispmanx_offline=1 line in /boot/config.txt, all 32 rectangles appears, but sometimes the last 5 rectangles blink.

I wrote a simple test based on hello_dispmanx.c to test this situation:

/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// A simple demo using dispmanx to display an overlay

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>

#include "bcm_host.h"

#define WIDTH 200
#define HEIGHT 200

#define ALIGN_UP(x,y) ((x + (y)-1) & ~((y)-1))

typedef struct
{
DISPMANX_DISPLAY_HANDLE_T display;
DISPMANX_MODEINFO_T info;
void *image;
DISPMANX_UPDATE_HANDLE_T update;
DISPMANX_RESOURCE_HANDLE_T resource;
DISPMANX_ELEMENT_HANDLE_T element;
uint32_t vc_image_ptr;

} RECT_VARS_T;

static RECT_VARS_T gRectVars;

static void FillRect( VC_IMAGE_TYPE_T type, void *image, int pitch, int aligned_height, int x, int y, int w, int h, int val )
{
int row;
int col;

uint16_t *line = (uint16_t *)image + y * (pitch>>1) + x;

for ( row = 0; row < h; row++ )
{
for ( col = 0; col < w; col++ )
{
line[col] = val;
}
line += (pitch>>1);
}
}


void WinCreate(int displayNumber, int display_width, int display_height, int x, int y, int alphaValue)
{
int32_t success = 0;
RECT_VARS_T *vars;
int ret;
int width = display_width, height = display_height;
int pitch = ALIGN_UP(width*2, 32);
VC_IMAGE_TYPE_T type = VC_IMAGE_RGB565;
int aligned_height = ALIGN_UP(height, 16);

vars = &gRectVars;



DISPMANX_ELEMENT_HANDLE_T dispman_element;
DISPMANX_DISPLAY_HANDLE_T dispman_display;
DISPMANX_UPDATE_HANDLE_T dispman_update;
VC_RECT_T dst_rect;
VC_RECT_T src_rect;

dst_rect.x = x;
dst_rect.y = y;
dst_rect.width = display_width;
dst_rect.height = display_height;

src_rect.x = 0;
src_rect.y = 0;
src_rect.width = display_width << 16;
src_rect.height = display_height << 16;

vars->display = vc_dispmanx_display_open( displayNumber /* LCD */);

ret = vc_dispmanx_display_get_info( vars->display, &vars->info);
assert(ret == 0);
printf( "Display is %d x %d\n", vars->info.width, vars->info.height );

vars->image = calloc( 1, pitch * height );
assert(vars->image);

FillRect( type, vars->image, pitch, aligned_height, 0, 0, width, height, 0xFFFF );
FillRect( type, vars->image, pitch, aligned_height, 0, 0, width, height, 0xF800 );
FillRect( type, vars->image, pitch, aligned_height, 20, 20, width - 40, height - 40, 0x07E0 );
FillRect( type, vars->image, pitch, aligned_height, 40, 40, width - 80, height - 80, 0x001F );

vars->resource = vc_dispmanx_resource_create( type,
width,
height,
&vars->vc_image_ptr );
assert( vars->resource );
vc_dispmanx_rect_set( &dst_rect, 0, 0, width, height);
ret = vc_dispmanx_resource_write_data( vars->resource,
type,
pitch,
vars->image,
&dst_rect );
assert( ret == 0 );


vc_dispmanx_rect_set( &src_rect, 0, 0, width << 16, height << 16 );

vc_dispmanx_rect_set( &dst_rect, x/ 2,
y / 2,
width,
height );

vars->update = vc_dispmanx_update_start( displayNumber );

VC_DISPMANX_ALPHA_T alpha;
memset(&alpha, 0x0, sizeof(VC_DISPMANX_ALPHA_T));
alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE| DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
alpha.opacity = alphaValue;

DISPMANX_CLAMP_T clamp;
memset(&clamp, 0x0, sizeof(DISPMANX_CLAMP_T));

vars->element = vc_dispmanx_element_add ( vars->update, vars->display,
displayNumber/*layer*/, &dst_rect, vars->resource/*src*/,
&src_rect, DISPMANX_PROTECTION_NONE, &alpha /*alpha*/, &clamp, 0/*transform*/);


if (!dispman_element)
{
return;
}

vc_dispmanx_update_submit_sync( vars->update );


ret = vc_dispmanx_element_remove( vars->update, vars->element );
assert( ret == 0 );

ret = vc_dispmanx_resource_delete( vars->resource );
assert( ret == 0 );

return;
}

int main(void)
{
uint32_t screen = 0;
int ret;
VC_RECT_T src_rect;
VC_RECT_T dst_rect;
VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,
120, /*alpha 0->255*/
0 };

int step_y=150;
int step_x=150;

bcm_host_init();

WinCreate(0, 50, 50, 0, 0, 255);
WinCreate(1, 50, 50, 0, step_y, 255);
WinCreate(2, 50, 50, 0, 2*step_y, 255);
WinCreate(3, 50, 50, 0, 3*step_y, 255);
WinCreate(4, 50, 50, 0, 4*step_y, 255);
WinCreate(5, 50, 50, 0, 5*step_y, 255);
WinCreate(6, 50, 50, 0, 6*step_y, 255);
WinCreate(7, 50, 50, 0, 7*step_y, 255);

WinCreate(8, 50, 50, step_x, 0, 255);
WinCreate(9, 50, 50, step_x, step_y, 255);
WinCreate(10, 50, 50, step_x, 2*step_y, 255);
WinCreate(11, 50, 50, step_x, 3*step_y, 255);
WinCreate(12, 50, 50, step_x, 4*step_y, 255);
WinCreate(13, 50, 50, step_x, 5*step_y, 255);
WinCreate(14, 50, 50, step_x, 6*step_y, 255);
WinCreate(15, 50, 50, step_x, 7*step_y, 255);

WinCreate(16, 50, 50, 2*step_x, 0, 255);
WinCreate(17, 50, 50, 2*step_x, step_y, 255);
WinCreate(18, 50, 50, 2*step_x, 2*step_y, 255);
WinCreate(19, 50, 50, 2*step_x, 3*step_y, 255);
WinCreate(20, 50, 50, 2*step_x, 4*step_y, 255);
WinCreate(21, 50, 50, 2*step_x, 5*step_y, 255);
WinCreate(22, 50, 50, 2*step_x, 6*step_y, 255);
WinCreate(23, 50, 50, 2*step_x, 7*step_y, 255);

WinCreate(24, 50, 50, 3*step_x, 0, 255);
WinCreate(25, 50, 50, 3*step_x, step_y, 255);

WinCreate(26, 50, 50, 3*step_x, 2*step_y, 255);
//#if 0

WinCreate(27, 50, 50, 3*step_x, 3*step_y, 255);
WinCreate(28, 50, 50, 3*step_x, 4*step_y, 255);
WinCreate(29, 50, 50, 3*step_x, 5*step_y, 255);
WinCreate(30, 50, 50, 3*step_x, 6*step_y, 255);
WinCreate(31, 50, 50, 3*step_x, 7*step_y, 255);
//#endif
getchar();


return 0;
}

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 24556
Joined: Sat Jul 30, 2011 7:41 pm

Re: Dispmanx - number of elements issue

Mon Jun 23, 2014 4:18 pm

You appear to be putting all the objects on the same layer (and you have used displayNumber as the layer which is odd). What happens if you have them each on their own layer?
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
“I own the world’s worst thesaurus. Not only is it awful, it’s awful."

mpegavc1
Posts: 11
Joined: Thu Jan 24, 2013 12:17 pm

Re: Dispmanx - number of elements issue

Tue Jun 24, 2014 3:03 pm

Hi jamesh,

Sorry... I'm not a specialist in dispmanx, but I thought that I was putting all the objects in different layers.
For me, I thought that the displayNumber parameter could be used as the layer number.

But the results are the same for me, using the same layer for all rectangles, or have them each on their own layer.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 24556
Joined: Sat Jul 30, 2011 7:41 pm

Re: Dispmanx - number of elements issue

Tue Jun 24, 2014 4:50 pm

mpegavc1 wrote:Hi jamesh,

Sorry... I'm not a specialist in dispmanx, but I thought that I was putting all the objects in different layers.
For me, I thought that the displayNumber parameter could be used as the layer number.

But the results are the same for me, using the same layer for all rectangles, or have them each on their own layer.
OK, odd. I may have misread the code. The displayNumber is the ID for the display - DSI, HDMI, composite etc.

Should be able to handle more images than that on multiple layers. I'll ping Dom who may know more.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
“I own the world’s worst thesaurus. Not only is it awful, it’s awful."

dom
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5378
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge

Re: Dispmanx - number of elements issue

Tue Jun 24, 2014 5:15 pm

By default dispmanx composites on the fly. i.e. each element is fetched, format converted, scaled and composited as the lines are output to display.

This is efficient (on memory) and gives the best chance of 60fps updates, but there are a number of limits you can run in to. This includes:
HVS memory used for describing the scene
HVS context memory required when vertically resizing elements
SDRAM bandwidth
pixel clock bandwidth (some operations can do 4 pixels per cycle, and some take one pixel per cycle).

It's hard to predict the exact limit is. Too many elements on the same horizontal row makes it worse for the bandwidths. Too many vertical resizes makes it worse for the memory usage.

I would expect somewhere between a few and a dozen full screen layers to work in this mode.

With dispmanx_offline=1 we allocate two offscreen buffers (double buffered) which are used for compositing to.
The compositing may require multiple passes to complete (due to hitting memory/bandwidth limits). This reduces framerate to typically 30fps.

There are also various software limits in the number of elements and updates that can be active. I think this was set to ~128,
although I seem to remember you could only have half as many objects as updates (as an update involves a remove update + an add update).

So dispmanx is not great for using as a sprite engine with lots of elements. (OpenGL ES may be a better choice for that).

It's possible there will be improvements to dispmanx as part of the wayland/weston/maynard work which also want to use dispmanx with reasonable numbers of elements.
However I don't believe it will ever support large numbers of elements.

mpegavc1
Posts: 11
Joined: Thu Jan 24, 2013 12:17 pm

Re: Dispmanx - number of elements issue

Wed Jun 25, 2014 12:57 pm

Thank you very much for your answers, jamesh and dom!

Actually, I'm using OpenGL ES 2.0, but I need to create windows, so I'm using dispmanx backend to do it. But to isolate the problem, I wrote a test using only dispmanx.

There is one question that comes to my mind: I saw the xbmc running in the xbian distribution, and it seems that it have a lot of elements in the screen. How do they do it? Does anyone have an idea about how it is achieved? Because I looked to the xbmc code and the graphics backend is very similar to my implementation.

dom
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5378
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge

Re: Dispmanx - number of elements issue

Wed Jun 25, 2014 2:21 pm

xbmc contains one dispmanx element when in GUi (the 3d surface) and two when playing a video (a video layer plus the 3d surface as an overlay).

The compositing of many GUI elements is done through GL ES (i.e. most GUI elements are stored as textures and rendered as a pair of triangles).

Return to “Graphics programming”