[Scummvm-devel] Issues with kyrandia engine

yotam barnoy yotambarnoy at gmail.com
Mon Jun 7 21:54:37 CEST 2010


On Mon, Jun 7, 2010 at 9:07 PM, Max Horn <max at quendi.de> wrote:
>
> [Could  you please turn off HTML mails? It is very annoying for me to quote your email (I basically had to go to raw mode and copy the content from there), because of the HTML quoting :-(. ]

I try to remember but gmail keeps changing it back :(

> Mathematically what you are doing is equivalent to (non-uniform) sampling :). You "take a sample" when you actually update the screen. You then ignore all data for 1/30th of a second, before "taking the next sample" -- thus, you sample at a non-uniform rate which is bounded above by 30 Hz.

OK I get it. Except that even looking at it that way, I'm sampling a
signal of unknown frequency. There may be elements of the signal (the
calls coming from the engine) that are 30Hz or less, but there could
easily be elements that are higher than 60Hz too (for example the
final call in Kyrandia may be closer to the previous call than 1/60.
And I want even these elements. In fact, if the signal really was
30Hz, I wouldn't need Nyquist frequency -- waiting 1/30th of a second
would do, since my phase would be synchronized with the update calls.
Nyquist is only needed for reproduction of a signal ie. being able to
know the true frequency content of the signal.

>
> Point is: Your current rate throttling logic, which throws away any update requests that come within 1/30th of a second after the last update, is incorrect, given the current OSystem specification. It *cannot* work correctly in general. Indeed, it will only work correctly if the engine requests updates at less than 30 Hz, or at least 60 Hz. Hence it works for e.g. SCI, but not for Kyra.

It fails for Kyra only because the engine goes above 30Hz for the last
update right when the animation ends. Whatever Hz that is, if I knew
it, I could adjust it. But it's possible that it goes over 60Hz too (I
haven't measured). It works for any engine that maintains a consistent
frequency (of any rate) of calls to updateScreen(), or one that waits
1/30 second until stopping the last update, which happens to be all
the other engines, as well as Kyra before the change was made
specifically for the old PSP code.

> I don't think that's quite true anymore -- After all, what is the main thread? It is just one arbitrary thread that you designate so. Let's say the thread doing the graphics is called "main thread". Yet many games have the game logic in a separate thread.... :)

You may be right about that. Truth is I heard about games being
written this way in the late 90s. Thought that was still the case but
I could easily be wrong.

> But this is really totally besides the point: If you say that on your system, the PSP, you cannot handle this via threads or timers due to efficiency reasons, then so it is!
>
> However, I wonder if it is really that slow? Is context switching and mutex locking / semaphore handling really that bad ? As for the code complexity, I am not sure what additional complications you forsee, and am curious to hear them. From my point of view, it looks rather straight forward -- but maybe I am missing something here, in particular since I am not familiar with the PSP, so there may be restrictions that render what I say moot...

It's a complication that's not necessary. I'm looking to optimize
performance right now, and from what I can tell, this will not do so.
Additional complications include for example the fact that many
engines make many many tiny calls to copy rectangles. Each one of
these needs to take and release a mutex. The graphics thread will need
to run at high priority, and will be doing relatively heavy processing
for a high priority thread, which in a cooperative multitasking system
is not wonderful. There's already minimal backend control over what
the middleware/frontend of ScummVM does, and that makes cooperative
multitasking a challenge.

None of this means it's not doable. It may even be that there will be
a performance advantage to freeing the main thread (sorry I'm still
calling it that :) from the rendering work. Right now it seems to me
the cost in context switching and blocking will be greater, but I
could very well be wrong. It's just a whole 'nother layer of
complication. Thread synchronization is a pain. I may give it a try
when I'm done doing other optimizations, but right now I don't want to
get into that mess. I may even be exaggerating it and it'll turn out
to be a piece of cake. From my experience on the PSP though that's
usually not the case.

> So, you are asking for the updateScreen API to be changed to work like this: "updateScreen() gives the backend the chance to perform a screen update. A backend may not do *anything* in response to an updateScreen() call. On the other hand, Engines may, and *must*, invoke updateScreen() as often as possible, ideally at least 60 times per seconds, to ensure smooth screen updates on all target platforms"

Taking a quick peek at the current notes for updateScreen() both in
the code and in the wiki is pretty open to interpretation. In
particular, the wiki even gives the 'sampling' code as an example
(albeit with a warning :)

I guess I agree with you though that it's not necessarily the right
way to go -- the frontend shouldn't worry about the backend -- but the
fact is that that's how the API has been understood so far as far as I
can tell. Are there many backends that use a thread to draw at regular
intervals?
2 factors have been pushing to rely on the calls from the frontend as
far as I can tell: 1. Our games have low frame rates and thus running
at an independent draw rate seems like a waste 2. The frontend is the
one running the main loop. Since historically things have worked this
way, I don't see the crime in telling the frontend that an
updateScreen at too fast of an interval (whatever that interval is
decided to be) may be ignored by the backend, and so it's safest to
send another update call or to wait a little before sending it. That's
really the only change I would want.

Later,
Yotam




More information about the Scummvm-devel mailing list