Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - Double buffering in OpenGL ES: (24 Items)
   
Double buffering in OpenGL ES  
As far as I can understand OpenGL ES 1.0 implementation in QNX supports single buffer output only.

When eglSwapInterval() is set to zero I can observe how framebuffer clear procudure is called via GL ES call glClear();

When I set EGL_SINGLE_BUFFER to EGL_FALSE as attibute to eglChooseConfig() function, eglChooseConfig() returns an error 
and zero count of framebuffer configurations.

If doublebuffering is supported, how to enable it ?
Re: Double buffering in OpenGL ES  
The function gf_3d_target_create, if successfull, always allocates two buffers. The gf_3d_target_t that gets created is 
the native window that you pass to eglCreateWindowSurface. This double-buffering can result in a swap chain if two 
displayable buffers were allocated, or in a presentation blit if the back buffer is not displayable.
Re: Double buffering in OpenGL ES  
Strange, but I can see full buffer clearence while double buffer is on. I'll check my code of buffers creation one more.

Re: Double buffering in OpenGL ES  
It's very difficult to distinguish between a presentation blit and a simple buffer clear going on. Perhaps you can try 
adding some geometry to the scene to see if scene elements build up on you, or if it is just the final blit that you see
 in progress.
Re: Double buffering in OpenGL ES  
> It's very difficult to distinguish between a presentation blit and a simple 
> buffer clear going on. Perhaps you can try adding some geometry to the scene 
> to see if scene elements build up on you, or if it is just the final blit that
>  you see in progress.

I've found two rendered images in my buffers, so OpenGL ES definitely uses two buffers. But when I set eglSwapInterval()
 to zero, I can see buffer clear operation visually. I will post a binary example soon to show the problem.
Re: Double buffering in OpenGL ES  
How to use attached example:

Do not run photon, just run in the plain console.

1) run ./testsprite2 --vsync --renderer opengl_es

eglSwapInterval() is set to 1 in this case. You can see moving 2D sprites (instead of sprites will be the trash, I still
 working on opengl_es 2D renderer) without blinking.

2) run ./testsprite2 --renderer opengl_es

eglSwapInterval() is set to 0 in this case. You can see blinking 2D sprites while double buffering is enabled. While 
using software OpenGL ES renderer, only left-bottom side (why only left-bottom ?) of screen is blinking when sprites are
 moving. While using hardware OpenGL ES renderer (In my case it is devg-extreme2 on 82852GM) all sprites are blinking.

Run photon and run the ./testsprite2 --renderer opengl_es - this how "present copy" works using one buffer only. There 
are no any blinking sprites, all works fine.
Attachment: Text testsprite.tar.gz 192.24 KB
Re: Double buffering in OpenGL ES  
Maybe I'm wrong, but it looks like rendering surface and visible surface in double buffer mode is the same and when 
eglSwapBuffers() switches to new buffer it sets new surface as visible and as rendering target at the same time.
Re: Double buffering in OpenGL ES  
Mike, do you see similar issues using devg-soft3d.so?  I only have access to that renderer at the moment.

-Derek
Re: Double buffering in OpenGL ES  
Yes, this issue could be reproduced on any hardware, including software renderer.
Re: Double buffering in OpenGL ES  
OK, I am getting this:

./testsprite2 --vsync --renderer opengl_es
Couldn't create renderer: GF: Can't create main layer surface

Any ideas?  I can run egl-gears OK ...
Re: Double buffering in OpenGL ES  
> OK, I am getting this:
> ./testsprite2 --vsync --renderer opengl_es
> Couldn't create renderer: GF: Can't create main layer surface
> Any ideas?  I can run egl-gears OK ...

This is similar to my issue with devg-radeon:  http://community.qnx.com/sf/discussion/do/listPosts/projects.graphics/
discussion.advanced_graphics.topc6683 .

Try to change color depth in the photon to 16 or 32 bpp, and then exit from photon to text mode, or manually fix it in 
the display.conf.
Re: Double buffering in OpenGL ES  
OK, I am running in argb8888 ... but I am using vmware ... what are you passing to gf_surface_create_layer()?  I assume 
that is what is failing in this case ...
Re: Double buffering in OpenGL ES  
> OK, I am running in argb8888 ... but I am using vmware ... what are you 
> passing to gf_surface_create_layer()?  I assume that is what is failing in 
> this case ...

Under my VMWare 6.0.0 build-45731 it prints "Couldn't create renderer: unsufficient free video memory". I'm using VMWare
 very rare, so did not tested on it well. As far as I understand the same will be using SVGA driver, since it doesn't 
provide video memory allocation.

At this point, where error is printed, I'm trying to allocate second frame buffer and then to pass both buffers to 
gf_3d_target_create().
Re: Double buffering in OpenGL ES  
What are you passing for the flags value to gf_surface_create_layer()?  This is rather odd ... hmmm ...
Re: Double buffering in OpenGL ES  
The flags are GF_SURFACE_CREATE_2D_ACCESSIBLE |  GF_SURFACE_CREATE_3D_ACCESSIBLE | GF_SURFACE_CREATE_SHAREABLE
Re: Double buffering in OpenGL ES  
> What are you passing for the flags value to gf_surface_create_layer()?  This 
> is rather odd ... hmmm ...

Derek, by the way, with which flags gf_3d_target_create() is creating surfaces for 3D rendering by default if surfaces 
are not passed to this function ?

What gf_3d_target_create() will do if only first surface is allocated and second allocation was failed ?
Re: Double buffering in OpenGL ES  
> OK, I am running in argb8888 ... but I am using vmware ... what are you 
> passing to gf_surface_create_layer()?  I assume that is what is failing in 
> this case ...

This is updated testsprite2 test, but it doesn't work with the devg-vmware or devg-svga. And I doubt that you can see 
flickering under VMWare ...
Attachment: Text testsprite.tar.gz 196.59 KB
Re: Double buffering in OpenGL ES  
ok, I will debug devg-vmware.so ... to see what I can do, because it's the only option I have at the moment ...

-Derek
Re: Double buffering in OpenGL ES  
cpu fast access and 3D accessible, but lets not mix words, here's the source :)

int
gf_3d_target_create(gf_3d_target_t *ptarget, gf_layer_t layer,
    gf_surface_t *surfaces, int nsurfaces,
    int width, int height, gf_format_t format)
{
	struct _gf_3d_target	*target;
	int			arraysize;
	int			rc = GF_ERR_OK;
	gf_dev_t		gdev = layer->display->gdev;

	GF_ASSERT(!gf_dev_islocked(gdev));

	if (surfaces == NULL) {
		nsurfaces = 1;
	}

	arraysize = sizeof(surfaces) * (nsurfaces < 2 ? 2 : nsurfaces);
	target = calloc(1, sizeof(*target) + arraysize);

	if (target == NULL) {
		return GF_ERR_MEM;
	}

	target->surfaces = (void *)(target + 1);

	if (surfaces == NULL) {
		/*
		 * Create drawing surfaces that can both be displayed on
		 * the given layer, and targeted by the 3D engine
		 */
		if ((rc = gf_surface_create_layer(&target->surfaces[0], &layer, 1, 0,
		    width, height, format, NULL,
		    GF_SURFACE_CREATE_3D_ACCESSIBLE)) != GF_ERR_OK) {
			free(target);
			return rc;
		}
		target->internal_alloced[0] = 1;
	} else {
		memcpy(target->surfaces, surfaces, arraysize);
	}

	target->nsurfaces = nsurfaces;

	/* Try to allocate a second surface for double buffering */
	if (nsurfaces < 2) {
		disp_3d_caps_t	caps;
		unsigned	flags = GF_SURFACE_CREATE_3D_ACCESSIBLE;

		if (gdev->rendf.query_caps) {
			gdev->rendf.query_caps(gdev->handle_3d, &caps);
		}
		if (!(caps.flags & DISP_3D_CAP_ACCEL)) {
			flags |= GF_SURFACE_CREATE_CPU_FAST_ACCESS;
		}
		if (gf_surface_create_layer(&target->surfaces[1], &layer, 1, 0,
		    width, height, format, NULL,
		    flags) == GF_ERR_OK) {
			target->nsurfaces++;
			target->internal_alloced[1] = 1;
		} else {
			/*
			 * Cannot allocate two layer-displayable surfaces,
			 * and therefore cannot double-buffer.  Allocate
			 * a non-layer displayable surface, so that the
			 * the OpenGL ES library can blit from the
			 * back-buffer to the displayable buffer instead.
			 */
			if ((rc = gf_surface_create(&target->surfaces[1],
			    gdev, width, height, format, NULL,
			    flags)) != GF_ERR_OK) {
				goto fail;
			}

			target->nsurfaces++;
			target->internal_alloced[1] = 1;
		}
	}

	target->width = width;
	target->height = height;
	target->layer = layer;
	target->swap_layer = swap_layer;

	*ptarget = target;
	return GF_ERR_OK;

fail:
	if (target->internal_alloced[0]) {
		gf_surface_free(target->surfaces[0]);
	}
	free(target);

	return rc;
}
Re: Double buffering in OpenGL ES  
I'll rewrite my code to do all stuff like in the gf_3d_target_create(). Thanks!

Regarding double buffer flickering issue, you will not able to see how it flickers while using vmware driver, according 
to this source :) This must be tested on the real hardware ...
Re: Double buffering in OpenGL ES  
I've added pauses between each triangle rendering and glFlush() after each glDrawArrays() call. When eglSwapInterval() 
is set to 0 and gf_3d_target_create() allocates two surfaces for double buffering, I am able to see how hidden faces are
 rendered first, and then how front faces are rendered. So it is definitely a bug, GLES renders to visible buffer, but 
not to back buffer.
Re: Double buffering in OpenGL ES  
Etienne, could you comment the described issue with eglSwapInterval(0) ?
Re: Double buffering in OpenGL ES  
> I've added pauses between each triangle rendering and glFlush() after each 
> glDrawArrays() call. When eglSwapInterval() is set to 0 and 
> gf_3d_target_create() allocates two surfaces for double buffering, I am able 
> to see how hidden faces are rendered first, and then how front faces are 
> rendered. So it is definitely a bug, GLES renders to visible buffer, but not 
> to back buffer.

With what driver were you seeing this ? Was it on the extreme2, soft3d or with vmware ?

I wouldn't say this is "proof" that GLES rendering is done on the front buffer. It could simply be that the 
implementation of glFinish on this particular driver returns too early, which causes EGL to flip buffers while rendering
 is still going on. In that case, one could still argue that rendering is done on the "front" buffer ; )

I'll look at the sample one more time to rule out the application, then, I would have to get my hands on the same 
hardware to do more investigating.
Re: Double buffering in OpenGL ES  
> > I've added pauses between each triangle rendering and glFlush() after each 
> > glDrawArrays() call. When eglSwapInterval() is set to 0 and 
> > gf_3d_target_create() allocates two surfaces for double buffering, I am able
>  
> > to see how hidden faces are rendered first, and then how front faces are 
> > rendered. So it is definitely a bug, GLES renders to visible buffer, but not
>  
> > to back buffer.
> 
> With what driver were you seeing this ? Was it on the extreme2, soft3d or with
>  vmware ?
> 
> I wouldn't say this is "proof" that GLES rendering is done on the front buffer
> . It could simply be that the implementation of glFinish on this particular 
> driver returns too early, which causes EGL to flip buffers while rendering is 
> still going on. In that case, one could still argue that rendering is done on 
> the "front" buffer ; )
> 
> I'll look at the sample one more time to rule out the application, then, I 
> would have to get my hands on the same hardware to do more investigating.

This sample will work (and will show the problem) on any hardware, excluding vga, svga, flat, vesa and vmware drivers, 
because they are not providing video memory allocation for the second buffer using double buffering.

Could you also comment other issues, which I've found ?