three.js: performance drop on iPad beginning at 1024 pixels - performance

I have a website using three.js with CanvasRenderer. The renderer's size is set depending on the window size. On an iPad, the size is 1024 x 672 pixels. With this size, I get extremely bad performance (~1 FPS). If I reduce the width to 1023 Pixels, I get about 60 FPS.
Is there any specific reasion why the performance should drop significantly when hitting 1024 pixels? I don't have any issues with this resolution in Firefox.

I have heard about the HTML5 canvas element in some browsers losing a massive amount of performance once a certain number of pixels is being rendered. This would appear to be caching issue with the browser itself. Though the question is still unanswered.
Why does drawImage performance differ greatly with larger than 65776 pixel canvas sources
Render the canvas at a lower resolution and use CSS to scale it up to full HD.

Related

Rasterize QML SVG Image in Alpha8 format

Importing a set of 80 icons in QML as non-visible images to be used for shader sources (for arbitrary colorization):
property Image action: Image { sourceSize.width: 512; sourceSize.height: 512; source: "icons/action.svg"; mipmap: true; antialiasing: true }
// 79 more of those
I discover that my memory consumption has skyrocketed, from 45 mb to 128 mb, a whooping ~185% increase, thats 83 extra mb for the 80 icons.
It was expected, after all, 512 * 512 * 4 / 1024 / 1024 makes up for exactly 1 mb of memory. However, that cost is not acceptable, especially in the face of targeting mobile phones with the app.
I could reduce the rasterization size, however, I want the icons to be nice and crisp. The icon size itself varies according to the device display, but for optimal user experience it needs to be about an inch or so. Given that most new high end phones are already pushing above 500 dpi, I'd really hate to scale the icons down and have them appear blurry.
Since the SVGs are supposed to be colorized in arbitrary colors, they are in effect simply alpha masks, meaning that all I really need is one of those 4 channels. Unfortunately, QML's Image doesn't seem to offer any sort of control, the SVG is rasterized to a RGBA image.
And indeed, if I
QVector<QImage> imgs;
imgs.reserve(80);
QDirIterator it(":/icons", QDirIterator::Subdirectories);
while (it.hasNext()) {
QSvgRenderer renderer (it.next());
QImage ic(512, 512, QImage::Format_Alpha8);
ic.fill(Qt::transparent);
QPainter pp(&ic);
renderer.render(&pp);
imgs.append(ic);
}
I get the expected modest 20 mb increase in memory usage.
Any ideas how to save on some memory?
2 hours later - good news, first and foremost, a custom QQuickImageProvider works out of the box with QImage::Format_Alpha8, no problems there. Unnecessary channels are eliminated.
But more importantly, I realized that the icons lend themselves very well to distance fields representation. So I now employ 128x128 SDF textures, which scale beautifully to far above 512x512, reducing the memory usage for the icons to the measly 1.25 mb, for a total of 64x reduction of ram usage compared to the initial implementation.
The only downside is the 3-4 seconds (on a Note 3 phone) additional startup, because the distance fields are calculated on startup, but there are remedies for this as well, I might switch to pre-computed SDFs or offload if to shaders, which would be a little more complex, but should reduce the time at least 5-fold.
The thing with the Image component is it appears to render the SVG to a bitmap before it is drawn. Hence the requirement to set sourceSize to force it to render your SVG at different resolutions. This force rendering can lead to poor memory usage and poor performance.
As an alternative, I found a number of components in QML that render SVG perfectly via the icon property.
Item {
width: 256
height: 256
Button {
anchors.centerIn: parent
background: Item { }
icon.source: "https://raw.githubusercontent.com/Esri/calcite-ui-icons/master/icons/biking-32.svg"
icon.width: 256
icon.height: 256
icon.color: "blue"
enabled: false
}
}
Which renders my biking-32.svg at 256x256 resolution in blue:

Original size of image - performance relevant in createjs

When loading images via Bitmap() into the stage/container is it relevant regarding the performance once they are loaded and scaled how big the original images were ?
Say I have some images of 800x800 but in the canvas they are only used at a maxiumum size of 400x400. Would it be better to initially onnly make them 400x400?
Yes, the images will become smaller in size, and that is a benefit for your bandwith and performance. Ofcourse the Canvas won't need to scale down the image anymore so the image will be more sharper. Nothing but benefits.

Do we really need separate thumbnail images?

I understand the use of thumbnail in network applications but assuming all the image are in the application itself (photo application), in this case do we still need thumbnail images for performance reasons or is it just fine for the device to resize the actual image on run time?
Since the question is too opinion based I am going to ask more quantitively.
The images are 500x500, about 200-300kb size jpg.
There will be about 200 images.
It is targeted for iphone4 and higher, so that would be the minimum hardware specs users will have.
The maximum memory used should not pass 20% of the devices capacity.
Will the application in this case need separate thumbnail images?
It depends on your application. Just test performance and memory usage on device.
If you show a lot of images and/or they change very quickly (like when you are scrolling UITableView with a lot of images) you will probably have to use thumbnails.
UPDATE:
When image is shown it takes width * height * 3 (width * height * 4 for images with ALPHA channel) bytes of memory. 10 photos 2592 x 1936 stored in memory will require 200Mb of RAM. It is too much. You definitely have to use thumbnails.
Your question is a bit lacking on detail but I assume you're asking if, for say a photo album app, can you just throw around full size UIImages and let a UIImageView resize them to fit on the screen, or do you need to resize?
You absolutely need to resize.
An image taken by an iPhone camera will be several megabytes in compressed file size, more in actual bytes used to represent pixels. The dimensions of the image will be far greater than the screen dimensions of the device. The memory use is very high, particularly if you're thinking of showing multiple "thumbnails". It's not so much a CPU issue (once the image has been rendered it doesn't need re-rendering) but a memory one, and you're severely memory constrained on a mobile device.
Each doubling in size of an image (e.g. from a 100x100 to a 200x200) represents a four-fold increase in the memory needed to hold it.

html5 canvas increase image size

I am looking for a solution to show smaller image in bigger canvas. would like to know if there is a method to increase image size 100% without distorting it in html5 canvas runtime on safari and chrome browsers .
Maybe...
If the image is vector based it would double size with little noticeable distortion.
If the small image is high resolution (eg 300 dpi instead of the webs traditional 72dpi) you can double the size with little noticeable distortion.
Otherwise...
Try just putting the image in an image element and having the browser double the size. Modern browsers use Bicubic interpolation and do a reasonable job of scaling.
Take the image into Photoshop and enlarge it there. Try both Bicubic Smoother and Bicubic Sharper to see which works best for your particular image.
If none of these are workable for you, try "cheating" by just scaling X 2 and then apply a slight blur to hide the distortion. A useful Gausian/Box blur library is Quasimondo's stackblur: http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html

Image sizing in cocos2d

I am playing through an animation of about 90 images # 480x320 each, and I am wondering with the images not being power of 2, will this be a big performance hit? I am programing for as far back as the iphone 3Gs. Also I am using cocs2d.
Assuming you load all of these images at the start and they are 16 bit images.
Well you will have 512x512x90 = 23,592,960 pixels
With 16 bit images thats 377,487,360 bits.
377,487,360 bits = 45 Megabytes of RAM.
So yes that is a big performance hit.
Let's see...
480x320 image will create a texture of 512x512 (next nearest power of two). 512x512 times 32bit color depth (4 bytes) equals 1 Megabyte. 90 times 1 Megabyte equals 90 Megabytes.
Your biggest problem will be allocating this much memory and caching it. Without caching the animation images, you'll have to load each image every time the animation frame changes. Loading 1 Megabyte from flash memory is pretty darn slow, I'm guessing > 100 milliseconds. So every time a frame changes, your app will stop for a fraction of a second. This will be a problem on the 3GS, and possibly the Retina devices as well if you use Retina images (each 960x640 image then requires 4 Megabytes texture memory).
You can only improve this by using PVR compressed images (use TexturePacker). Even halving texture size to 16 bit will probably not be enough for a smooth animation.

Resources