tetravalence
Posts: 16
Joined: Thu Jul 19, 2012 5:14 pm

EGL display not pixel precise

Fri Aug 31, 2012 7:38 am

Hello,
I am outputting via RCA to a small 320x240 display, running the triangle.c test suite and my own OpenGL project ported to OpenGL ES. In both cases, the display automatically detected and created by EGL to fill the whole screen is 720x480, while manually providing the proper dimensions only draws on the upper-left quarter of the screen. My issue is that this makes for very poor picture quality. Any ideas on what might be causing this?
Thank you in advance!

blu
Posts: 55
Joined: Tue Jul 17, 2012 9:57 pm

Re: EGL display not pixel precise

Fri Aug 31, 2012 12:16 pm

Can you post some code showing how you init the EGL context? Generally, I'm not aware how EGL could automatically pick fb resolutions, but apparently I'm missing something from the picture.

tetravalence
Posts: 16
Joined: Thu Jul 19, 2012 5:14 pm

Re: EGL display not pixel precise

Fri Aug 31, 2012 6:26 pm

Sure, here's the code taken from /opt/vc/src/hello_pi/hello_triangle/triangle.c (I took out some of the members of the state struct used by the demo that aren't involved in this process). graphics_get_display_size appears to be the function in question.

Code: Select all

typedef struct
{
	uint32_t screen_width;
	uint32_t screen_height;
// OpenGL|ES objects
	EGLDisplay display;
	EGLSurface surface;
	EGLContext context;
} STATE_t;

void init_ogl(STATE_t* state)
{
	int32_t success = 0;
	EGLBoolean result;
	EGLint num_config;

	static EGL_DISPMANX_WINDOW_T nativewindow;

	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;

	static const EGLint attribute_list[] =
	{
		EGL_RED_SIZE, 8,
		EGL_GREEN_SIZE, 8,
		EGL_BLUE_SIZE, 8,
		EGL_ALPHA_SIZE, 8,
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
		EGL_NONE
	};
	
	EGLConfig config;

	// get an EGL display connection
	state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
	assert(state->display!=EGL_NO_DISPLAY);

	// initialize the EGL display connection
	result = eglInitialize(state->display, NULL, NULL);
	assert(EGL_FALSE != result);

	// get an appropriate EGL frame buffer configuration
	result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
	assert(EGL_FALSE != result);

	// create an EGL rendering context
	state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL);
	assert(state->context!=EGL_NO_CONTEXT);

	// create an EGL window surface
	success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
	assert( success >= 0 );
	
	dst_rect.x = 0;
	dst_rect.y = 0;
	dst_rect.width = state->screen_width;
	dst_rect.height = state->screen_height;

	src_rect.x = 0;
	src_rect.y = 0;
	src_rect.width = state->screen_width << 16;
	src_rect.height = state->screen_height << 16;		  

	dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
	dispman_update = vc_dispmanx_update_start( 0 );

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

	nativewindow.element = dispman_element;
	nativewindow.width = state->screen_width;
	nativewindow.height = state->screen_height;
	vc_dispmanx_update_submit_sync( dispman_update );

	state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
	assert(state->surface != EGL_NO_SURFACE);

	// connect the context to the surface
	result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
	assert(EGL_FALSE != result);
}

blu
Posts: 55
Joined: Tue Jul 17, 2012 9:57 pm

Re: EGL display not pixel precise

Fri Aug 31, 2012 6:56 pm

Well, that's not EGL picking the res - that's dispmanx, IIRC. So you're saying that 720x480 spans the entire screen, while the actual res of 320x240 - only a quarter? BTW, 720x480 is a standard NTSC res (well, with some overscan), so my guess is that there's some firmware/driver logic somewhere which just goes 'canonical res' whenever it sees analog out. What you can do is the following: keep dst_rect's dimensions as they are (i.e. state->screen_width and state->screen_height), but change your nativeWindow's and src_rect's width and height to your desired res. That way you'll have a fb of the desired res and the overlay hw will do the up-scaling for you.

tetravalence
Posts: 16
Joined: Thu Jul 19, 2012 5:14 pm

Re: EGL display not pixel precise

Fri Aug 31, 2012 7:43 pm

Perfect, that works just how I wanted it to! I really appreciate the help :D
EDIT:
Actually, one more question. If I wanted a cursor, my guess is that I'd have to render it myself, correct? The overlay appears to cover it up.

Return to “OpenGLES”