I'm making a 2d tile level editor (you click a tile on the loaded spritesheet and then can draw it to the main area). Although it performs fine on desktop the mobile performance is staggeringly slow, so I've been testing out various perf tweaks. Monitoring the results with framerate monitor from chrome dev tools (desktop), I noticed something I don't understand. When I click on the menu icon and the overlay menu pops out (visible on the left in the screenshot, uses css transform:translate for the animation) the frame rate skyrockets up to about the monitor refresh sync rate, even when drawing the canvas.
If I haven't touched the menu icon, the framrate is about 40fps on idle and ~15fps when drawing the canvas, but simply triggering the menu animation eliminates the framerate drop. It also seems to have a lasting effect, the idle framerate of 40fps no longer drops on repaints when the menu is closed, and when the menu is open the framerate stays up near 60fps.
So the question is twofold: why does triggering this css animation have such a HUGE effect on canvas drawing perf (15fps vs 60), and is there any way to force a consistent 60fps without having the menu open all the time?
PS* The visibility of the menu is irrelevant, leaving it on the page makes no difference but animating it in seems to affect the framerate greatly. The menu has the 'null transform hack' applied because it was triggering a repaint of the canvas it overlays, but removing only drops the fps a little at each stage of the process, the relative performance of the different states of the program are similar.
Chrome has this thing where upon using a css transformation it enables hardware acceleration.
It would be easy to verify it by moving the menu position with js instead of using css tranformation.
Regarding the second part of the question, if that's the case, a hidden or off-screen transformation should have the same effect.
Related
I'm trying to make a borderless window where the maximized window properly fits the work area of the screen when maximized. This has turned out to be more difficult than I could've ever imagined, and every solution I can find has some sort of downside or glitch that prevents it from being perfect. Some of the glitches are very minor and probably wouldn't be a big deal to most people, but it bothers me.
I know it's possible to do this somehow because I've used a few programs that clearly draw their own non-client area but have proper maximize behavior and appear to be without glitches. Steam and Twitch clients are two examples. However, I have no idea how much code or what sort of tricks they used to get their windows to have that behavior.
Background Info:
When maximizing a window, the window manager positions the window in such a way that the non-client area falls just outside of the visible work area so that the non-client area is not visible when the window is maximized. I remove the non-client area by returning 0 from WM_NCCALCSIZE because I want to be able to draw my own non-client area. The result is that the window manager is trying to account for a non-client area that doesn't exist and my maximized borderless window extends off the screen approximately 7 or 8 pixels in all directions.
What I've tried to fix this:
I've tried handling WM_MINMAXINFO, which doesn't work because the window manager ignores any dimensions passed unless they are smaller than the work area or monitor area. For example, if I subtract 1 from the ptMaxSize.x coordinate, the window fits almost perfectly except there's a 1 pixel transparent space where you can click whatever is behind the window. See this post for more info.
What almost works:
I found this post which contains a solution that almost works perfectly, except that when maximizing the window with Aero Snap, there's a very brief flicker where you can see everything behind the window. This doesn't occur when maximizing the window by double clicking the title bar or using the maximize buttons, even when adjusting the size of the non-client area on maximize. Here's a video that demonstrates the issue.
Video explanation:
First, I maximize the window several times with Aero Snap without the adjustments being made to the non-client area to demonstrate that the maximize transition is flicker-free. Then I show that the window flickers after having adjusted the size of the non-client area on maximizing.
My Question:
Is there a way to prevent the flicker from happening when using this method to fit the maximized borderless window to the work area? Or is there a better way to go about making the maximized window fit the screen? Handling WM_MINMAXINFO seemed like the best hack-free approach, but because of the quirky way windows responds to dimensions that are greater than or equal to the work area, it doesn't seem to work.
I have a very specific issue. I am doing a demo in VR with three.js where I want to display 2D data. The data that will be displayed is dynamic (Text info) and needs to be animated.
Animate CC providing a nice suite of tools is an easy choice for this. With three.js, the way I found to add some 2D animation in the world, was to create a plane, add a texture from a canvas I created, which I update on RAF. No problem as of now.
The canvas I'm rendering is also the one that I create my stage from. Here the issue : Whatever the animation is (even an empty stage) I see a drop in framerate of about 15, as soon as I add the eventlistener on tick for the stage update. I tried many things (like not even adding the mesh, onto which I draw the canvas, to my scene) And If the eventlistener is added, I see my fps take a hit.
Whether the animation is "heavy" or not, I see this drop in framerate. And that drop is a big issue in VR since staying on 60 FPS is pretty much a must have at this point.
Any lead on what I could do to make this better ? Thank you !
When a page contains CSS3 animations that are below the fold, or that get hidden as the user scrolls down, should you apply a class using Javascript to stop the animation, or do browsers not animate invisible elements?
Even though browsers will not draw elements that are outside of the viewport I'm still pretty sure they will continue to update the css properties as determined by the css animation even when the element is not visible.
This is needed in order to be able to listen for animation events, or to be able to read the value of an animated css property at any given time.
So, in theory you might improve performance by removing the css class that animates the element, but unless you have very complex animations or animate hundreds of elements I wouldn't really worry about it.
"Drawing" is the most expensive part usually, especially if you're animating things such as colors, which causes a repaint. However, if you're animating a translation or rotation using a css transform the browser usually doesn't need to do a repaint each frame. Instead it can just paint the element once and send it to the GPU as a texure and let the GPU translate or rotate it each frame, which is crazy fast since it's all hardware accelerated.
I have a OSX Cocoa WebView that is a subview of view in a NSViewController. The view of the NSViewController has been added as a subview to the main window controller's view.
I am attempting to load HTML5 games into the WebView and proportionally scale them so that they fit the WebView with the least empty space possible.
I have a LOT of games I am trying to make this work for with different constraints.
For HTML5 games that were designed to auto-scale to the window, this works perfectly out of the box.
For HTML5 games that were design a fixed size for iPhone, they appear in the upper left of the WebView and take up a very small portion of the window.
For example, many games are 480x360. The window size is 1024x768 (less the title bar).
I've tried various methods for scaling up the content:
How to resize WebView according to its content?
Scale WebView in Cocoa
I've also tried using javascript to scale the content.
These definitely DO work in scaling up the content and I can get good results in filling the screen.
HOWEVER, this does NOT properly scale the position of the mouse events on the WebView canvas. Meaning, no matter how big I scale the WebView clipview which resizes content, the actual area that is clickable with the mouse is still the smaller unscaled area (as if visually things are scaling but functionally things are not).
Is there some way to scale the mouse click event for position? I can see if I click in the lower right area of the smaller bounding box, it has an affect on the larger scaled content as if I clicked the lower right area.
It seems I could add some scaling math somewhere in capturing the mouse click events but I don't understand where this can be done.
Appreciate any help.
Thanks
I have code that paints to a hidden canvas style="visibility: hidden" and then plots this hidden canvas onto one that is visible on screen.
Now as far as I understand, with the hidden canvas drawing should be performant even if it is not triggered via requestAnimationFrame. Is this so? Because I would then only use requestAnimationFrame for the blitting of the hidden canvas on the main screen.
The app I'm working on is not heavily animated but has quite a lot of lines to draw when something changes.
You should create the canvas with document.createElement("canvas") and don't attach this created canvas in any DOM container instead of use a hidden style . (Needs tests to prove, but at least is another way to create a back buffer canvas).
Even so, in my experience I never see effective gains by using backbuffered canvas with requestAnimationFrame. In fact, requestAnimationFrame does their job of synchronize the browser paint with the monitor's refresh rate and this enables smooth animations and more responsive pages. Also the animation will stop if the user switches to another tab which saves CPU usage and battery life of mobile devices.
I would not recommend the use of a back buffer canvas and I suggest, instead, that you perform your drawing stuff directly in main canvas inside a requestAnimationFrame callback. If you continuously keep drawing into the backbuffer canvas and trapped the main canvas into a requestAnimationFrame call you might unnecessarily(or not, that depends on you) lose some frames generating waste of CPU usage and low quality animations.
To help choose the better approach always do your own performance tests for your specific use cases.
And requestAnimationFrame is no needed at all. You are always able to use setInterval or setTimeout but the pros of using requestAnimationFrame are way bigger than his cons what make it the better approach for animations.