SteveTJS
SteveTJS

Reputation: 705

QML Item visibility and computation

I have a qml file BackgrounPage.qml which is used as a background for all my qml pages in my application.

This background can be a gradient, a solid color or an image.

So I did:

BackgroundPage{

  property bool isGradient: false
  property bool isSolid: true //by default
  property bool isImage: false

  //gradient background
  Rectangle{
    visible: isGradient

    ...//create the rectangle

    LinearGradient{
      ...//create gradient
    }
  }

  //solid background
  Rectangle{
    visible: isSolid

    //create rectangle

    color: ...
  }

  Image{
    visible: isImage
    source: ...
  }
}

It works well but for performance, optimization, I wonder if a non visible item is computed or not by QML. If I create a solid background, I don't want the gradient and the image to be computed.

So my question is: are non visible item computed in QML?

Upvotes: 1

Views: 3191

Answers (1)

derM
derM

Reputation: 13691

What is "computed" for you?

Yes, the objects are created and are "alive" - so if there are any bindings that affect those Items, those will be evaluated.

Whether they will be rendered? No. When they are invisible, the engine prevents them from going to the GPU.

To validate that claim see this example:

ApplicationWindow {
    id: window
    visible: true
    width: 600
    height: 600


    Rectangle {
        width: 100
        height: 100
        color: 'green'

        Timer {
            running: true
            interval: 1000
            repeat: true
            onTriggered: parent.visible = !parent.visible
        }
    }
}

The visiblity of the Rectangle is toggled every second.
If you watch the output generated by setting the envrionment variable:

QSG_DEBUG_RENDERER=render

you will see, that this toggels the amount of rendered nodes between 0 and 1.

Rendering:
 -> Opaque: 0 nodes in 0 batches...
 -> Alpha: 0 nodes in 0 batches...
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/0, render: 0
Renderer::render() QSGAbstractRenderer(0x2341b258) "rebuild: full"
Rendering:
 -> Opaque: 1 nodes in 1 batches...
 -> Alpha: 0 nodes in 0 batches...
 - 0x38589200 [  upload] [noclip] [opaque] [  merged]  Nodes:    1  Vertices:     4  Indices:     6  root: 0x0
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/0, render: 1
Renderer::render() QSGAbstractRenderer(0x2341b258) "rebuild: none"

The better solution however would be to have use a Loader to load the right component:

Loader {
    sourceComponent: (isGradient ? gradientComponent :
                      (isSolid ? solidComponent :
                       (isImage ? imageComponent : null)))
    Component {
        id: gradientComponent
        ...
    }
    ...
}

Upvotes: 2

Related Questions