Duplicate events in a single frame in Chrome - css

I'm testing a sub-optimal but really simple CSS animation in Chrome on Mac. In the dev tools, I see that "recalculate style" and subsequent activities are being executed multiple times in a single frame. "Update layer tree" is being called 3 times.
I do not see this behavior in Chrome on Windows. I also do not see equivalent behavior in Firefox.
Here is the simple demo I'm using: http://s.codepen.io/lonekorean/debug/44cf0a50e321de7ec7ff4fac5d3f4514
Why am I seeing these events repeated? It seems very inefficient for Chrome to redo that work in the same frame, so I would like to understand why.
Thanks!

A similar was asked previously on Google Forums, so I've quoted the explanation given below:
The signal that we use for frame boundaries is emitted when the
compositor actually draws layers, and there are plenty of
opportunities for the compositor to bail out before actually drawing,
most common being the update being outside of view-port. So the flow
in your case is likely as this:
you invalidate styles;
the main thread requests a frame from the impl side;
the impl side begins a frame and requests a main thread frame;
the main thread performs style recalc/layout/update layer tree;
it turns out there are no invalidations within the visible area;
frame is not drawn. (the above is repeated several times, then something is actually drawn, and at this point we mark next frame
boundary in Timeline).
Comment by: Andrey Kosyakov
Source: https://groups.google.com/forum/#!topic/google-chrome-developer-tools/JaWHxD6oaXU
From what I understand, invalidating styles is the process of deciding which elements need to have their computed styles recalculated. This is done by storing meta data of the relationships between the elements in the form of Descendant Invalidation Sets.
Update:
I can replicate the same behaviour in on Chrome for Windows as you can see below:
I can't see any reason why the compositor would bail out but I'm not so familiar with the intricate details of this. It's somewhat complicated.

Related

When to emit dataChanged from a QAbstractItemModel

In Qt, I have a model subclassing QAbstractItemModel - it's a tree displayed in a QTreeView.
The model supports various forms of change which all work OK. The two of relevance are:
1) Some data in a small number of related rows changes
2) A visualisation change means that the majority of rows should change their formatting - in particular they have a change of background highlighting. Their DisplayRole data does not change.
The current design deals with both of these in the same way: for every row that has any change the model emits dataChanged(start_of_row_index,end_of_row_index). I emit the signal for both parent rows that change and for any of their children that have changed.
However, this performs badly in case 2 as the model gets big: a very large number of dataChanged signals are emitted.
I have changed the code so that in case 2 the model emits dataChanged only for the (single) row that is the parent of the entire tree.
This still appears to work correctly but does not accord with my understanding of the responsibilities of the model. But I suspect I may be wrong.
Perhaps I am misunderstanding the dataChanged signal? Does it actually cause the view to update all children as well as the specified range? Or can I avoid emitting dataChanged when it is not the DisplayRole that is changing?
Edited with my progress so far
As Jan points out, I ought to emit dataChanged either for most or all of the rows in case 2.
My code originally did this by emitting dataChanged for every changed row but this is too expensive - the view takes too long to process all these signals.
A possible solution could be to aggregate the dataChanged signal for any contiguous blocks of changed rows but this will still not perform well when, for example, every other row has changed - it would still emit too many signals.
Ideally I would like to just tell the view to consider all data as potentially changed (but all indexes still valid - the layout unchanged). This does not seem to be possible with a single signal.
Because of a quirk of the QTreeView class, it is possible (though incorrect according to the spec) to emit only one dataChanged(tl,br) as long as tl != br. I had this working and it passed our testing but left me nervous.
I have settled for now on a version which traverses the tree and emits a single dataChanged(tl,br) for every parent (with tl,br spanning all the children of that parent). This conforms to the model/view protocol and for our models it typically reduces the number of signals by about a factor of 10.
It does not seem ideal however. Any other suggestions anyone?
You are expected to let your views know whenever any data gets changed. This "letting know" can happen through multiple ways; emitting dataChanged is the most common one when the structure of the indexes has not changed; others are the "serious" ones like modelReset or layoutChanged. By a coincidence, some of the Qt's views are able to pick up changes even without dataChanged on e.g. a mouseover, but you aren't supposed to rely on that. It's an implementation detail and a subject to change.
To answer the final bit of your question, yes, dataChanged must be emitted whenever any data returned from the QAIM::data() changes, even if it's "just" some other role than Qt::DisplayRole.
You're citing performance problems. What are the hard numbers -- are you actually getting any measurable slowdown, or are you just prematurely worried that this might be a problem later on? Are you aware of the fact that you can use both arguments to the dataChanged to signal a change over a big matrix of indexes?
EDIT:
A couple more things to try:
Make sure that your view does not request extra data. For example, unless you set the QTreeView's uniformRowHeights (IIRC), the view will have to execute O(n) calls for each dataChanged signal, leading to O(n^2) complexity. That's bad.
If you are really sure that there's no way around this, you might get away by combining the layoutAboutToBeChanged, updatePersistentIndexes and layoutChanged. As you are not actually changing the structure of your indexes, this might be rather cheap. However, the optimization opportunity in the previous point is still worthwhile taking.

Different approaches on getting captured video frames in DirectShow

I was using a callback mechanism to grab the webcam frames in my media application. It worked, but was slow due to certain additional buffer functions that were performed within the callback itself.
Now I am trying the other way to get frames. That is, call a method and grab the frame (instead of callback). I used a sample in CodeProject which makes use of IVMRWindowlessControl9::GetCurrentImage.
I encountered the following issues.
In a Microsoft webcam, the Preview didn't render (only black screen) on Windows 7. But the same camera rendered Preview on XP.
Here my doubt is, will the VMR specific functionalities be dependent on camera drivers on different platforms? Otherwise, how could this difference happen?
Wherever the sample application worked, I observed that the biBitCount member of the resulting BITMAPINFOHEADER structure is 32.
Is this a value set by application or a driver setting for VMR operations? How is this configured?
Finally, which is the best method to grab the webcam frames? A callback approach? Or a Direct approach?
Thanks in advance,
IVMRWindowlessControl9::GetCurrentImage is intended for occasional snapshots, not for regular image grabbing.
Quote from MSDN:
This method can be called at any time, no matter what state the filter
is in, whether running, stopped or paused. However, frequent calls to
this method will degrade video playback performance.
This methods reads back from video memory which is slow in first place. This methods does conversion (that is, slow again) to RGB color space because this format is most suitable for for non-streaming apps and gives less compatibility issues.
All in all, you can use it for periodic image grabbing, however this is not what you are supposed to do. To capture at streaming rate you need you use a filter in the pipeline, or Sample Grabber with callback.

Framerates in Flash/Flex apps

In MXML-based apps, you set the target framerate for the app and I believe this is a core part of Flash as well.
Two questions...
In many games you want the game to run as fast as it can for graphical smoothness, with some upper cap like 50-100Hz. How can you have variable framerates in Flash, or is it really not how things work?
What happens when an app cannot run at the target framerate? Do updates 'stack up' leading to other problems, or does Flash discard them?
I've a simple case where I'm moving a sprite from left to right at 100px/s, at 20fps it looks un-smooth. It's not jerky or anything, but you can clearly see the stepped motion, the artwork is black/white which accentuates it I think. I reckon a higher FPS is needed ideally, but on slower systems it might be too much and I don't want to run into nasty issues where I try to drive it too fast.
If the ActionScript takes too much time and the player can't maintain the frame rate that was specified, the frame rate just drops. There's nothing to stack up, you just get frames generated less often. For this reason when frame rate is important it's critical to make sure the AS code is not taking more time than you have available given the desired frame rate. Also make sure all calculates for movement are based on time and not frames.
As far as animation as 20fps, yeah, it will not look smooth. Bump up the frame rate. :-)
http://www.morearty.com/blog/2006/07/17/flex-tip-a-higher-frame-rate-even-makes-text-entry-look-better/
If Flash is unable to execute at the desired framerate, it will begin dropping frames. You can read the details of this here.
If you are dealing with framerates in Flash a lot, it can be helpful to understand the 'elastic racetrack' model that Flash uses. You can see details about it here, but the basic idea is that the amount of time spend executing code or rendering a frame can vary on a frame by frame basis.

How to get IMediaControl.Run() to start a file playing with no delay

I am attempting to use DirectShow to play two AVI files consecutively (one after the other) so that there is no interruption in the audio or video when the player transitions from one file to the next.
I have two custom controls on my form. Each one is pre-loaded with an AVI file, and before playback begins I set up all the DirectShow interfaces, set the video windows and resize them, call IMediaControl.Run(), then IMediaControl.Pause(), then IMediaSeeking.SetPositions to reset to frame 0, on both controls. On the form, you can see that both files are paused at their initial frames.
I then call IMediaControl.Run() on the first control, and wait for it to complete before calling Run() on the second control. Initially, I hooked into the first video's EC_COMPLETE notification message, and used this to start the second. Thinking that this event might be slow to arrive (turns out it is, but for a weird reason), I tried two other approaches:
Check the first video's current position inside a timer that goes off every second or so (using IMediaPosition.get_CurrentPosition). When the current position is within a second of the video's stop time (known in advance from IMediaPosition.get_StopTime), I go into a tight while loop and wait for the current position to equal the stop time, and then call Run() on the second video.
Same as the first, except I replace the while loop with a call to timeSetEvent from winmm.dll, with a delay set so that it fires right when the first file is supposed to end. I use the callback to Run() the second file.
Either of these two methods substantially cuts down the delay between the end of the first file and the beginning of the second, indicating that the EC_COMPLETE message doesn't arrive immediately after the file is complete (I also tried hooking the EC_SEGMENT_COMPLETE message, which is supposed to be used for looping within a file, but apparently nobody supports this - it never occurs on my machine, at least).
Doing all of the above has cut the transition delay from as much as a second, down to a barely perceptible glitch; about a third of the time the files transition with no interruption at all, which suggests there's no fundamental reason I can't get this to work all the time.
The slight delay is still unacceptable, unfortunately. I assume (and I could easily be wrong) that the remaining delay is due to a slight variable delay between the call to IMediaControl.Run() and when the video actually starts playing.
Does anybody know anything I can do to eliminate this little lag? It would also help to be told this is fundamentally impossible for whatever reason, which wouldn't surprise me. I've never encountered a video player in Windows that doesn't have this problem, so it may not be doable.
More info: the AVI files I'm playing are completely uncompressed (video and audio are uncompressed), so I don't think the lag is due to DirectShow's having to uncompress the video ahead of play start, although it may still buffer ahead as matter of course (and this may be the source of the problem). I would have though that starting play, pausing and then rewinding to the beginning would fix this.
Also, the way I'm handling the transition is to actually have the second control underneath the first; when the first completes playing, I start the second and then call BringToFront on it, creating the appearance of a single video transitioning between the two originals. I don't think the glitch is due to this, because it works perfectly some of the time, and even if this were problematic, it wouldn't explain the matching audio glitch.
Even more: I just tried starting the second video 30-50 milliseconds "early" and that seemed to eliminate even more of the gap, so I'm guessing that the lag in Run() is about that long. It appears to be variable, though, so this is still not where I need it to be.
Still more: perhaps I could eliminate this delay by loading the AVIs from memory rather than from a file. Unfortunately, I have no idea how to do this. IMediaControl only has a RenderFile() method, not something like a RenderStream or RenderMemory method.
If you call IMediaControl::Run on a stopped graph, the graph manager will post the call to a worker thread (so there's some variability). On the worker thread, the graph will be paused. Render filters only complete a pause transition once they have received data, so once GetState() returns S_OK, the graph manager knows that the graph is fully cued. At this point, it picks a time roughly 10ms into the future, and calls Run on each filter with that time as the start point. Since it takes time to tell each filter to Run, the dshow Run method has a parameter which is the refclock time at which a sample timestamped zero should be played -- i.e. the time at which the actual transition to run mode should take place.
To synchronise this with another graph, you first have to ensure that both graphs have the same clock. Query the graph (not the filter) for IMediaFilter, and call GetSyncSource on one graph and SetSyncSource on the other. Then you need to pause the second graph, so that it is cued and ready. When you want to start it, call IMediaFilter::Run instead of IMediaControl::Run, and you can pass your own start time. This still has to be a few milliseconds into the future, so the best thing might be to set the start time of the second graph to be the first graph's start time plus its duration (for an indexed container of uncompressed streams, the duration should be accurate).
Another approach is to use multiple graphs. Separating source from rendering would allow you to switch seamlessly between sources since they feed into a common render graph. There is sample source code for this approach at www.gdcl.co.uk/gmfbridge.
G

Is it a bad idea to implement a timer loop in Flex?

In our game project we did have a timer loop set to fire about 20 times a second (the same as the application framerate). We use this to move some sprites around.
I'm wondering if this could cause problems and we should instead do our updates using an EnterFrame event handler?
I get the impression that having a timer loop run faster than the application framerate is likely to cause problems... is this the case?
As an update, trying to do it on EnterFrame caused very weird problems. Instead of a frame every 75ms, suddenly it jumped to 25ms. Note, it wasn't just our calculation claimed the framerate was different, suddenly the animations sped up to a crazy rate.
I'd go for the Enter frame, in some special cases it can be useful to have two "loops" one for logic and one for the visuals, but for most games I make I stick to the Enter frame-event listener. Having a separate timer for moving your stuff around is a bit unnecessary since having it set to anything except the framerate would make the motion either jerky or just not visible (since the frame is not redrawn).
One thing to consider however is to decouple your logic from the framerate, this is most easily accomplished by using getTimer (available in both as2 and as3) to calculate the time that has expired since the last frame and adjusting the motions or whatever accordingly.
A timer is no more reliable than the enter frame event, flash will try to keep up with whatever rate you've set, but if you're doing heavy processing or complex graphics it will slow down, both timers and framerate.
Here's a rundown of how Flash handles framerates and why you saw your content play faster.
At the deepest level, whatever host application that Flash is running in (the browser usually) polls flash at some interval. That interval might be every 10ms in one browser, or 50ms in another. Every time time that poll occurs, Flash does something like this:
Have (1000/framerate) miliseconds passed since the last frame update?
If no: do nothing and return
If yes: Execute a frame update:
Advance all (playing) timelines one frame
Dispatch all events (including an ENTER_FRAME event
Execute all frame scripts and event handlers with pending events
Draw screen updates
return
However, certain kinds of external events (such as keypresses, mouse events, and timer events) are handled asynchronously to the above process. So if you have an event handler that fires when a key is pressed, the code in that handler might be executed several times between frame updates. The screen will still only be redrawn once per frame update, unless you use the updateAfterEvent() method (global in AS2, attached to events in AS3).
Note that the asynchronous behavior of these events does not affect the timing of frame updates. Even if you use timer events to, for example, redraw the screen 50 times per second, frame animations will still occur at the published framerate, and scripted animations will not execute any faster if they're driven by the enterFrame event (rather than the timer).
The nice thing about using enter frame events, is your processing will degrade at the same pace as the rendering and you'll get a screen update right after the code block finishes.
Either method isn't guaranteed to occur at a specific time interval. So your event handler should be determining how long it's been since it last executed, and making decisions off of that instead of purely how many times it's run.
I think timerEvent and Enter Frame are both good options, I have used both of them in my games. ( Did you mean timerEvent by timer loop? )
PS: notice that in slow machines the timer may not refresh quick enough, so you may need to adjust your code to make game work "faster" in slow machines.
I would suggest using a class such as TweenLite ( http://blog.greensock.com/tweenliteas3/ ) which is lightweight at about 3kb or if you need more power you can use TweenMax, which i believe is 11kb. There are many advantages here. First off, this "engine" has been thoroughly tested and benchmarked and is well known as one of the most resource friendly ways to animate few or even many things. I have seen a benchmark, where in AS3, 1,500 sprites are being animated with TweenLite and it holds a strong 20 fps, as where competitors like Tweener would bog down to 9 fps http://blog.greensock.com/tweening-speed-test/. The next advantage is the ease of use as I will demonstrate below.
//Make sure you have a class path pointed at a folder that contains the following.
import gs.TweenLite;
import gs.easing.*;
var ball_mc:MovieClip = new MovieClip();
var g:Graphics = ball_mc.graphics;
g.beginFill(0xFF0000,1);
g.drawCircle(0,0,10);
g.endFill();
//Now we animate ball_mc
//Example: TweenLite.to(displayObjectName, totalTweeningTime, {someProperty:someValue,anotherProperty:anotherValue,onComplete:aFunctionCalledWhenComplete});
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5});
So this takes ball_mc and moves it to 400 from its current position on the x axis and during that same Tween it reduces or increases the alpha from its current value to 0.5.
After importing the needed class, it is really only 1 line of code to animate each object, which is really nice. We can a also affect the ease, which I believe by default is Expo.easeOut(Strong easeOut). If you wanted it to bounce or be elastic such effects are available just by adding a property to the object as follows.
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5,ease:Bounce.easeOut});
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5,ease:Elastic.easeOut});
The easing all comes from the gs.easing.* import which I believe is Penner's Easing Equations utilized through TweenLite.
In the end we have no polling (Open loops) to manage such as Timer and we have very readable code that can be amended or removed with ease.
It is also important to note that TweenLite and TweenMax offer far more than I have displayed here and it is safe to say that I use one of the two classes in every single project. The animations are custom, they have functionality attached to them (onComplete: functionCall), and again, they are optimal and resource friendly.

Resources