Poor offscreen performance

I use offscreens to draw my own lines (anli-aliased), so I have to read
from the offscreen first, then add my pixels and write them back to the
offscreen.

I use it like this:

gOffscreen = PdCreateOffscreenContext(0, 800, 600, Pg_OSC_MEM_PAGE_ALIGN);
main_ptr.ptr8 = (unsigned char *)PdGetOffscreenContextPtr(gOffscreen);

After that, I access main_ptr.ptr8 to read and write to the offscreen.

At the end, I use PgContextBlit/PgFlush to copy the offscreen to the main
screen.

It always seemed to take a lot of time, so I ran a few tests:

To copy the whole offscreen memory (8006002, 16-bit color) it takes:
reading from offscreen : 147ms (6.3 MByte/s)
writing to offscreen : 11ms (85 MByte/s)
(Using memcpy)

So reading from the videocard’s memory is slower than reading from
the harddisk…

I’ve tested it on a machine with the tnt driver and one with the c&t driver.
Same result on both machines.

I guess there is some cache/shared memory in between me and the card. How
can I remove that bottleneck? Has anyone experienced this before??

Oliver
redir@dreer.ch

Oliver <redir@dreer.ch> wrote:

I use offscreens to draw my own lines (anli-aliased), so I have to read
from the offscreen first, then add my pixels and write them back to the
offscreen.

I use it like this:

gOffscreen = PdCreateOffscreenContext(0, 800, 600, Pg_OSC_MEM_PAGE_ALIGN);
main_ptr.ptr8 = (unsigned char *)PdGetOffscreenContextPtr(gOffscreen);

After that, I access main_ptr.ptr8 to read and write to the offscreen.

At the end, I use PgContextBlit/PgFlush to copy the offscreen to the main
screen.

It always seemed to take a lot of time, so I ran a few tests:

To copy the whole offscreen memory (8006002, 16-bit color) it takes:
reading from offscreen : 147ms (6.3 MByte/s)
writing to offscreen : 11ms (85 MByte/s)
(Using memcpy)

So reading from the videocard’s memory is slower than reading from
the harddisk…

I’ve tested it on a machine with the tnt driver and one with the c&t driver.
Same result on both machines.

I guess there is some cache/shared memory in between me and the card. How
can I remove that bottleneck? Has anyone experienced this before??

I have… raw accesses to a frame buffer device are typically an order of
magnitude slower for reads than for writes:

http://www.ussg.iu.edu/hypermail/linux/kernel/0106.0/0269.html

Note that when you’re reading from your hard drive, the disk controller
is using bus mastering, which avoids the latency issues.

You could try getting a pointer directly to onscreen (use
PG_OSC_MAIN_DISPLAY) to avoid copying the entire area, and only touch
the pixels you need to. (I don’t know your application, so this may or
may not be an option for you).

Dave

I have very simillar problem.

I need a fast way to copy from memory to offscreen buffer. I have tried
several approaches and the drawing is always very slow.

I have my own low-level graphic routines and only need Photon to copy
the resulting memory surface to the video card.

I tried PgContextBlitArea with PgGetOffscreenContextPtr for offscreen
context in direct mode. When I copy the memory content with memcpy to
the offscreen buffer, 0.2 seconds is spent just in this one memcpy. The
offscreen buffer has about 768kB (800x480x16bpp). That means a speed of
about 3.75MB/s which is very low. Perhaps it has something to do with
the hardware or the shared memory implementation. Other Photon programs
run fast, with no problems (e.g. you can move a window on the screen
smoothly).

And I also tried PgDrawImage and PgDrawPhImage which is perhaps even
slower, you can see how the screen fills from top to bottom. Most time
is spent in the graphics driver in this case.

Tomas

David Donohoe wrote:

Oliver <> redir@dreer.ch> > wrote:

I use offscreens to draw my own lines (anli-aliased), so I have to read
from the offscreen first, then add my pixels and write them back to the
offscreen.


I use it like this:


gOffscreen = PdCreateOffscreenContext(0, 800, 600, Pg_OSC_MEM_PAGE_ALIGN);
main_ptr.ptr8 = (unsigned char )PdGetOffscreenContextPtr(gOffscreen);


After that, I access main_ptr.ptr8 to read and write to the offscreen.


At the end, I use PgContextBlit/PgFlush to copy the offscreen to the main
screen.


It always seemed to take a lot of time, so I ran a few tests:


To copy the whole offscreen memory (800
600*2, 16-bit color) it takes:
reading from offscreen : 147ms (6.3 MByte/s)
writing to offscreen : 11ms (85 MByte/s)
(Using memcpy)


So reading from the videocard’s memory is slower than reading from
the harddisk…


I’ve tested it on a machine with the tnt driver and one with the c&t driver.
Same result on both machines.


I guess there is some cache/shared memory in between me and the card. How
can I remove that bottleneck? Has anyone experienced this before??


I have… raw accesses to a frame buffer device are typically an order of
magnitude slower for reads than for writes:

http://www.ussg.iu.edu/hypermail/linux/kernel/0106.0/0269.html

Note that when you’re reading from your hard drive, the disk controller
is using bus mastering, which avoids the latency issues.

You could try getting a pointer directly to onscreen (use
PG_OSC_MAIN_DISPLAY) to avoid copying the entire area, and only touch
the pixels you need to. (I don’t know your application, so this may or
may not be an option for you).

Dave

Does anybody knows how can I access directly to graphics driver without
using photon? Some example would be great.

Thanks,

Tomas


Tomas Kolda wrote:

I have very simillar problem.

I need a fast way to copy from memory to offscreen buffer. I have tried
several approaches and the drawing is always very slow.

I have my own low-level graphic routines and only need Photon to copy
the resulting memory surface to the video card.

I tried PgContextBlitArea with PgGetOffscreenContextPtr for offscreen
context in direct mode. When I copy the memory content with memcpy to
the offscreen buffer, 0.2 seconds is spent just in this one memcpy. The
offscreen buffer has about 768kB (800x480x16bpp). That means a speed of
about 3.75MB/s which is very low. Perhaps it has something to do with
the hardware or the shared memory implementation. Other Photon programs
run fast, with no problems (e.g. you can move a window on the screen
smoothly).

And I also tried PgDrawImage and PgDrawPhImage which is perhaps even
slower, you can see how the screen fills from top to bottom. Most time
is spent in the graphics driver in this case.

Tomas

Tomas Kolda wrote:

Does anybody knows how can I access directly to graphics driver without
using photon? Some example would be great.

You can load the driver directly to reduce memory footprint but I’d
guess that won’t help with blitting speed a great deal.

Evan Hillas wrote:

Tomas Kolda wrote:

Does anybody knows how can I access directly to graphics driver
without using photon? Some example would be great.


You can load the driver directly to reduce memory footprint but I’d
guess that won’t help with blitting speed a great deal.

They seem to have disappeared from 6.3.0 but there was a couple of
examples with the 6.2.x graphics DDK.

Eg: /usr/src/ddk-6.2.1/graphics/src/services/graphics/tests/bench

I found a way which is much faster, at least in my case:

I create a memory context using a picture in photon
shared memory:

myImage.type = Pg_IMAGE_DIRECT_555;
myImage.size = myDim; // E.g. the whole screen
myImage.image = PgShmemCreate(w * h * 2, NULL);
myMc = PmMemCreateMC(&myImage, &myDim, &myPoint);

Then I can either draw using Photon:

PmMemStart(myMc);

…photo drawing…

PmMemFlush(myMc, &myImage);
PmMemStop(myMc);
PhDCSetCurrent(NULL);

or I can access the memory directly at address
myImage.image

Finally, I can display the picture using
PgDrawPhImagemx(&location, &myImage, 0);


This helped speed up my application a lot! (I use QNX 6.2.1)

Oliver
redir@dreer.ch


In article <chph6c$o95$1@inn.qnx.com>,
Tomas Kolda <kolda@lss.fd.cvut.cz> wrote:

I have very simillar problem.

I need a fast way to copy from memory to offscreen buffer. I have tried
several approaches and the drawing is always very slow.

I have my own low-level graphic routines and only need Photon to copy
the resulting memory surface to the video card.

I tried PgContextBlitArea with PgGetOffscreenContextPtr for offscreen
context in direct mode. When I copy the memory content with memcpy to
the offscreen buffer, 0.2 seconds is spent just in this one memcpy. The
offscreen buffer has about 768kB (800x480x16bpp). That means a speed of
about 3.75MB/s which is very low. Perhaps it has something to do with
the hardware or the shared memory implementation. Other Photon programs
run fast, with no problems (e.g. you can move a window on the screen
smoothly).