qtscrollqmlqtquick2culling

Culling items that are outside the visible area


From the docs:

The default renderer does not do any CPU-side viewport clipping nor occlusion detection. If something is not supposed to be visible, it should not be shown. Use Item::visible: false for items that should not be drawn. The primary reason for not adding such logic is that it adds additional cost which would also hurt applications that took care in behaving well.

So is there a trick to do it easily, without implementing it myself?

Note that in my case the items that are outside the visible area are there because they are in a ScrollView and they are not scrolled-to.

The reason I want culling is to reduce CPU usage for full-scene redraws.


Solution

  • Here is a trivial example you can extend upon:

    Window {
      visible: true
      width: 640
      height: 480
    
      Rectangle {
        anchors.centerIn: parent
        width: 200
        height: 200
        color: "yellow"
    
        Flickable {
          id: view
          anchors.fill: parent
          contentWidth: 200
          contentHeight: col.height
          property real span : contentY + height
          Column {
            id: col
            x: 90
            spacing: 2
            Repeater {
              model: 50
              delegate: Rectangle {
                width: 10
                height: 10
                color: inView ? "blue" : "red"
                property bool inView: y > view.contentY && y < view.span
              }
            }
          }
        }
      }
    }
    

    Obviously, a full-proof solution would also include the item's height in the calculation. You can also do the check in the x axis if necessary.