[Interest] Qml Canvas is too slow

Mitch Curtis mitch.curtis at qt.io
Fri Nov 1 09:42:49 CET 2019


There are a few articles online about improving its performance that should also apply to Qt. I just picked the first three I found:

- https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas
- https://www.html5rocks.com/en/tutorials/canvas/performance/ 
- https://stackoverflow.com/questions/8205828/html5-canvas-performance-and-optimization-tips-tricks-and-coding-best-practices

Essentially you should avoid unnecessary rendering.

You could also try rendering to an FBO:

https://doc.qt.io/qt-5/qml-qtquick-canvas.html#renderTarget-prop

I did that with QQuickPaintedItem and got a huge speedup, but I'm not sure if it works the same here.

> -----Original Message-----
> From: Interest <interest-bounces at qt-project.org> On Behalf Of Alexander
> Dyagilev
> Sent: Thursday, 31 October 2019 5:43 PM
> To: interest at qt-project.org
> Subject: [Interest] Qml Canvas is too slow
> 
> Hello,
> 
> The following code is too slow (paint operation takes few seconds):
> 
> Canvas {
> 
>         id: map
>         width: columnsCount * rectangleSize
>         height: rowsCount * rectangleSize
>         anchors.horizontalCenter: alignCenter ? parent.horizontalCenter :
> undefined
>         anchors.left: alignCenter ? undefined : parent.left
>         anchors.bottom: parent.bottom
>         property int offset: 1
> 
>         onPaint: drawMap()
> 
>         function drawMap() {
>             if (columnsCount === 0 || rowsCount === 0) {
>                 return;
>             }
> 
>             var map = downloadProgressMap.map();
>             var ctx = getContext("2d");
> 
>             for (var i = 0; i < map.length; i++) {
>                 var x = (i % columnsCount) * rectangleSize;
>                 var y = (Math.floor(i/columnsCount)) * rectangleSize;
> 
>                 if (map[i]) {
>                     drawFillRect(ctx, x, y);
>                 } else {
>                     drawClearRect(ctx, x, y);
>                 }
>             }
>         }
> 
>         function drawFillRect(ctx, x, y) {
>             ctx.fillStyle = appWindow.theme.progressMapFillBorder
>             ctx.fillRect(x + offset, y + offset, rectangleSize - offset * 2,
> rectangleSize - offset * 2);
>             ctx.fillStyle = appWindow.theme.progressMapFillBackground
>             ctx.fillRect(x + offset + 1, y + offset + 1, rectangleSize - (offset + 1) * 2,
> rectangleSize - (offset + 1) * 2);
>         }
> 
>         function drawClearRect(ctx, x, y) {
>             ctx.fillStyle = appWindow.theme.progressMapClearBorder
>             ctx.fillRect(x + offset, y + offset, rectangleSize - offset * 2,
> rectangleSize - offset * 2);
>             ctx.fillStyle = appWindow.theme.background
>             ctx.fillRect(x + offset + 1, y + offset + 1, rectangleSize - (offset + 1) * 2,
> rectangleSize - (offset + 1) * 2);
>         }
>     }
> 
> Can anything be done to improve its speed, or should we use c++ instead?
> 
> It paints the following:
> 
> 
> 
> Map size: 2323 elements.


More information about the Interest mailing list