I have been thinking a lot about the problem of optimizing animation
playback. I know that some people here are unfamiliar with working with
real animations and have been doing applications instead. Please
consider this aimed at real animations like in movies and games.
While the best solution is to simply make the animation simpler so that
it is easier to render, that is far from an easy, or even possible solution.
Instead the idea is to dynamically adjust the rendering quality. But as
I will explain, it is far from a simple task.
Please excuse any "too easy for me" explanations, I aim for a post that
any developer can read and understand.
As most of you know the Flash player have three main rendering quality
options, low, medium and high quality. There is also the option to go
for best, but that is largely the same as high.
What the rendering quality control mainly controls is the subpixel
rendering. When flash detects that a shape has an edge on a non integer
position it will do subpixel rendering for that pixel.
The subpixel rendering is surprisingly simple, flash just scales up the
area (factor 2 for medium, 4 for high) and renders the new pixels. It
then takes the average value of the pixels and uses that as the value of
the real pixel. Low quality skips subpixel rendering completely.
Now, this does change the rendering cost quite a lot. As such, it is the
stock option for controlling rendering cost in the player.
What some people may not know is that the Flash renderer is smart enough
to skip frames. What this means is that if it detects that it is too far
behind it will simply skip the drawing step and move directly on to the
next frame. This can happen multiple times in a row in severe cases.
This is rather easy to detect. If the drawing skip is skipped, so is the
Event.RENDERED event. Just by checking if there was one between
Event.ENTER_FRAME events it is possible to see if the previous frame was
skipped.
Similarly you can get a good estimate of how long the frame took to draw
by computing the time between the Event.RENDERED event and the
Event.ENTER_FRAME event. It is not perfect since it includes the wait
after the rendering, but that is not a problem in practice.
Now we define the problem. We want to draw the graphics at the highest
possible quality, but without forcing Flash to skip frames. To do this
we have the option of changing the current rendering quality before each
frame is rendered.
In more specific situations we also have the option of changing various
effects, but for easy discussion we will stick to just the rendering
quality.
So the question becomes, what is the condition for changing quality?
A naïve option is to change the quality if the previous frame took too
long to render.
A slightly better option is if we can pre-render each frame and get the
rendering cost on a reference machine. Then we can scale the reference
value to the current machine based on a known reference point, a
previously rendered frame.
However, this approach has the issue of the rendering cost not scaling
linearly between machines. The largest reason is that different machines
might be displaying the animation at different sizes. As rendering in
different sizes can change cost geometrically this makes it hard to
scale properly.
A different idea that I have been thinking about is to use the frameskip
amount as a deciding factor. However, I think that it may lead to
similar results as the rendering time.
Furthermore complicating things is the fact that changing the rendering
quality invalidates the dirty region caching that the player does. While
the effect of this differs depending on the animation being suitable for
the dirty region system, it is a possible cost. There is also the issue
of it being jarring to the user when the quality does change.
The solution to that seems to be hysterics, that we have a threshold
before changing back.
Overall, this is a complicated matter and I am requesting feedback from
people with experience dealing with this issue.
_______________________________________________
Flashcoders mailing list
Flashcoders@chattyfig.figleaf.com
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders