Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - EGL/KD and direct buffer manipulation: (7 Items)
   
EGL/KD and direct buffer manipulation  
First, I apologize if this seems like a bad question to even be asking; however..

In the gf_ world, one could create a surface with gf_surface_create_layer(), get the vaddr using gf_surface_get_info(), 
and copy data directly into the surface (and thereby into the display).  (I realize that may or may not be a good thing,
 but it is possible to do).

At any rate, in the CWM/OpenKODE world I'm not clear on how one would do that.  I have an application that generates 
data that I want to display on the screen at a very fast rate (say 15-30 fps).  Using gf, I can pretty much keep up with
 the display of that data.  Using CWM/OpenKODE, I cannot.  

What I'm doing (for now) is creating a separate gf_surface, memcpying the data into the vaddr, and then when the whole 
surface is filled, doing the 

gf_context_set_surface_3d()
gf_draw_being()
gf_draw_blit2()
gf_draw_end();
eglSwapBuffers()

dance to blit the separate gf_surface onto the opened CWM window.

Is there a better way to accomplish my goal here?

-garyf
Re: EGL/KD and direct buffer manipulation  
The options for software-based rasterizers are typically to render to the window, or to render into an offscreen buffer 
and then make the changes visible using some kind of blit. It seems you are using a variant of the second approach right
 now. It is important to note that unless most of the pixels in a window change every frame, rendering into an offscreen
 buffer first is usually more efficient.

To render directly into a window this is what you can do:

1) Use eglGetConfigs or eglChooseConfig to get an EGL config with an  EGL_SURFACE_TYPE that has both the EGL_WINDOW_BIT 
and the EGL_LOCK_SURFACE_BIT_KHR set. EGL_KHR_lock_surface is the EGL extension that allows you to get a pointer to one 
of an EGLSurface's buffers.

2) Create your window with eglCreateWindowSurface. You don't need an EGLContext since you will be using a software 
rasterizer.

3) In your rendering loop, call eglLockSurfaceKHR followed by eglQuerySurface to get a pointer to the back buffer. 
Unless the EGLSurface is single-buffered, the pointer to use will most likely change each frame because the back buffers
 get swapped. However, on some platforms they won't change even if the window is double-buffered, so the only way to be 
sure is to query for the pointer each iteration.

4) Use the pointer to the current back buffer to do your updates. When you are done you unlock the surface using 
eglUnlockSurfaceKHR. You can follow this by eglSwapBuffers on QNX platforms.

Here are more things to keep in mind.

* The pointer you are getting is most likely to a non-cached memory mapping because many display controllers and/or GPUs
 that might be used to do compositing aren't cache-coherent. This is also a problem for offscreen buffers. However, a 
cache flush or cache invalidate can be inserted at strategic points (e.g., prior to blits) instead of having the display
 controller do it before each refresh.

* To get buffer flipping enabled, you need double-buffered windows. This is enabled by default in EGL. However, this 
means that partial rendering needs to consider changes from two frames ago. You can use EGL_SWAP_BEHAVIOR to ask EGL to 
preserve pixels each time buffers are swapped. In this case, there will be an extra blit for each post, making rendering
 into a double-buffered window no more efficient than rendering into an offscreen buffer.
RE: EGL/KD and direct buffer manipulation  
You can use the EGL_KHR_lock_surface extension to lock your window surface and get a vadder to the render buffer. So if 
you memcpy directly to your window surface, performance should be much better.

You can find an example application which uses the EGL_KHR_lock_surface extension at:

http://community.qnx.com/integration/viewvc/viewvc.cgi/trunk/apps/kd/tutorials/sw-kd-vsync/sw-kd-vsync.c?root=graphics&
system=exsy1001&view=markup

For 6.4.2 we plan to release several improvements to software renders along with updated tutorials which make use of the
 new features. These new features have been found to increase performances significantly.

-Joel

-----Original Message-----
From: Gary Faulkner [mailto:community-noreply@qnx.com] 
Sent: January 15, 2010 8:19 AM
To: cwm-graphics
Subject: EGL/KD and direct buffer manipulation

First, I apologize if this seems like a bad question to even be asking; however..

In the gf_ world, one could create a surface with gf_surface_create_layer(), get the vaddr using gf_surface_get_info(), 
and copy data directly into the surface (and thereby into the display).  (I realize that may or may not be a good thing,
 but it is possible to do).

At any rate, in the CWM/OpenKODE world I'm not clear on how one would do that.  I have an application that generates 
data that I want to display on the screen at a very fast rate (say 15-30 fps).  Using gf, I can pretty much keep up with
 the display of that data.  Using CWM/OpenKODE, I cannot.  

What I'm doing (for now) is creating a separate gf_surface, memcpying the data into the vaddr, and then when the whole 
surface is filled, doing the 

gf_context_set_surface_3d()
gf_draw_being()
gf_draw_blit2()
gf_draw_end();
eglSwapBuffers()

dance to blit the separate gf_surface onto the opened CWM window.

Is there a better way to accomplish my goal here?

-garyf



_______________________________________________

CWM/OpenKODE
http://community.qnx.com/sf/go/post45284
Re: RE: EGL/KD and direct buffer manipulation  
Thanks!  this helps quite a bit.  Now my problem appears to be that io-winmgr wants to eat up a ton of CPU in this case.
  From what I can tell it's all in the eglSwapBuffers (if I don't do this, io-winmgr doesn't chew through cpu, but 
(obviously) I don't get output on the screen.

Seems like eglSwapBuffers is required; is there any way around that?  
Re: RE: EGL/KD and direct buffer manipulation  
It is possible that the composition manager is configured to do compositing instead of flipping buffers on a layer. This
 would mean an extra blit each frame. If for some reason there is no acceleration of blits on your platform, this could 
end up using a lot of CPU, especially if the surface isn't cached.

Look for 'egl-config' directives in the winmgr.conf. The default configuration file is usually:

begin display
  begin plane
    egl-config = auto
  end plane
end display

Which means all windows are composited to one framebuffer. Changing it to

begin display
  begin plane
    wfd-pipeline = 1
  end plane
end display

would enable buffer flipping. You can add a plane for each layer available. The pipeline numbers start at 1 instead 0 
like in GF.
Re: RE: EGL/KD and direct buffer manipulation  
Thanks!

So a few things here..

First, we're on an imx35; blits are accelerated.  

Second, from reading the comments in the default winmgr.conf file, there are some issues with changing from egl-config 
to wfd-pipeline.  Specifically, it would appear (from the comments) that only 1 window will be visible at a time.

That is not what we want/need.  Furthermore, when I do make this switch, my existing CWM/KD programs can no longer find 
a usable configuration.

Re: RE: EGL/KD and direct buffer manipulation  
Actually, let me be more specific.  MOST of the time we need to be able to have more than one window visible at a time. 
 However, when this particular application is displaying (the one doing the direct rendering), we do not need multiple 
windows.

It still seems like the eglSwapBuffers is costing us significant cpu time, and I really wasn't expecting that at all.