RE: Graphics speed and stability

"Don Woodward" <[email protected]>
Newsgroups gmane.comp.hardware.roku.technical
Message-ID <006301c444e0$08274190$c800a8c0@silverbox>
Ho the list!

Elan, regarding graphics performance, you wrote:
> 1) It seems that the speed of the display is fairly slow in terms of
> writing graphics to the screen and then seeing them update. The good
> news is I don't see any flicker.

The good news is that you don't see any flicker, because by default
in our system, the screen is always double-buffered.  Here's how it works:
When the windowing system decides that the screen needs repainting,
it calls all apps with materialized windows to paint.  Ultimately this
results in your windows' OnPaint() handler getting called and your app,
unbeknownst to it, actually paints to an off-screen buffer.  After
all apps have painted, the window manager flips the buffers (hw page flip/
instant), and then copies the updated region from the front buffer to
the back buffer (hw blit/very fast) to ensure the buffers are consistent.

This is great, particularly because it is automatic.  However, it masks
the leading cause of drawing performance problems: overpaint.  You can
run the attached program to disable automatic double-buffering and you can
watch your app paint its windows.  If you see flashing, then you're
painting more than necessary and you'll be able to improve performance
by optimizing how you paint.  One other interesting thing about the
auto-double-buffering is perceptual - with overpaint,
the user interface takes on a more sluggish feel than it would without
double-buffering.

> The bad news is that I see around a 500ms latency in the display updating.

This is too much.  There are several reasons for the latency.  Aside from
the aforementioned problem of overpainting, here are some other contributing
factors to poor performance:

1.  While the chip has industry leading hardware graphics accelleration, the
driver libraries that came with the chip suffer from two major limitations:
a.  If a client of the driver libraries crashes; the device is left in an indeterminate
state.  This is a leading cause of instability in 3rd party apps that use
libHDMachineX225; more on this later.
b.  The driver libraries aren't designed with resource sharing among multiple
processes in mind. 

The effect of item b on performance is this:
When cascade starts it creates a graphics server thread within the /cascade process.
All calls to the native graphics library are made from this cascade graphics
server thread.  Each cascade app on startup figures out if it can be a native
client of the graphics driver (if the platform graphics driver is multi-process safe)
or if it has to use the graphics server (which is the case for all CascadeApps on the HD1000).
That is why there are two graphics driver libraries:
libCascadeGraphicsDriver_Deschutes.so - which is used by the graphics server,
-and-
libCascadeGraphicsDriver_GFXServer.so - which is used by all cascade apps.

Using the graphics server incurs the overhead of a round-trip wormhole message
for each rendering call.  This overhead is slight for 'expensive' operations
that are called infrequently like FillRect and Blit, but if you implement a screen
grab utility as I have by calling GetPixel() 589,824 times, you'll definitely
notice it.  I can improve performance here - more later.

2.  The font rendering engine we got with the aforementioned driver
library has extremely poor performance.

If you make a lot of font rendering calls, you will experience poor
performance.  Take a look at the WiFi setup screen where it draws an
on-screen keyboard.  Go to the password button and press select.
Then navigate over to the Shift button on the keyboard and press it.
It is taking about 800ms to redraw the keyboard.  This is because of
the poor performance of the provided font rendering support.

My plan is to ditch the provided font rendering implementation
and implement my own.

> a) Is there anything I can do in my app to make it more responsive?

You can do the following:
a.  Send me your painting code and I'll take a look at it and see
if there are things I can suggest.
b.  Turn off double-buffering by running the attached program and
see if your application is painting too much.
c.  Coalesce where possible any font rendering into as few function calls
as possible.  If you render text over a bitmap and the text doesn't change,
consider including the text as part of the bitmap and not rendering text.
d.  Try and minimize the calls you make (e.g. don't implement your own
line-draw using SetPixel()!).

> b) Is this issue likely to be addressed in future versions of the
> software, or is it an inherent characteristic of the underlying
> hardware platform?

As previously mentioned, the underlying hardware platform is fast.
The libraries that control it however, have limitations.
Fortunately, these problems are well understood by me and I have the
following plans:

a.  Implement my own font rendering.
b.  Attemp to rewrite the native graphics driver library so that CascadeApps
    can be native clients instead of going through the graphics server.
c.  Improve performance of the wormhole implementation.
d.  Add clipping support to the windowing system.
e.  Provide direct access to the screen bits.

> 2) In terms of stability, I've had several occasions where 
> the Roku has locked up solid on me, both within my application,
> and other places, such as adjusting the display size to eliminate
> the black borders. I'm wondering if there are known issues and if
> these issues are likely to be fixed in an upcoming release.

There are two leading causes of instability:

a.  Low memory resulting in a lockup.
b.  Third party apps accessing non-robust driver libraries directly.

I'm not sure what you mean by "such as adjusting the display size to eliminate
the black borders."  Are you referring to CinemaSix (formerly MpegPSPlay) or
are you referring to the video placement setup panel?  If you are
referring to CinemaSix, then this is a known issue and Sujal is working
on it.  In fact, as previously alluded to, any 3rd party app that uses
libHDMachineX225 (class MPEGDecoder, class PCMAudioPlayer, class VideoScaler),
must not ever crash or terminate without cleanly shutting down the device,
or the entire system will become unstable.  This is a limitation in the
device libraries that libHDMachineX225 uses.  Because of this limitation,
I was reluctant to release libHDMachineX225 as part of the sdk, but demand
was great so I did.  In the future, I will rectify the problem, most likely
by creating 'server' processes much like the graphics server.  My server
processes will never crash so sdk clients that use them will never be
able to affect stability of the system in this way.  NOTE: mpegd is
such a process.  If you use class CascadeMPEGPlayer instead of class MPEGDecoder,
then you will get the benefit now; unfortunately CascadeMPEGPlayer is currently
only able to play MPEG2 transport streams from files.  That's why I released
MPEGDecoder.

Regarding low memory situations:
This issue is definitely one we are addressing.  Basically Linux is quite
heavy weight and memory consumptive with all of its inbuilt page caching
and such.  Since we don't have a hard disk or swap file, it is very easy
for one process to starve another of memory, even if the process is only
doing seemingly innocuous things like reading files from compact flash
or the network (see comments in CascadeFileStream.h).  When this starving
happens, Linux's kswapd process kicks in and starts thrashing the system.
The system is still operative, just so slow as to be unusable and give
the appearance of a hang.  This is most noticable when playing back
audio or video as those real-time processes basically suck up all available
CPU cycles to do their job, and the user interface cannot update.
For now, the best thing you can do in your application is to only read
(large) files opened with O_DIRECT or O_STREAMING access.
Our plans are to systematically reduce memory usage by components
of our system.  The greatest memory hog is samba.  Each network share
takes up about 700K and consumes memory by filling up page caches
for stuff that it reads (like directories).  As a result, you will
get better memory performance by limiting the amount of your network
shares.

In summary, graphics performance, memory consumption, and stability
when accessing devices will all be improved.  Steps can be taken now
to improve performance and Cascade programmers can rest easy in the
knowledge that software they write now will benefit from future performance
enhancements without modification.

-Don

_______________________________________________
Roku-tech mailing list
[email protected]
http://lists.rokulabs.com/mailman/listinfo/roku-tech
framebuffer.cpp (application/octet-stream, 2.7 KB) - not displayed
Makefile (application/octet-stream, 244 B) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.