Optimizing OpenGL canvas with partial updates

Boudewijn Rempt boud at valdyas.org
Sun Feb 14 12:35:06 UTC 2016

On Sun, 14 Feb 2016, Stefano Bonicatti wrote:

> Drawing only a portion of the canvas should be an old tech/improvement and double buffering is an old technique too to
> avoid flickering when repainting.. so.. they should just work.

Yeah, we've used/use both in various places, of course.

> About the artifacts, isn't that because we don't correctly
> calculate the texture update bounds? Because i wouldn't see other cases where that could be an issue.

The artefacts I'm talking about are with the GPU canvas. They happen because we're downscaling rects and then pasting them into the canvas image. That's something we need to take care about, because it's pretty much impossible to avoid when doing scaled-down canvas updates.

> About our current partial updates, we update internally only part of the texture but then we draw it fully to the screen
> (glClear on all and then call our drawImage function, which again doesn't check which parts are changed).
> So also the artifacts are actually because of some bugged code, not because we do partial screen updates (which we don't).

Not in the GPU canvas.

> 2016-02-14 9:15 GMT+01:00 Boudewijn Rempt <boud at valdyas.org>:
>       It's worth a try, but at least in some point of time we already didn't update all of the screen, even in in
>       opengl mode, didn't we? I know we had problems with that on AMD. It also sounds like we might be running into
>       the same problems we have with the GPU canvas, namely small artefacts at the update bounds. If we keep that in
>       mind, it's definitely worth a try, anything that improves performance always is!
>       On Sun, 14 Feb 2016, Dmitry Kazakov wrote:
>             Hi, all!
>             Today I was talking to Maxim (Salabar) and we found quite an interesting idea, which could
>             optimize our openGL rendering pipeline a lot, and would make our dependency on glSync less
>             important (glSync is an extension, and it is not present on some (older) GPUs).
>             The point is that starting with Qt 5, our paintGL() implementation does not draw our canvas
>             directly on screen. Instead it is drawn on an internal Qt's framebuffer, which is (later)
>             painted on screen buffers, which are swapped double buffering. I'm not going to discuss whether
>             such global decision in Qt is good or bad, but for us it means that now we can use
>             partial updates, which (starting with Qt5.5) can be activated with a special call
>             QOpenGLWidget::setUpdateBehavior(). What does it mean? It means that we shouldn't repaint the
>             whole
>             canvas every time and we need *not* spend quite a lot of time in our High Quality scaling shader,
>             which is really slow. Instead, we can update only a portion of the screen, spend a
>             little time on shading this small portion and store in this internal Qt's buffer. Of course in
>             some special cases glSync will still be needed, but I bet that in 90% of the use cases
>             such partial updates will execute really fast!
>             What do you think about this idea? 
>             --
>             Dmitry Kazakov
> --
> Boudewijn Rempt | http://www.krita.org, http://www.valdyas.org
> _______________________________________________
> Krita mailing list
> kimageshop at kde.org
> https://mail.kde.org/mailman/listinfo/kimageshop

Boudewijn Rempt | http://www.krita.org, http://www.valdyas.org

More information about the kimageshop mailing list