Odd problem with alpha in the frame buffer


17 posts
by RichardUK » Tue Jun 19, 2012 9:33 pm
Seems that we have to have alpha in the frame buffer. I have noticed when this is the case and an alpha less than 1.0f is in the frame buffer the RPi uses it to blend against the tty window. So the effect is that you can see the tty text beneath it.

Image
User avatar
Posts: 130
Joined: Fri Jun 01, 2012 5:12 pm
by jmacey » Wed Jun 20, 2012 11:23 am
I was originally getting this, think it was more to do with not setting / clearing the depth buffer properly.

I now use the following (with or without alpha) and it seems to work ok

Code: Select all
glClearColor(0.2, 0.2,0.2,1.0);
glEnable(GL_DEPTH_TEST);

// then before a draw
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );


I also set this in the config
EGL_DEPTH_SIZE,24
Posts: 135
Joined: Thu May 31, 2012 1:05 pm
by RichardUK » Wed Jun 20, 2012 3:38 pm
I fixed it by masking our alpha writes. Although blending is off for when I render the cubes the cubes will, if I set the shader to write, say, 0.3f to the alpha to the frame buffer. The clear is good, it is only transparent where the cubes have written a less than one value to the frame buffer.
User avatar
Posts: 130
Joined: Fri Jun 01, 2012 5:12 pm
by dattrax » Wed Jun 20, 2012 4:19 pm
You probably want to disallow blending on the layer, rather than remove the alpha channel from it.

dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
0/*layer*/, &dst_rect, 0/*src*/,
&src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

point the 0 /*alpha*/ structure

typedef enum {
/* Bottom 2 bits sets the alpha mode */
DISPMANX_FLAGS_ALPHA_FROM_SOURCE = 0,
DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS = 1,
DISPMANX_FLAGS_ALPHA_FIXED_NON_ZERO = 2,
DISPMANX_FLAGS_ALPHA_FIXED_EXCEED_0X07 = 3,

DISPMANX_FLAGS_ALPHA_PREMULT = 1 << 16,
DISPMANX_FLAGS_ALPHA_MIX = 1 << 17
} DISPMANX_FLAGS_ALPHA_T;

typedef struct {
DISPMANX_FLAGS_ALPHA_T flags;
uint32_t opacity;
DISPMANX_RESOURCE_HANDLE_T mask;
} VC_DISPMANX_ALPHA_T; /* for use with vmcs_host */

I guess

flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE = 0;
opacity = 255;

should fix it

Jim
Posts: 50
Joined: Sat Dec 24, 2011 5:09 pm
by RichardUK » Sat Jun 23, 2012 4:47 pm
Jim, I had to use DISPMANX_FLAGS_ALPHA_FIXED_NON_ZERO to ignore any alpha that maybe in the frame buffer.

Is there any performance issues using glColorMask(EGL_TRUE,EGL_TRUE,EGL_TRUE,EGL_FALSE); instead of the alpha struct?

Is a full screen alpha blend to present the display expensive?
User avatar
Posts: 130
Joined: Fri Jun 01, 2012 5:12 pm
by dattrax » Sun Jun 24, 2012 11:24 pm
Hi,

I didn't have my pi board connected to a tv at the time, so couldnt test what I sent. Glad you got it working. If you set the blending at the composition it shouldn't have any detremental effects. Ideally you need to force the optimization path in the HW which bypasses the DRAM fetch of the underneath layers. I'll check to see if thats what you have done.

color masking will generate additional shader instructions, so you generally dont want to do it if you dont have to.

Jim
Posts: 50
Joined: Sat Dec 24, 2011 5:09 pm
by Blobchaser » Fri Jun 29, 2012 9:10 pm
Jim,

I found that DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS was the best flag to use for my app -- that way I don't need to worry about what is in the alpha of the GL layer.

Steve.
Posts: 1
Joined: Wed Jun 06, 2012 7:10 pm
by RichardUK » Sat Jun 30, 2012 6:25 pm
Ah yes Steve, having read your post I checked mine. Seems mine code worked except for when alpha was == 0. Using yours it's all ok.
User avatar
Posts: 130
Joined: Fri Jun 01, 2012 5:12 pm
by chris_c » Sun Jul 01, 2012 9:35 pm
I've bumped into this problem
I noticed random transparent pixels where textures were pure black with no alpha component....
I fixed it with

VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,255,0 };

dispman_element =
vc_dispmanx_element_add(dispman_update, dispman_display,
0 /*layer */ , &dst_rect, 0 /*src */ ,
&src_rect, DISPMANX_PROTECTION_NONE,
&alpha /*alpha */ , 0 /*clamp */ ,
0 /*transform */ );

but I'm not sure why it works or whats happening in the first place can anyone explain the defines and what the values are doing?

Is there any overhead for doing this?

I need to have alpha objects (text without coloured background) and none alpha objects on the screen
Posts: 108
Joined: Sun May 06, 2012 10:23 am
by dattrax » Sun Jul 01, 2012 10:18 pm
Since you have just or'd 0 with 1, I suspect you aren't getting what you thought.

try

VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,0,0 };

as in the previous post (from blobchaser). Does this fix your alpha issue?

> Is there any overhead for doing this?

Quite the oposite, during our testing it actually increased the framerate. The HW composition can optimize the alpha blend away on the lower console layer so giving more bandwidth to the GPU.

Jim
Posts: 50
Joined: Sat Dec 24, 2011 5:09 pm
by chris_c » Sun Jul 01, 2012 11:36 pm
0,0 caused the gles context to be pure transparent for everything

equally 127,0 made all the gles graphics look 50% transparent

(I have a pure white xwindows fullscreen window underneath, which is only there to catch xlib mouse events...)

so quite why we've had oposite results (if I understood you correctly) who knows...


*edit* just noticed we're using different flags!
any idea what they mean?
Posts: 108
Joined: Sun May 06, 2012 10:23 am
by chris_c » Sun Jul 01, 2012 11:49 pm
VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,255,0 };
works

VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,0,0 };
makes everything transparent

colour me confused!

I'm using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
but disabling GL_BLEND all the time except for when rendering text
Posts: 108
Joined: Sun May 06, 2012 10:23 am
by RichardUK » Tue Jul 03, 2012 8:10 pm
Chris, I found turning of alpha blend did not help. With it off the alpha part is still written to the frame buffer, which I guess is to be expected.

I would like to know what is going on under the hood, if it is a hardware layer then I expect it will not be of much use. But if it is using the GPU to 'present' the new frame to display I would like to take that render over as I could use that quad to also apply some screen space post render effects like glowing textures at the same time.
User avatar
Posts: 130
Joined: Fri Jun 01, 2012 5:12 pm
by chris_c » Tue Jul 03, 2012 10:07 pm
what on earth is so secret about a public API that it can't be documented is beyond me...

Its not like it would vaguely give anyone any hints on how to design their own gpu...

I'm fairly convinced if this interface library was properly documented a SDL accelerated driver could be fairly easily written, this would speed up a large number games - including the python game library which would speed up python games - great for learning.

With this info it would also make a GLES xwindows driver possible (like the openpandora) - rather than directly hitting the hardware - you hit GLES....

I had another poke through the headers but still can't see why what works for me doesn't for you... Maybe because the window under my context is fullscreen and pure white??? (where yours is black? lame idea i know...)

real frustrating.....
Posts: 108
Joined: Sun May 06, 2012 10:23 am
by adam.biltcliffe » Sun Aug 26, 2012 5:51 pm
I don't know whether addressing this at the dispmanx level is better, but if you want to just solve this just using GL then instead of calling:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

use:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE)

This tells GL to blend the RGB channels normally but leave the alpha values on the destination surface exactly as they were (presumably, all fully opaque).
Posts: 5
Joined: Sun Aug 26, 2012 5:36 pm
Location: Cambridge
by dattrax » Mon Aug 27, 2012 8:55 am
Whilst there may be many ways to skin a cat, using blending is not a cost effective way to achieve the correct result.

its going to a instructions to your fragment program.

this is why setting the surface up correctly in dispmanx is a better way to do it.

Cheers
Jim
Posts: 50
Joined: Sat Dec 24, 2011 5:09 pm
by ffelagund » Thu Aug 08, 2013 8:43 am
Moreover, if you are porting something, fix this at dispmanx layer is the best option, so you dont have to touch your rendering source code.

BTW, I'd reciently had this same problem and found the solution here :)
Posts: 30
Joined: Wed Nov 21, 2012 7:53 pm