Aller au contenu
Tous les transcripts
Podcast / conversationQt Group· 25 avril 2013 98 minAutoproduitDivertissementNumérique

Qt DevDays 2010 - Qt GraphicsView in Depth: Alexis Menard

Source d'origine 2 locuteurs

Transcription Whisper (large-v3), avec identification des locuteurs. À recouper avec la source d'origine.

Analyse automatique

Générée par IA — peut contenir des erreurs. Méthodologie

Chapitres

Répartition du ton (temps de parole politique)

Propositif 100 %

Affirmations vérifiables (citations exactes)

  • 19:18PrésentateurFait
    « Graphics view has a cache mode built-in inside. »
  • 36:09PrésentateurFait
    « when you call set pose many times then it's actually fluid because we don't need to update the BSP so it's only when the items become static that we re-add it into the BSP »
  • 36:24PrésentateurFait
    « the problem with that of course is if you call set pose or you animate thousands of items at the same time because then we got all those timers going on and then a big list of temporary items that are moving »
  • 37:07PrésentateurFait
    « it's basically it depends of the scene but you can try it as well it's a one line code change but BSP is usually more for static contents right »
  • 40:15PrésentateurFait
    « the only difference with that diagram is basically that when we asked the index the items for a given area it was returning everything not necessarily top levels »
  • 40:36PrésentateurFait
    « when you run out from the parents and then you do the subtree right as I was explaining let's say the parent has a transformation let's say 45 degree rotation »
  • 41:56PrésentateurFait
    « if you have an opacity of 0.5 on the parents and then the children will also have the opacity of 0.5 right »
  • 42:18PrésentateurFait
    « we tried to cache everything so cache the opacity cache the transformation and so on but that was a bad idea »
  • 43:22PrésentateurFait
    « versus now the recursive approach the fact that it is recursive and then each time we paint a child we actually give the painter like it is we actually save those calculations so rendering by sub trees make it very efficient »
  • 46:09PrésentateurFait
    « graphics item has two cache modes it's a bit like the background I was explaining before »
  • 46:22PrésentateurFait
    « it's basically like if you have a camera and then you take a picture of the item like it is on the screen and then you save that picture for the next time you are under a frame for instance »
  • 47:03PrésentateurFait
    « to make it clear I did a small diagram here on the left item coordinate cache take a screenshot like it is if the item was rotated then I take the screenshot and rotate the screenshot »
  • 47:30PrésentateurFait
    « when there is a cache set on the item we don't use the painter that we had from graphics view and then graphics scene we actually open a new one on the pixel map »
  • 48:00PrésentateurFait
    « since 4.6 there is a new API for qpxmap cache that I've implemented is because qpxmap cache the way it works is like you say here is a key here is a pixel map »
  • 48:46PrésentateurFait
    « what I did instead is like I've implemented an extension to the pixel cache that I recommend to use and to port your old cube pixel cache with string base key to the new API »
  • 52:53PrésentateurFait
    « item set coordinate set cache mode right and then queue graphics item »
  • 56:25PrésentateurFait
    « let's say I activate the item coordinate cache on it so if you remember correctly what I said we take a screenshot untransformed and then we apply the transformations on the pixel map »

Temps de parole

  • Présentateur88 %
  • ?9 %

≈ 62,1 interruptions / 10 min (chevauchements et interjections détectés).

Modèle mistral-small-latest · prompt v1 · les citations sont vérifiées mot pour mot dans le transcript ; le taux de réponse directe est calculé à partir des verdicts question par question. Aucun label idéologique n'est produit.

0:04
Locuteur

So,

0:05
Présentateur

the doors are closed, so I guess we can start. Welcome, everyone. I'm a bit impressed. A lot of people, big stage. I feel like a superstar, but I'm not. But at the end, I do give for free business cards. So, today's talk is about QGraphicsView in-depth. So, I assume people here have already used a bit of graphics view, because I use a bit of technical words, and I assume people already somehow played with the framework.

0:33
Locuteur

The

0:34
Présentateur

agenda for today, a bit of an introduction. History, and I will introduce graphics view architecture, basic, and then goes inside details for the view, and details for the scene, for the items.

0:49
Locuteur

Also,

0:49
Présentateur

the lessons we learn while developing this framework and the future of it, and I will conclude.

0:56
Locuteur

About

0:57
Présentateur

me, I'm French. You'll probably notice to my accent. I'm sorry. There's nothing I can do. I'm a Qt developer since 2008. I'm based in Oslo. Since the very first days I joined the company, I was interested by working on QGraphicsView, mainly because of my past.

1:20
Locuteur

I

1:20
Présentateur

was involved recently, beginning of the year, in QML development, mainly the graphical part of it, like making it work in QGraphicsView.

1:29
Locuteur

and

1:30
Présentateur

now I moved on a bit to change what I was doing, and I'm working on Qt WebKit and WebKit in general, and recently I was working on the HTML5 video and audio elements.

1:44
Locuteur

On

1:45
Présentateur

the side note, I'm a KDE developer, even though today I'm using macOS. Since 2006, I joined the KDE development when I was

1:55
Locuteur

a

1:55
Présentateur

student. I work on Keplato. It's a project management application. and then I joined Plasma, the desktop thing, in 2007 when they were trying to find people to help. And nowadays I'm actually working on the mobile version of Plasma, which works on my A900, as my spare time.

2:18
Locuteur

On

2:18
Présentateur

my spare time. Working in Qt development framework is actually quite cool, because I left the French fast food

2:26
Locuteur

for

2:27
Présentateur

the Norwegian gastronomy,

2:28
Locuteur

which

2:29
Présentateur

is based on sausages and hot dogs. So it's very nice. And also the weather is really cold up there. But it's fun to work there. Do you think how many we are for working on Qgraphics view? Let's say 10, 20, something like that? How many you think we are? Give numbers. Run them. Ah, he knows. We are two on a knife. There is Bjorn-Erik, my colleague. There is me, and there is a new guy that joined at the beginning of the year, the company. And there is also some guys working around, but not on the core Graphics view. We used to have Andreas, but he left. It was the main, like the guy behind Graphics view, the guy that created the framework.

3:22
Locuteur

So

3:22
Présentateur

a bit of the history of the framework. So Qgraphics view was born in Qt 4.2.

3:33
Locuteur

At

3:34
Présentateur

that time, it was born to replace the old Qt 3 Qcanvas.

3:40
Locuteur

So the

3:41
Présentateur

goal of that project was to make it better and easy to use API because Qcanvas, while I was doing the presentation, I was looking at the API of Qcanvas, and I was like, wow. And so, yeah, basically,

3:55
Locuteur

when

3:56
Présentateur

Qgraphics view arrived, it was a replacement of Qcanvas, the same, trying to solve the same issues and on a better API and based on Qt 4, basically.

4:09
Locuteur

Then

4:10
Présentateur

in Qt 4.3, we basically added features like convenience for, let's say, the reverberant selection for items, Qtransform support, and some later APIs addition like convenience like

4:24
Locuteur

for

4:25
Présentateur

mapping coordinates in between the scene and the item and so on. Qt 4.4, huge projects called Widgets and Canvas. The idea was to create

4:36
Locuteur

widgets

4:37
Présentateur

or at least the base, like the building blocks for bringing widgets inside Graphics view. By that, I mean creation of Qgraphics widgets and also creation of layouts

4:49
Locuteur

and

4:49
Présentateur

also the, like the, we wanted also to be able to support Qwidgets inside Qgraphics view and that's why Qgraphics proxy widget arrived.

5:01
Locuteur

Qt

5:02
Présentateur

4.5,

5:03
Locuteur

a

5:03
Présentateur

lot of feedback. Qgraphics widget, buggy. Layouts, not very nice. I know because I was using them in Plasma, so I was fixing them while I was using them in Plasma.

5:17
Locuteur

Basically,

5:18
Présentateur

it was like incorporating the feedback from the people, the customers, the community, and fixing everything. And we met also, met some performance improvements, but not that much. Basically,

5:30
Locuteur

faster

5:32
Présentateur

indexing lookup, I'll explain what it is. Better caching and stuff like that. But what we discovered back in time is like making layouts is really hard. So, we learned it the hard way. Qt 4.6, it's basically the biggest refactoring of the framework. We took our painting code, we threw it away, and we revoid it from scratch.

6:02
Locuteur

We

6:03
Présentateur

moved the indexing logic out of the scene, put it into a separate class so we could optimize it separately.

6:09
Locuteur

And

6:10
Présentateur

we also introduced Qgraphics objects.

6:12
Locuteur

It

6:12
Présentateur

was mainly for QML. So, Qgraphics object is like a subclass of Qgraphics item, but also inherits from Qobject. And then you can get the property support and all the convenience that you have with Qobject.

6:25
Locuteur

And

6:26
Présentateur

Qt 4.7, mainly stability, after the biggest refactoring that we did in 4.6, like bug fixing, little API additions there on there for QML, and some little tweaks for the performance, trying to do our best, basically.

6:43
Locuteur

And

6:43
Présentateur

since Qgraphics view is widely used in Nokia, at least for Amigo and Symbian 4, we got a lot of feedback from them as well, so I was working hardly to actually fix what they were asking for.

6:57
Locuteur

So,

7:01
Présentateur

the architecture. I'll just give a basic overview. You guys can figure out while using the framework, and I won't repeat the documentation anyway. So,

7:11
Locuteur

you

7:12
Présentateur

start with Graphics view, Qgraphics view. You can have multiple views. It's like a built-in feature of the framework. It's like

7:18
Locuteur

the

7:19
Présentateur

viewers can see the entire scene, or

7:22
Locuteur

they

7:23
Présentateur

can see part of the scene.

7:27
Locuteur

So,

7:27
Présentateur

they basically see a graphic scene. The graphic scene is responsible for managing the items, adding items, removing items. The graphic scene is responsible for paintings, and everything related to events. Internally, the graphic scene,

7:47
Locuteur

that

7:47
Présentateur

you won't find in the documentation, has a graphic scene index. So, why we have an index is basically to find the items. Like, we can't have just one list of items. We just need an index for finding them.

8:02
Locuteur

And

8:02
Présentateur

currently, on the framework, we've got

8:04
Locuteur

two

8:05
Présentateur

indexes. One is the BSP tree. I will explain what it is. And one is a linear scene index, which is basically a whole list of items.

8:17
Locuteur

So,

8:18
Présentateur

the three last boxes are internals. You want access to it. It's not public API. And, of course, the index is responsible for managing the items. So, the QGraphics items. It's only one of the index. It's like not two, right? Like, either you have a linear index, either you have the BSP. The view. So, it's Graphics view, right? So, as I said, it visualizes a part of the complete scene. It's a QAbstract scroll area because it supports scrolling. So, you can navigate in the scene with the view, with the mouse, for instance. And, if it's a QAbstract scroll area, then it's a QWidget, which means that it can be top-level, it can be put into a layout, and so on.

Everything that you get from QWidget, you have it on the Graphics view.

9:12
Locuteur

So,

9:12
Présentateur

as I said, scrolling support. It has a selection support. You can grab the mouse and select items inside with a rubber band, for instance.

9:21
Locuteur

And

9:21
Présentateur

the Graphics view is responsible. Like, I mean, the Graphics view receives all the events from QT, right? From the windowing system, for the event queue, for everything. Resale the paint events, resale the keyboard events, resale everything. And then, basically, except for the rubber band, is forward everything to the Graphics scene. There is not that much logic for the painting code, not that much logic for the events inside Graphics view. It's basically send everything to the Graphics scene.

9:52
Locuteur

The

9:52
Présentateur

view supports transformation, so you can actually rotate. You can do everything that QTransform support, basically. So rotation, scaling, and so on. So you apply on the view and not on the scene, right?

10:12
Locuteur

So

10:13
Présentateur

I won't go more in detail for Graphics view. Let's go for tips and tricks, because that's what matters. How you can use Graphics view and all the framework the best you can, right? That's the purpose of my talk.

10:28
Locuteur

First,

10:30
Présentateur

so Graphics view has an optimization flag. One is called don't save painter state.

10:36
Locuteur

So

10:36
Présentateur

what that means. Basically, when we render the items, like

10:40
Locuteur

we

10:41
Présentateur

get the painter from the paint event of QGraphics view, then it goes to the scene, and then the scene says, okay, I need to render items. It's a bit more complex, but let's put it simple for now.

10:51
Locuteur

So

10:52
Présentateur

let's say you have to render two items, right?

10:55
Locuteur

The

10:55
Présentateur

rendering of the item is actually made by calling paint on the item, right? You get a QPainter, and then you do stuff with it, and then you return, and then we paint the second item, right? That's how it works. Let's say the simplified version.

11:08
Locuteur

So

11:08
Présentateur

what happens is like when we call paint, we give the same painter that we have at the beginning, which means that in your paint function, you can do whatever, right? Changing the paint, changing the brush, doing crazy stuff, right?

11:21
Locuteur

Which

11:21
Présentateur

means that when we call paint on the second item,

11:24
Locuteur

the

11:24
Présentateur

painter has to be clean. Otherwise, you will narrate everything that you got from the previous paint event, the brush modified, the pen modified, and everything, right? So

11:33
Locuteur

what

11:34
Présentateur

happened today is like if you use GraphicView by default without setting this optimization flag, it's like before calling the paint on an item, we save the painter, call paint on your item. You can do whatever you want there, and then we restore the painter.

11:47
Locuteur

And

11:48
Présentateur

then we call the next one, save, paint, and restore.

11:52
Locuteur

So

11:52
Présentateur

when you arrive and your paint function on your item, you always have a clean painter.

11:59
Locuteur

So

12:00
Présentateur

when you trigger this, when you set this optimization flag to true, what happens is like we don't save and restore the painter anymore in between items.

12:11
Locuteur

It's

12:11
Présentateur

not like a huge performance improvement, like don't expect two times faster, right? Because saving and restoring has been optimized quite a lot on Qpainter, but

12:20
Locuteur

it's

12:21
Présentateur

still beneficial. So I actually show it in the demo.

12:31
Locuteur

So

12:31
Présentateur

I've ordered a small demo. By the way, there will be no super nice effect and so on. It's basic demos with boxes and rectangles, like all the fashion needs was basically on Guilnard's talk this morning, or I mean beginning of afternoon.

12:48
Locuteur

So

12:49
Présentateur

on this demo, it's basically a simple main window, right? I have a graphic scene here. I set the scene on my graphics view. It happens to be on the UI file. I don't need to go in detail, right? There is a graphics view.

13:03
Locuteur

I

13:04
Présentateur

got a top-level parent item, which is a top-level graphics widget.

13:10
Locuteur

I

13:10
Présentateur

add it into the scene, and then I have got a double loop, which basically adds graphics proxy widgets with the red widget inside. And then, let's see, it's a bit better to read, exactly.

13:25
Locuteur

So

13:26
Présentateur

I got a, yeah, graphics proxy widgets, and then set widgets, which is actually a red widget, and then set pose. I basically put them as a, like a grid, right?

13:36
Locuteur

And

13:36
Présentateur

then I got my small utility class, which basically gives me the FPS. And then I have an animation on the position on the parent item, so the top-level one, and I actually ask him to move, right? That's not a very advanced example, right? So, and then if you look at the red item, which is a key widget. Sorry. Let me see if I was right here.

14:04
Locuteur

Up. Yeah.

14:06
Présentateur

So, sorry, it was like I was editing the wrong one. So the yellow item, so it's just a graphics widget. I can show the implementation here, which in the paint event, does draw text, so it actually draws B. That's really basic. It's set the brush to yellow, so the background will be yellow, and the pen blue, so like the border of the rectangle will be basically blue,

14:31
Locuteur

and

14:32
Présentateur

an opacity of 0.5,

14:34
Locuteur

and

14:34
Présentateur

then just I draw a rect. Basic code, right?

14:38
Locuteur

So

14:38
Présentateur

when you run this example,

14:43
Locuteur

it

14:44
Présentateur

looks like this.

14:45
Locuteur

probably

14:46
Présentateur

showing my screen here. Yeah.

14:49
Locuteur

I

14:50
Présentateur

need to move it here. Up.

14:53
Locuteur

Exactly.

14:54
Présentateur

So as you can see here, on the button, my FPS tracker actually debugged the average millisecond I spent per frame,

15:02
Locuteur

and

15:02
Présentateur

as you can see here, 66, 67, 55, so around 60, let's put it like this, right? Now,

15:12
Locuteur

go

15:12
Présentateur

back to my main window,

15:13
Locuteur

and

15:14
Présentateur

then here,

15:16
Locuteur

on

15:17
Présentateur

the graphics view, I set the flag, optimization flag, don't save, pair or set, true. Let's see what it looks like when I run the app. The macro is really annoying. I can't remember the position of the window.

15:37
Locuteur

So

15:37
Présentateur

you see, it's like the frames are slightly faster, 50 is not like, it's not awesome, as I said, but it's still like some milliseconds per frame that we save by not saving and restoring the painter's save at each time I paint the item. This is the ideal use case, for sure.

15:54
Locuteur

The

15:55
Présentateur

problem, as I said on the slide, is we don't save the painter's save, right? Now, let's say I have a red item, like this, that I put on top of all of them, this one, right? It's basically the same item as the yellow one, but in red.

16:10
Locuteur

It's

16:11
Présentateur

just slightly different.

16:16
Locuteur

If

16:16
Présentateur

you look at

16:17
Locuteur

the

16:17
Présentateur

code here, so it's quite a pen, set the color, red, right? So I got the border of the rectangle being red,

16:27
Locuteur

and no

16:28
Présentateur

brush, and set the width to four, so it's like a huge line, and then a bonding, right? Right? So what do you expect?

16:35
Locuteur

You

16:36
Présentateur

expect a translucent rectangle?

16:38
Locuteur

When

16:38
Présentateur

you see this painting code, you expect a translucent rectangle with like a big blue border, a red border, sorry, right? Because, and let's see what's happened when you actually run the code. Ah,

16:55
Locuteur

here. You

16:57
Présentateur

see, funny enough, like the content is actually yellow.

17:01
Locuteur

Why?

17:03
Présentateur

Because when we run down the previous item, the smaller yellow ones, like we set the brush to be yellow on the yellow ones,

17:11
Locuteur

and

17:11
Présentateur

then since we don't save the painter state and restore the painter state anymore, like when we arrive on the paint function of the red one, then the brush is set to yellow,

17:20
Locuteur

which

17:21
Présentateur

means that you inherit a dirty state of the painter, right? That means that that's why it's actually yellow in the middle.

17:29
Locuteur

So I

17:30
Présentateur

recommend to use that flag, and when you have like broken behaviors like this, then you fix your painting code.

17:37
Locuteur

And

17:37
Présentateur

it's easy in that case.

17:39
Locuteur

Here,

17:40
Présentateur

on my red item,

17:42
Locuteur

what

17:43
Présentateur

I can do is painter, set brush, and then cut, no brush. That's what I want, right?

17:55
Locuteur

Then

17:56
Présentateur

you ensure that

17:56
Locuteur

what

17:58
Présentateur

you want will be on the screen regardless of the previous state of the painter, right? Otherwise, what you could have done is painter, restore, and save at the end, right? Sorry, save, sorry, save here,

18:14
Locuteur

and

18:15
Présentateur

then restore at the end of your paint function, right? But I recommend to set the brush because it's cleaner at least for me, I think. So when I run the example,

18:26
Locuteur

it

18:26
Présentateur

looks like this, translucent. That's what I wanted since the beginning.

18:31
Locuteur

And

18:31
Présentateur

of course, now if I remove,

18:35
Locuteur

if

18:36
Présentateur

I remove my fix, like this, right? Up. And then I come back to my main window and then unset the flag

18:47
Locuteur

and

18:47
Présentateur

then run it.

18:53
Locuteur

That's

18:53
Présentateur

the same result, right? So, use the flag.

18:58
Locuteur

If

18:59
Présentateur

you have regressions in your code, fix the painting code. That's the best you can do. Up. Let's go back to the presentation

19:13
Locuteur

because

19:14
Présentateur

I did the demo. Other tips and tricks. Graphics view has a cache mode built-in inside. So you get two modes. You can either cache the background or

19:26
Locuteur

do

19:28
Présentateur

not cache the background.

19:29
Locuteur

So

19:30
Présentateur

why? Because Graphics view has a draw background function that is virtual so you can reimplement it. It gives you a painter and a rectangle which is the size of the view,

19:38
Locuteur

right?

19:40
Présentateur

Oops. And so you can actually draw your custom background instead of the default one which is white. When you activate the cache, what happens is that

19:54
Locuteur

when

19:55
Présentateur

we call draw background, instead of giving the painter open like the normal painter that comes from Graphics view, we actually open one on a PixMap.

20:03
Locuteur

Then

20:04
Présentateur

we call draw background and then everything you do will go to a PixMap that will save

20:08
Locuteur

and

20:09
Présentateur

then the next paint event instead of calling again your draw background function will actually just draw the PixMap.

20:17
Locuteur

It's

20:17
Présentateur

nice

20:18
Locuteur

because

20:19
Présentateur

if you have a complex background let's say with gradients and really complex background gradients like dotted lines and stuff like that, then it will actually be faster.

20:28
Locuteur

The

20:28
Présentateur

drawback is

20:30
Locuteur

the

20:31
Présentateur

memory consumption because let's say your view is huge like you get at least a PixMap let's say 640 by 480, then at least the PixMap will be that size.

20:42
Locuteur

So

20:42
Présentateur

if you're running on a very low-end hardware and with not that much memory, well, you have to compromise with either you have more memory usage or you simplify the painting of your background. The other flag that is on it since 4.6 it's the indirect painting

21:03
Locuteur

it's

21:04
Présentateur

actually not tips and tricks it's just to remember what it is. Before 4.6 graphics view had a virtual method called draw items where you can actually subclass and override that method and interfere

21:20
Locuteur

on

21:21
Présentateur

the painting of the items. I don't know, setting something different from the painter or doing pre-processing or whatever.

21:30
Locuteur

The

21:31
Présentateur

problem with this public API is that it was giving a list of items to draw and

21:37
Locuteur

the

21:38
Présentateur

style options for them when you paint. And the list of style options was

21:45
Locuteur

not

21:45
Présentateur

very optimal. Allocating all of them and giving them to the public function to the function and in most cases was doing nothing because not that much people actually override draw items. So

21:58
Locuteur

since

21:59
Présentateur

4.6 we basically deactivate the call of that function so we change the behavior. It's bad, I know. But at least it doesn't call the public function anymore so it doesn't allocate all those graphic style options the q style option graphics item

22:14
Locuteur

and then

22:17
Présentateur

goes directly to the scene via private functions. But if you do want the old behavior you can set that flag indirect painting and then it will call the old function like before same behavior as before.

22:30
Locuteur

But

22:30
Présentateur

it's slow. It's slower.

22:33
Locuteur

So

22:34
Présentateur

sometimes you better think about what you were actually doing in your draw items code and think about okay can we do it a

22:40
Locuteur

different

22:41
Présentateur

way

22:42
Locuteur

because

22:43
Présentateur

there's not the optimal path. Just like just remember one thing on the cache mode don't activate the cache if on the draw background of your graphics view you just draw a pixmap

22:59
Locuteur

because

23:00
Présentateur

what's the point caching a pixmap

23:03
Locuteur

which

23:03
Présentateur

is a I mean caching into a pixmap a pixmap right so it has to be a very expensive draw background code

23:10
Locuteur

so

23:11
Présentateur

that the cache mode will be a beneficiary. Other tips and tricks I recommend the usage of set viewport new QTL widget so basically setting the viewport of graphics view as a GL widget so you can actually also do GL code in your painting code of the items

23:32
Locuteur

because

23:32
Présentateur

then the rendering will go through the GL widgets and then you get some GL acceleration or boost in some cases. For instance on the Nokia 900 the best couple I could find at least for KDE was using the GL widget as the viewport and graphic system raster. If someone comes with a better combination then I'll be happy. Also for instance let's say you're doing a full screen app which let's say you're doing a mobile application which is full screen

24:03
Locuteur

you

24:04
Présentateur

want to set set from style to zero. All those tips and tricks are no big deal right? I'm not talking about getting like I don't know 10% performance improvement

24:13
Locuteur

but

24:13
Présentateur

for instance getting away the frame style doesn't query the styles doesn't draw useless stuff doesn't allocate borders and stuff like that so when you do a full screen app like a game on a mobile phone you better want to set that.

24:27
Locuteur

For

24:27
Présentateur

instance on QML we do it. Same if you do a full screen app

24:37
Locuteur

you

24:38
Présentateur

want to set you

24:40
Locuteur

want to set the

24:40
Présentateur

attribute WA translucent background to false. This attribute means that the background of the graphics view will be translucent

24:47
Locuteur

so

24:48
Présentateur

you can actually do translucency right? And

24:52
Locuteur

it

24:52
Présentateur

depends the operating system you're only on let's say on X11 you need to have like a window compositor like let's say compes kwin or on Windows it has to be at least from Windows Vista and macOS it always works pretty much

25:06
Locuteur

so but

25:09
Présentateur

why you want to deactivate it sometimes because

25:12
Locuteur

on

25:12
Présentateur

the Android again

25:14
Locuteur

if

25:15
Présentateur

you set it to true

25:16
Locuteur

even

25:17
Présentateur

if you let's say draw a background which is completely opaque

25:20
Locuteur

the

25:21
Présentateur

compositor like the window compositing will try to compose it like crazy

25:25
Locuteur

to

25:26
Présentateur

actually try to do translucency even though you draw an opaque surface on top of it right? And then your FPS drops like crazy

25:34
Locuteur

so

25:35
Présentateur

once I discovered in Plasma like one of our issues at the beginning was that the fact that we didn't set to false the translucent background because on the desktop version we do require it

25:44
Locuteur

but

25:45
Présentateur

on the mobile phone since it's a full screen app we didn't care

25:48
Locuteur

and

25:49
Présentateur

it was set to true and the framework was very bad so be careful of your old code that went on the desktop and then you tried to port it on the mobile world and it's true

26:01
Locuteur

also

26:02
Présentateur

I recommend the usage of graphics system raster because it's any way faster than the native I think I have a small demo

26:16
Locuteur

so

26:16
Présentateur

on that demo so you remember I got like 58 54 FPS right let's say now I go to the project and then on run settings macOS or kit creator

26:37
Locuteur

should

26:45
Présentateur

be okay ah

26:47
Locuteur

so

26:48
Présentateur

you see like 20 milliseconds average per frame less just by using raster on this simple demo right which just draw rectangles and have a bit of opacity and draw some text right

26:59
Locuteur

what

27:00
Présentateur

a fight to just show that so yeah use graphics system raster go for it

27:11
Locuteur

back

27:12
Présentateur

in graphics view graphics view has some viewport update mode what is the viewport update mode is like the way we actually send updates I mean the way we actually update the scene

27:29
Locuteur

full

27:30
Présentateur

viewport update is recommended for viewports like GL widgets why because QGL widget for now at least doesn't support partial updates right so you can say oh the top left corner has been updated and as well as the right or the bottom right for instance it's always a full update

27:50
Locuteur

and

27:50
Présentateur

actually in some cases it's faster in GL to redo everything than trying to figure out what to redo

27:56
Locuteur

so

27:57
Présentateur

full viewport update when you have a GL widget is also what I found out to be the best combination for the I900 and Plasma

28:04
Locuteur

by

28:05
Présentateur

default it's bonding rect viewport update and to be honest I think it's the best compromise you can find it's the best case for many many use cases

28:14
Locuteur

you

28:14
Présentateur

can try the others there are two more it's well explained in the documentation to be honest it's like it's a one line change in your code right so try it and then you see if it's beneficial or not but at least it's nice to remember that they exist and use full viewport update for GL widgets it really depends the scene so try it by yourself other tips and tricks if you know the area the view should see so let's say you know that your graphics view will see the entire scene

28:47
Locuteur

or

28:47
Présentateur

you know exactly the part you'll see always call set scene right on the graphics view why

28:54
Locuteur

because

28:54
Présentateur

graphics view has a built-in feature to actually trying to

28:58
Locuteur

fit

28:58
Présentateur

the content and to see like the optimal part of the scene and also adjust the scroll bars and so on

29:08
Locuteur

and this

29:10
Présentateur

is expensive calculation when you add an item you know we have to figure out what we should see and so on and update the scroll bar and stuff like that so

29:20
Locuteur

when

29:21
Présentateur

you know the array you will see on the scene always set scene rect because then you don't need to we don't need to do those computations the framework won't do them for you right

29:31
Locuteur

so

29:32
Présentateur

when you got a full screen app that see the entire scene

29:36
Locuteur

then

29:36
Présentateur

set code sets in right it's the best code path you can get

29:42
Locuteur

also

29:43
Présentateur

there is a fit in view I just remember it's basically scaled the view matrix and update the scroll bar accordingly to ensure that the scene rectangle fits inside the graphics view port right

30:00
Locuteur

so

30:00
Présentateur

that you can see basically the entire scene

30:02
Locuteur

so

30:03
Présentateur

how it works it basically scaled right if it doesn't fit in your scene rect on the view then it will scale everything down so that you can see the entire scene right

30:13
Locuteur

I've

30:14
Présentateur

seen code people were calling fit in view because they didn't know exactly what it was doing and what happened is the scaling factor that was applied was close to 1 0.9 or something like that so on the screen with your eyes you can't see it

30:30
Locuteur

like

30:32
Présentateur

if you look like with a magnifier and stuff like that you see it but

30:36
Locuteur

it

30:36
Présentateur

looks the same right with 0.91 it transformation applied on every item right so the cost of convenience is basically that you slow down everything for sometimes nothing

30:55
Locuteur

so

30:55
Présentateur

be careful of this fit in view feature

30:58
Locuteur

sometimes

30:58
Présentateur

you better do it by yourself scaling the items you really need to see and so on the scene

31:10
Locuteur

so

31:10
Présentateur

the graphic scene

31:14
Locuteur

it

31:14
Présentateur

manages the item

31:15
Locuteur

it's

31:16
Présentateur

easy so by managing it means like if you delete the scene then it will delete all the items the scene is responsible for hiding items inside removing items inside

31:27
Locuteur

the

31:28
Présentateur

scene is also responsible for delivering the events

31:30
Locuteur

by

31:31
Présentateur

delivering the events it's like let's say you get a keyboard event the scene is responsible to find which item will get the keyboard event

31:40
Locuteur

the

31:40
Présentateur

graphic scene under the focus same where I should input and we will get the focus when the scene will get the focus back

31:51
Locuteur

and

31:52
Présentateur

the graphic scene handles the painting

31:55
Locuteur

so

31:56
Présentateur

what should be redrawed

31:58
Locuteur

how

31:59
Présentateur

we redrawed and stuff like that

32:03
Locuteur

so

32:03
Présentateur

the core feature of the I mean the graphic scene need an index so why basically the index is needed for item lookup so when you need to let's say you have a redraw on let's say on top right corner and you need to figure out

32:22
Locuteur

what

32:23
Présentateur

is in this area what are those items there so you need to find them fast right you cannot just go through one list and then one by one say okay are you there no are you there no are you there no right it will be slow so

32:40
Locuteur

and

32:40
Présentateur

also for collision detection let's say you want to know the items that collides with the one you are actually working on then you need to know the one around you right same you can't go through all of them to figure out if they are next to you and they collide to you they collide actually with you

32:56
Locuteur

so

32:57
Présentateur

we got two implementations today linear

33:00
Locuteur

just

33:01
Présentateur

plain list of items

33:02
Locuteur

so

33:04
Présentateur

linear time lookup it's actually partially false but let's put it like this BSP so it's binary space partitioning it's actually the default I'll explain the next slide what is BSP

33:25
Locuteur

so

33:25
Présentateur

BSP it's like

33:27
Locuteur

it's

33:28
Présentateur

a tree and how it works is like in the scene so when you add items and so on we modify that BSP tree

33:35
Locuteur

we

33:36
Présentateur

basically divide the scene into small parts to create a tree of areas right like I saw in the small diagrams look so let's say the shape like the black shape is like the scene we divide in two parts so we got the tree let's say A B and C

33:53
Locuteur

and

33:54
Présentateur

then we divide it to actually have like to basically decomplexify the scene that we have so that and then on the leaf of our tree we actually add the items

34:09
Locuteur

so

34:10
Présentateur

whenever you want

34:11
Locuteur

to

34:11
Présentateur

find an item you just look the area you're looking for so let's say I don't know a rectangle and then you look the x and y and then or C is like minus or like bigger or less and then you basically divide by two at each time the areas you're looking for items right

34:31
Locuteur

so

34:32
Présentateur

it's a well-known implementation mainly used in 3D they actually use they don't use that much VSP anymore they use like something like octree and stuff like like the 3D open source 3D lookup is fast as I was explaining we just divide like we just divide the areas and then go deep into the tree and then we have a smaller list of items than the global list of all items in the scene right

35:00
Locuteur

but

35:00
Présentateur

as you can imagine moving is slow because let's say the item move because of an animation

35:07
Locuteur

well

35:07
Présentateur

we need to first find it in the tree fast

35:10
Locuteur

but

35:11
Présentateur

then we need to move it in the tree so that it will have the right position afterwards because let's say it moves from the area C to B it has to move in the tree right

35:21
Locuteur

so

35:22
Présentateur

keeping up to date the BSP tree is something that is slow

35:29
Locuteur

so

35:30
Présentateur

let's say you have an animation where the item is called set pose set pose set pose set pose like it kills the frame rate so

35:39
Locuteur

we

35:39
Présentateur

come up with a work around

35:43
Locuteur

so

35:44
Présentateur

the first time you call set pose

35:46
Locuteur

we

35:46
Présentateur

put into temporary so we remove the item from the tree of the BSP right

35:51
Locuteur

we

35:51
Présentateur

put into a temporary list

35:52
Locuteur

and

35:53
Présentateur

then we start the timer

35:55
Locuteur

and

35:55
Présentateur

then at each time you call set pose the timer is reset

35:57
Locuteur

reset

35:58
Présentateur

reset reset reset reset and then when the timer expires like timeouts then we re-add the item into the BSP

36:06
Locuteur

so

36:07
Présentateur

that's why when you call set pose many times then it's actually fluid because we don't need to update the BSP so it's only when the items become static that we re-add it into the BSP

36:20
Locuteur

the

36:24
Présentateur

problem with that of course is if you call set pose or you animate thousands of items at the same time because then we got all those timers going on and then a big list of temporary items that are moving which means that when you need to remove them from this list because the timer expired and stuff like that then it's linear lookup and stuff like that so it has drawbacks

36:52
Locuteur

so

36:53
Présentateur

the index you can change it with the set item index method

36:57
Locuteur

and

36:58
Présentateur

then of course you might ask which one I should use BSP it's basically it depends of the scene but you can try it as well it's a one line code change but BSP is usually more for static contents right the one that you don't move typically the demo we have which is like the ship demo you know with like four views thousands of items that don't move

37:25
Locuteur

this

37:25
Présentateur

is the best use case no index

37:30
Locuteur

is

37:31
Présentateur

nice for animated scene that doesn't contain that much items for instance in QML we deactivate the BSP

37:38
Locuteur

because

37:39
Présentateur

there is no damaged items like in the ship demo for instance so no index is faster on Plasma I also put no index it was faster

37:54
Locuteur

okay

37:54
Présentateur

now let's move on a bit talking about how the wandering works

38:00
Locuteur

in

38:01
Présentateur

graphic scene it's hard to explain so I try to do my best to actually show it on slides

38:10
Locuteur

so

38:11
Présentateur

first what happened is like we get our suspects graphics view graphic scene and the index I put the index as a generic because it doesn't matter if we use the BSP or the linear in that case

38:24
Locuteur

so

38:24
Présentateur

we get a paint event that arrives from the window system or anything like you calling updates for instance or the window system saying oh you need this region is dirty you need to repaint

38:36
Locuteur

then

38:37
Présentateur

graphics view basically does nothing

38:40
Locuteur

I

38:41
Présentateur

mean yes it actually draw the background and then

38:45
Locuteur

call

38:46
Présentateur

draw items

38:46
Locuteur

not

38:48
Présentateur

the public function the private one since 4.6

38:51
Locuteur

on

38:52
Présentateur

the graphic scene and say okay here is the region you need to repaint

38:56
Locuteur

and

38:56
Présentateur

here is my transformation my view transformation and riddle

39:02
Locuteur

so

39:02
Présentateur

then the graphic scene need to find out for those regions the items that it needs to repaint for for that it it will say okay I go to the index and

39:14
Locuteur

I

39:14
Présentateur

like all

39:15
Locuteur

the

39:16
Présentateur

top levels

39:18
Locuteur

for

39:18
Présentateur

a given area so let's say if it's on the top right corner then give me all the top level items that are in that area

39:27
Locuteur

and

39:28
Présentateur

return me a list of that

39:30
Locuteur

right just

39:33
Présentateur

the parents

39:35
Locuteur

and

39:36
Présentateur

then what happened is like

39:37
Locuteur

we

39:38
Présentateur

start from the parent

39:39
Locuteur

and

39:40
Présentateur

then we render the subtree so all the children recursively

39:43
Locuteur

so

39:44
Présentateur

starting from the parent then one child and then recursively all the children of this child and then to the next child and so on and then we do it for all the top levels that is returning that the graphics in this return

39:58
Locuteur

so

39:58
Présentateur

it's recursive algorithm for painting it's actually almost the same in q widgets this paint algorithm is the one since 4-6 before it was not like that

40:11
Locuteur

before

40:12
Présentateur

it was iterative so the only difference with that diagram is basically that when we asked the index the items for a given area it was returning everything not necessarily top levels

40:26
Locuteur

so the

40:28
Présentateur

main problem with this approach was

40:36
Locuteur

when

40:36
Présentateur

you run out from the parents and then you do the subtree right as I was explaining let's say the parent has a transformation let's say 45 degree rotation

40:44
Locuteur

so

40:45
Présentateur

you need to apply the transformation on the painter right to paint 45 degree right so which means that all the children except if they ignore the transformation they will be rotated by 45 degree as well right

41:00
Locuteur

so

41:01
Présentateur

the painter

41:02
Locuteur

the

41:03
Présentateur

transformation set it on the like that you set on the painter it stay the same while we render recursively the whole subtree right

41:09
Locuteur

versus

41:10
Présentateur

the problem with the iterative approach is like since we got random items from different sub trees and just a list which was non ordered

41:18
Locuteur

we

41:18
Présentateur

start from one item say okay what is your transformation your top level fine I just use your transformation next one

41:25
Locuteur

next

41:26
Présentateur

one it can be a children deep inside the subtree and then we need to figure out okay what is the transformation and then you need to go to the parent to see if it has a transformation and so on until you reach the top level to actually find

41:40
Locuteur

the

41:40
Présentateur

transformation for the complete tree right

41:44
Locuteur

and

41:44
Présentateur

this was

41:47
Locuteur

a

41:47
Présentateur

bottleneck of the previous implementation is actually to find out also the opacity right if you have an opacity of 0.5 on the parents and then

41:59
Locuteur

the

41:59
Présentateur

children will also have the opacity of 0.5 right

42:02
Locuteur

but

42:03
Présentateur

if you can set different opacity on all the children right and then you combine this opacity and then that's the same you need to figure out up until the parents

42:12
Locuteur

the

42:12
Présentateur

real opacity that you will apply on the painter

42:15
Locuteur

so

42:16
Présentateur

what did first is we tried to cache everything so cache the opacity cache the transformation and so on but that was a bad idea because

42:29
Locuteur

when

42:29
Présentateur

you cache data it's fine if nothing changes like if you have to redo

42:35
Locuteur

after

42:35
Présentateur

and after the same content then that's fine because you calculate the cache the first time let's say for the transformation you calculate the cache for every item like their cached transform

42:47
Locuteur

but

42:47
Présentateur

let's say

42:49
Locuteur

you

42:49
Présentateur

call set transform then you need to update all the caches right so the worst part is like if you update the set transform on the parent then you need to invalidate all the cache on all the children and then recalculate everything back and forth

43:01
Locuteur

so

43:02
Présentateur

painting was faster but calling functions like set transform or set opacity became slower

43:09
Locuteur

so

43:10
Présentateur

at the end there was no benefits cache up to date was insanely hard

43:21
Locuteur

so

43:21
Présentateur

versus now the recursive approach

43:23
Locuteur

the

43:24
Présentateur

fact that it is recursive and then each time we paint a child we actually give the painter like it is we actually save those calculations so rendering by sub trees make it very efficient and also

43:41
Locuteur

the

43:41
Présentateur

fact that we are caching stuff like make the code really like it was looking bad and we were not proud in that case tentacular code like ugly really bad so we said nah let's clean it and rewrite everything the items so graphics item basically friends it has friends so the base class is graphics item it's subtract you need to implement paint and bonding write

44:17
Locuteur

it

44:18
Présentateur

has the qobject variant it's exactly the same

44:21
Locuteur

which

44:22
Présentateur

just like the property declaration and then of course you can have signal slot on it

44:27
Locuteur

and

44:28
Présentateur

I think if I recall correctly that's also some stuff for the gesture API because the gesture API need to get qobject

44:35
Locuteur

so use

44:38
Présentateur

qgraphics item if you don't care of the qobject facilities and you don't mind of the memory usage because you know if you multiply inherit qgraphics object from qobject and qgraphics item

44:50
Locuteur

so

44:51
Présentateur

the memory usage is qobject plus qgraphics item so if you have a lot of items in your scene be careful of the memory usage that's why the qgraphics item was designed to be not a qobject just for the memory usage we also have qgraphics subject I was explaining it's a qgraphics object also and it inherits from qgraphics layout items so that you can put into a layout it has a geometry concept so you can have a width height and x and y also it has font support palette support size policy support and stuff like so it's basically a bit like a qwidget

45:40
Locuteur

and

45:40
Présentateur

for instance if you have ever looked the Migo touch API for Migo

45:44
Locuteur

and

45:45
Présentateur

also the Orbit or also known as UI extension for Symbian they narrow it from Q-Graphics widgets because they put that into their layouts and so on so they use Q-Graphics widgets some tips and tricks about graphics item

46:08
Locuteur

the

46:08
Présentateur

cache mode graphics item has two cache modes it's a bit like the background I was explaining before so what happened the cache mode works is like

46:21
Locuteur

it's

46:22
Présentateur

basically like if you have a camera and then you take a picture of the item like it is on the screen and then you save that picture for the next time you are under a frame for instance so that you don't call again the paint function on the item

46:35
Locuteur

so

46:36
Présentateur

the item coordinate cache is a screenshot or a picture of the item untransformed

46:41
Locuteur

so if

46:43
Présentateur

you have a rotation on it doesn't work it will just take the picture of the item untransformed and then rotate the pixel map

46:53
Locuteur

for

46:54
Présentateur

instance device coordinate cache on the other hand take a screenshot of the item transformed right so to make it clear I did a small diagram here

47:07
Locuteur

on

47:07
Présentateur

the left item coordinate cache take a screenshot like it is

47:11
Locuteur

if

47:11
Présentateur

the item was rotated then I take the screenshot and rotate the screenshot device coordinate cache

47:17
Locuteur

as

47:18
Présentateur

you can see on the diagram like the dotted lines are actually

47:27
Locuteur

so

47:27
Présentateur

a bit how it works the cache mode so

47:32
Locuteur

when

47:32
Présentateur

there is a cache set on the item we don't use the painter that we had from graphics view and then graphics scene we actually open a new one on the pixel map

47:43
Locuteur

we

47:43
Présentateur

call your paint function

47:46
Locuteur

that

47:46
Présentateur

will render everything into the pixel map

47:49
Locuteur

and

47:50
Présentateur

then when we get that pixel map we store it into the pixel map cache

47:54
Locuteur

and

47:55
Présentateur

then I make a bit of advertisement since 4.6 there is a new API for qpxmap cache that I've implemented is because qpxmap cache the way it works is like

48:07
Locuteur

you

48:07
Présentateur

say here is a key

48:09
Locuteur

here

48:09
Présentateur

is a pixel map

48:11
Locuteur

it

48:12
Présentateur

store it for you

48:13
Locuteur

and

48:13
Présentateur

then the next time you want like so you can throw away your pixel that you store locally and then the next time you need to get this pixel from the cache you say hey I have the key I want to get it back and then the cache can view the pixel that it saved

48:27
Locuteur

so

48:27
Présentateur

the problem with the key before cat 4.6 it was that

48:31
Locuteur

it

48:32
Présentateur

was qstring

48:33
Locuteur

and

48:35
Présentateur

everybody knows that

48:36
Locuteur

if

48:37
Présentateur

you want to make something fast at least when it's in a painting code you should avoid string operation

48:44
Locuteur

so

48:45
Présentateur

what I did instead is like I've implemented an extension to the pixel cache that I recommend to use and to port your old cube pixel cache with string base key to the new API so that

48:56
Locuteur

you

48:57
Présentateur

give the pixel to the cache and then the cache gives you a key back which is an int it's encapsulated into a class but it's actually an int behind the scene

49:08
Locuteur

and

49:09
Présentateur

then you store that key

49:10
Locuteur

and

49:10
Présentateur

then the next time we run the item for instance we have the key we ask the pixel cache to get the pixel back and then we render everything we just draw the pixel that we get from the cache

49:23
Locuteur

so

49:24
Présentateur

when for instance you move

49:30
Locuteur

the

49:31
Présentateur

item

49:32
Locuteur

if

49:32
Présentateur

you don't call update on it then it's just reading from the cache and then bleating the pixel on the screen so super fast

49:40
Locuteur

if

49:41
Présentateur

a redraw is needed like for instance you call update on it then we need to figure out the exposed area

49:47
Locuteur

that

49:48
Présentateur

are dirty basically and then we call again paint on your item with a new pixel and then we replace the one in the cache by the new version

50:01
Locuteur

so

50:01
Présentateur

I got a demo for it so you'll see

50:05
Locuteur

the

50:05
Présentateur

cache modes beware

50:08
Locuteur

it's

50:08
Présentateur

nice it's fast let's say you got an item that is really complex

50:12
Locuteur

with

50:12
Présentateur

a drawing code

50:13
Locuteur

quite

50:13
Présentateur

complex

50:16
Locuteur

then

50:16
Présentateur

you save like I mean it's fast right you just run down the first frame and then after it's fast it's just like bleating a pixel on the screen but be careful because same problem as the backgrounds on the graphics view

50:30
Locuteur

is

50:31
Présentateur

like

50:32
Locuteur

it

50:33
Présentateur

allocates a pixel map but that is the size of the item right so if the item is huge then you get a huge pixel in memory

50:40
Locuteur

I'm

50:41
Présentateur

just saying device coordinate cache

50:46
Locuteur

always

50:47
Présentateur

uses more memory because as you can see here

50:50
Locuteur

the

50:50
Présentateur

actual pixel that we put on the cache the dotted lines are bigger right

50:55
Locuteur

so when

50:57
Présentateur

the item is un-transformed you better want to use item coordinate cache otherwise

51:02
Locuteur

like

51:03
Présentateur

the pixel map at the end will be the same but the code actually goes there is a bit different and more complex so if the item is un-transformed item coordinate cache

51:12
Locuteur

and

51:12
Présentateur

the drawback of item coordinate cache is like it might look bad

51:16
Locuteur

when

51:17
Présentateur

the item is transformed because we operate on the pixel map right and then the pixel map we all know that if you scale the pixel map it looks bad so I'll show exactly what's going on when it's formed

51:32
Locuteur

so

51:32
Présentateur

here I got another demo which is the cache mode

51:36
Locuteur

start

51:38
Présentateur

a project so it's basically the same demo as I had before so main window you know graphics scene graphics view apparent item same and then I got again a grid of items and in that case there are proxy

52:01
Locuteur

with

52:02
Présentateur

the red widget inside

52:03
Locuteur

I

52:04
Présentateur

show the code of the red widgets and then I position them as a grid and same my FPS tracker and same I have a property animation that moves them down

52:13
Locuteur

the

52:14
Présentateur

red widget is actually a q widget here which has a paint event and then the paint event just draw rectangle basic

52:23
Locuteur

so if

52:25
Présentateur

I run the thing right now I need to move the window

52:33
Locuteur

it

52:33
Présentateur

looks like this right moving down

52:38
Locuteur

and this

52:41
Présentateur

basic example right up and if you look the average is like

52:47
Locuteur

42

52:47
Présentateur

39 36 right

52:49
Locuteur

now

52:52
Présentateur

let's say on the item I said item set coordinate set cache mode right and then queue graphics item item code item coordinate cache

53:13
Locuteur

right

53:13
Présentateur

so I set the cache let's put it like this so you can see better I set the cache on the item right which means that the first time we run the item it runs into a pixel map then we put it into the cache and if we just move it which doesn't require to like I mean there is no dirty area while moving it unless if it's and just drawing a pixel map right so let's see the frame rates like on that guy

53:45
Locuteur

so

53:45
Présentateur

it builds and I move it back

53:51
Locuteur

here

53:52
Présentateur

so as

53:53
Locuteur

you

53:53
Présentateur

can see the frame is like 20 16 as half right

53:57
Locuteur

in

53:58
Présentateur

that case I can close when it's down here up so half just by using the cache in that particular case right

54:07
Locuteur

of

54:07
Présentateur

course and I use a lot of memory here because like I got 10 by 10 items right and I activate the cache for all of them so the memory usage increase quite a lot

54:18
Locuteur

so

54:18
Présentateur

be careful when you use it use it on the right items right on the one that you know it's a painting code complex and it's worth the memory usage

54:29
Locuteur

now

54:29
Présentateur

as I was explaining

54:32
Locuteur

let's

54:32
Présentateur

have another example to see the differences between

54:40
Locuteur

between

54:40
Présentateur

the device coordinate cache and actually the item coordinate cache so I got a small example simpler here you know graphics view graphics scene again then top level item parent and then I have children which is the yellow item I'll show what it does and then you'll see I will activate and show you the differences between the two cache modes so if you look the yellow item which is not yellow it actually

55:11
Locuteur

I

55:11
Présentateur

like white I'm French and the pen is white and actually writes stuff on it which is I'm

55:22
Locuteur

a

55:23
Présentateur

cached item right so if you run the example right now how it looks like

55:28
Locuteur

here

55:38
Présentateur

just moving around right now

55:43
Locuteur

if

55:46
Présentateur

I come back to my main window

55:47
Locuteur

what

55:52
Présentateur

happens is like if I actually

55:55
Locuteur

rotate

55:55
Présentateur

by 45 and scale the item by three on x and y right so I run it

56:04
Locuteur

here

56:05
Présentateur

no cache mode still involved right oops need to

56:10
Locuteur

put

56:10
Présentateur

it here it looks like that right so as you can see the pixel like the pixel map is not high resolution so it looks a bit crap but the font is perfect right

56:21
Locuteur

so

56:22
Présentateur

now let's say

56:24
Locuteur

I

56:25
Présentateur

activate the item coordinate cache on it

56:29
Locuteur

so

56:29
Présentateur

if you remember correctly what I said we take a screenshot untransformed and then we apply the transformations on the pixel map so the first time we render the item put it into the cache untransformed

56:41
Locuteur

and

56:41
Présentateur

then and then we apply transformation on it on the pixel map right so what do you expect to see you expect to see like the pixel map looking as bad as it was here

56:54
Locuteur

but

56:55
Présentateur

the text the text is not using like it's not using the painter API it's basically scaling the pixel map right so it will looks it should look bad actually and it will put it back

57:12
Locuteur

so

57:12
Présentateur

I don't know if you see it but it's actually really pixelized right because why we actually just scale a pixel map

57:19
Locuteur

right

57:19
Présentateur

instead of drawing

57:22
Locuteur

a

57:22
Présentateur

text on a scanned painter that's the difference

57:26
Locuteur

so

57:26
Présentateur

now you said well but in that case I just used the device coordinate cache well but that's exactly for what it is made

57:31
Locuteur

so

57:32
Présentateur

if I replace here

57:38
Locuteur

by

57:38
Présentateur

the way at each time I move the position there is no call to paint event no call to the paint function on your item right because it's cached

57:46
Locuteur

it's

57:47
Présentateur

only if you call update or it needs to be updated then it actually recall paint

57:52
Locuteur

so

57:53
Présentateur

now if you look here

57:54
Locuteur

I

57:55
Présentateur

change it to device coordinate cache

57:57
Locuteur

and

57:57
Présentateur

then you see

57:59
Locuteur

it's

58:00
Présentateur

nice

58:00
Locuteur

because

58:01
Présentateur

why

58:01
Locuteur

I

58:02
Présentateur

render the item into a pixel map after it has been transformed so the font was properly rendered and then I store that pixel map but of course

58:11
Locuteur

here

58:12
Présentateur

the memory usage is way bigger because

58:16
Locuteur

I

58:17
Présentateur

scale it by three right so on the item coordinate cache since I do a screenshot and transform the scaling is not taken into a code and the pixel is really tiny

58:26
Locuteur

versus

58:27
Présentateur

here I store this huge pixel in the memory

58:30
Locuteur

so

58:31
Présentateur

because I stored the transformed version

58:33
Locuteur

so

58:37
Présentateur

and then you have to basically

58:39
Locuteur

like

58:40
Présentateur

by yourself find out what is the best solution caching no device coordinate cache no or item coordinate cache it's up to you up to the memory that you have on your operating system

58:51
Locuteur

now

58:52
Présentateur

you know how it works

59:06
Locuteur

now

59:06
Présentateur

there is a tips and tricks

59:08
Locuteur

that

59:08
Présentateur

only if you have looked at the code you know how you can use it it's a third cache mode you know like for instance on the two other cache modes if you get an update on the right top corner then we actually clip the painter so that you only render that part

59:36
Locuteur

so

59:37
Présentateur

you get partial update of the cache right

59:41
Locuteur

now if

59:43
Présentateur

you use the graphics effect in a nasty way you can actually have subtree caching because all the cache mode that I was explaining apply per item right it's only for an item not for item plus children right so it's only for a given item

59:57
Locuteur

now

59:58
Présentateur

there are many people that say oh it would be nice to have subtree caching you know

1:00:02
Locuteur

because

1:00:03
Présentateur

you are under the complete subtree and then when you move the complete subtree then it's actually just bleating a pixmap right

1:00:13
Locuteur

so

1:00:13
Présentateur

now let's just explain how works the graphics effect so the graphics effect it's basically

1:00:21
Locuteur

we

1:00:22
Présentateur

render the items and the item itself so you can set an effect on the graphics item and then we render the item and all the children

1:00:30
Locuteur

into

1:00:31
Présentateur

a pixmap

1:00:31
Locuteur

so

1:00:32
Présentateur

why we do that

1:00:33
Locuteur

because

1:00:34
Présentateur

let's say you want to apply a blur effect

1:00:36
Locuteur

you

1:00:37
Présentateur

apply the effect on the complete subtree right you not apply the blur effect on the parent and then another blur effect on the child on one child and another child it's not right

1:00:48
Locuteur

so

1:00:49
Présentateur

you should get the complete subtree and then you apply the blur on everything

1:00:55
Locuteur

so

1:00:55
Présentateur

now you say hey but it actually render the complete thing on the pixmap the complete subtree on the pixmap so why I couldn't use that pixmap for myself so that I have a subtree caching

1:01:08
Locuteur

well

1:01:08
Présentateur

then so

1:01:15
Locuteur

and

1:01:15
Présentateur

because the API works that

1:01:17
Locuteur

you

1:01:18
Présentateur

get a draw code on the graphics effect class which gives you a painter and then you can actually ask for the pixmap of your subtree

1:01:26
Locuteur

and

1:01:26
Présentateur

then you can apply your transformation on it I mean your effects sorry so

1:01:32
Locuteur

on

1:01:33
Présentateur

the blur typically on the blur effect what we do on the draw is like we get this pixmap from the graphics blur effect on the pixmap so it's fast

1:01:48
Locuteur

now

1:01:50
Présentateur

let's say on your custom draw effects you just get the pixmap

1:01:56
Locuteur

from

1:01:56
Présentateur

the graphics view so contain all the subtree but you don't apply any effects you just draw it

1:02:01
Locuteur

well

1:02:02
Présentateur

then you just have basically a subtree caching implemented and

1:02:07
Locuteur

it

1:02:08
Présentateur

just works I have a demo to actually show

1:02:11
Locuteur

now

1:02:11
Présentateur

the only drawback of that as I was explaining is let's say one of the children get an update so either you call update on it or

1:02:20
Locuteur

for

1:02:20
Présentateur

some reason it has to be redraw because of capacity and stuff like that then all the pixmap is thrown away

1:02:28
Locuteur

and

1:02:28
Présentateur

then we have to rewonder the whole subtree on it we have to rewonder the subtree so you get the pixmap back and you can draw it

1:02:35
Locuteur

so

1:02:36
Présentateur

every update that happens inside the subtree is costly

1:02:39
Locuteur

so

1:02:41
Présentateur

that's the only drawback

1:02:43
Locuteur

so

1:02:44
Présentateur

now I have a small demo up here

1:02:49
Locuteur

close

1:02:51
Présentateur

that one graphics effect

1:02:59
Locuteur

source usual

1:03:02
Présentateur

suspect graphics view graphics scene asset the scene rex as I said parent item

1:03:10
Locuteur

nothing

1:03:11
Présentateur

and then just

1:03:13
Locuteur

20

1:03:14
Présentateur

by 20 yellow items and I put them as a grid same as before and if you look the yellow items they are the same as before just the B and opacity

1:03:26
Locuteur

and

1:03:26
Présentateur

yellow basically so same demo

1:03:29
Locuteur

so

1:03:30
Présentateur

then now

1:03:30
Locuteur

I

1:03:31
Présentateur

got here this caching effect

1:03:34
Locuteur

so if

1:03:36
Présentateur

you look the implementation of it

1:03:37
Locuteur

so

1:03:38
Présentateur

it subclass qgraphics effect

1:03:41
Locuteur

as

1:03:41
Présentateur

the draw function I was explaining ask the source pixmap so

1:03:47
Locuteur

I

1:03:47
Présentateur

can actually close that so you see better up

1:03:50
Locuteur

so

1:03:50
Présentateur

I ask the source pixmap and this pixmap that you get is actually the complete subtree so let's say the parent has many children then you get the parent plus all the children into a big pixmap right

1:04:04
Locuteur

and

1:04:05
Présentateur

then

1:04:05
Locuteur

here I

1:04:07
Présentateur

just draw the pixmap

1:04:08
Locuteur

but

1:04:09
Présentateur

in theory the way you should use the API is when you get this pixmap here

1:04:13
Locuteur

you

1:04:14
Présentateur

should do I don't know

1:04:15
Locuteur

do

1:04:16
Présentateur

an effect right blurring changing the colors on the pixmap whatever right but in that case we just use it and draw it right so

1:04:28
Locuteur

the

1:04:28
Présentateur

first time we render the guy on the item that has the effect then it will actually

1:04:35
Locuteur

say

1:04:36
Présentateur

oh there is an effect so we should call first draw all the subtree and then get the pixmap and then draw it and the pixmap is cached as well

1:04:46
Locuteur

so

1:04:46
Présentateur

source pixmap the first time render the complete subtree but the next time if nothing has changed on the subtree it reused a pixmap

1:04:53
Locuteur

that

1:04:54
Présentateur

is on the cache

1:04:56
Locuteur

so now

1:04:58
Présentateur

you said on which item I should set the effects

1:05:01
Locuteur

on

1:05:02
Présentateur

my demo so I got a lot of rectangles right

1:05:05
Locuteur

moving

1:05:06
Présentateur

around actually in that case the animation is different is actually I move actually animate the scale so all the items in the grid will actually scale right

1:05:18
Locuteur

so

1:05:19
Présentateur

then

1:05:19
Locuteur

it's

1:05:20
Présentateur

a bit stupid to actually set caching effect on all items it will bring me anything comparing to the normal cache mode right

1:05:26
Locuteur

but

1:05:27
Présentateur

what I want is like on this logical parent that is here

1:05:30
Locuteur

that

1:05:31
Présentateur

one

1:05:32
Locuteur

that

1:05:33
Présentateur

because all the yellow items are actually children of the parents right I want to set an effect on it

1:05:39
Locuteur

on

1:05:39
Présentateur

the parents so that

1:05:40
Locuteur

the

1:05:41
Présentateur

first time you will run all the children and then I get a pixmap and then whenever I need to redraw I scale the pixmap instead of scaling and redrawing everything so here

1:05:52
Locuteur

let's

1:05:53
Présentateur

say if I run without the effects you see

1:05:56
Locuteur

what

1:05:56
Présentateur

it looks like and the performance of it

1:06:00
Locuteur

I

1:06:01
Présentateur

move it you see it scales right

1:06:06
Locuteur

and

1:06:07
Présentateur

then it will stop at some point

1:06:08
Locuteur

so

1:06:13
Présentateur

of course the milliseconds per frame is not the same at each time because like on the very first paint we got many items then we scale we scale we scale and then some of them goes out of the viewport right so then we don't see them anymore so then we just discard the painting anyway so that's why the frame rate is getting

1:06:37
Locuteur

I

1:06:38
Présentateur

mean the time we spent per frame is getting lower and lower after the animation is getting before the end actually

1:06:45
Locuteur

so

1:06:46
Présentateur

now if I set the

1:06:48
Locuteur

the

1:06:48
Présentateur

effects

1:06:50
Locuteur

on

1:06:50
Présentateur

the parents so on my top level that contains all the children and then I run the animation

1:06:56
Locuteur

so

1:06:56
Présentateur

what do you expect for the frame rate same as the beginning here

1:07:01
Locuteur

and

1:07:01
Présentateur

then it should be constant right because I just scale a pixel map so the operation is always the same and then I come here

1:07:16
Locuteur

it

1:07:17
Présentateur

was

1:07:18
Locuteur

so

1:07:19
Présentateur

it's slightly faster as you can see 41

1:07:22
Locuteur

and

1:07:22
Présentateur

it's constant as I was explaining because

1:07:24
Locuteur

we

1:07:25
Présentateur

run off first and then it's just doing a pixel map but

1:07:31
Locuteur

in

1:07:32
Présentateur

that particular case it's faster it's nice

1:07:37
Locuteur

the

1:07:37
Présentateur

problem is as you can see if I rerun the demo

1:07:41
Locuteur

when

1:07:41
Présentateur

we scale

1:07:43
Locuteur

look

1:07:44
Présentateur

at the text since we scale a pixel map

1:07:47
Locuteur

text

1:07:48
Présentateur

will look crap it looks bad at the end right so

1:07:52
Locuteur

that's

1:07:53
Présentateur

the same drawback after item coordinate cache because we operate on a pixel map

1:07:58
Locuteur

so

1:07:59
Présentateur

when you should use these caching effects

1:08:03
Locuteur

actually

1:08:03
Présentateur

on my plasma here you don't see it that much but

1:08:06
Locuteur

the

1:08:07
Présentateur

way the panels move is basically we got like a normal screen

1:08:12
Locuteur

and

1:08:13
Présentateur

then one that will come so when you switch the screen like we scale down the current one slide it away then move the next one and scale up

1:08:24
Locuteur

and

1:08:24
Présentateur

those panels contain many items contain applets contain everything right and of course you know scaling

1:08:31
Locuteur

when

1:08:32
Présentateur

I do the scaling animation to like moving the panels around it was slow

1:08:36
Locuteur

and

1:08:37
Présentateur

then in that case I use the scale the effects I activate the effects only when I start the animation of changing the panel why because then when I do the scaling animation I only do it on the pix map and not on all items inside so that's one of the use cases I use the graphics effect like this

1:08:57
Locuteur

by

1:08:58
Présentateur

the way if you want to see how I use it it's on the KDE repository so I can point you the link for it

1:09:11
Locuteur

Q

1:09:12
Présentateur

graphics proxy widgets

1:09:14
Locuteur

haha it's

1:09:17
Présentateur

really tempting right because you can use any Q widget that you already have and put into the graphics view

1:09:23
Locuteur

it's

1:09:24
Présentateur

not fast

1:09:25
Locuteur

why

1:09:25
Présentateur

it's not fast because the way Q widget works is that you get a paint event right and then the paint event

1:09:36
Locuteur

you

1:09:37
Présentateur

don't get a painter you have to open the painter on the paint event right so since graphics view share the painter at each time you paint items

1:09:47
Locuteur

it's

1:09:48
Présentateur

different it's different comparing to Q widget

1:09:50
Locuteur

we

1:09:51
Présentateur

get a painter from Q graphics view which is a Q widget create I mean create a paint event from graphics view that create a painter and we reuse the same painter for

1:09:59
Locuteur

all

1:09:59
Présentateur

the items we render

1:10:01
Locuteur

even

1:10:02
Présentateur

for the background

1:10:03
Locuteur

so

1:10:03
Présentateur

now there is no way for us to actually give that painter to Q widgets

1:10:09
Locuteur

like

1:10:09
Présentateur

we can't create a paint event for the widget we embed right so the only way we can actually render the widget inside the canvas is give a painter you give a painter and render the widgets in the painter

1:10:26
Locuteur

but

1:10:26
Présentateur

render it's always a full update

1:10:29
Locuteur

so

1:10:30
Présentateur

whenever we paint a QGraphics proxy widget in Graphics view it will always be a full update on the widget

1:10:37
Locuteur

so

1:10:38
Présentateur

let's say the widget is like 200 by 200 it will be always 200 by 200 like you always paint the 200 by 200 widgets regardless the clipping regardless it's a partial update at some point

1:10:50
Locuteur

so

1:10:52
Présentateur

use it if you have no other alternatives really if you can't write your QGraphics widget subclasses

1:10:59
Locuteur

or

1:11:00
Présentateur

if you can't write Qt component for instance for QML or stuff like that

1:11:06
Locuteur

and

1:11:07
Présentateur

please don't embed complex hierarchy the way we thought people will use QGraphics proxy widgets it was like convenience for a push button and stuff like that and I've had bug reports on people embedding QMain window complete apps inside QGraphics proxy widget and expect everything to work

1:11:27
Locuteur

like

1:11:28
Présentateur

I can't debug all my life they won't work it's just too complex so it's basically making two different frameworks working together and so keep with simple widgets simplify them and try to use as simple as you can widgets like patch pattern line even combo box have to be sometimes problematics but

1:11:48
Locuteur

stuff

1:11:49
Présentateur

like that because otherwise you get focus issues painting artifacts because you know the way QGraphics proxy widget work is like we map all the events from graphic scene to QWidget and then send them through the event loop but many widgets

1:12:03
Locuteur

they

1:12:04
Présentateur

don't have code for actually handling the fat like for instance

1:12:07
Locuteur

the

1:12:08
Présentateur

X and Y is like 2000 2000 right

1:12:12
Locuteur

because

1:12:12
Présentateur

they're supposed to run on the desktop

1:12:14
Locuteur

which

1:12:15
Présentateur

is maximum resolution and 1600 by 1200 right and the scene can be huge right so for instance I remember I had a bug for the combo box and the pop-up that was showing

1:12:28
Locuteur

trying

1:12:28
Présentateur

to be smart and you know so if the combo box is on that it's not cut right

1:12:38
Locuteur

this

1:12:38
Présentateur

for instance if you were putting the combo box more in the scene on the X and Y more than your screen resolution then everything was completely broken so I actually fix it right but there's a lot of problems like this you will run into

1:12:52
Locuteur

just

1:12:53
Présentateur

because your code and our code is not very graphics view friendly so don't use it

1:13:00
Locuteur

I

1:13:01
Présentateur

have a small demo to show how slow it is and why you shouldn't use it

1:13:11
Locuteur

so

1:13:12
Présentateur

if I come back to my cache mode demo because it's defined

1:13:19
Locuteur

so

1:13:19
Présentateur

remember the demo right I create a proxy widget and then I set a widget which is just drawing a red rectangle right it was just like this basically if you remember correctly up right so let's see the frames it's unfair it has a cache mode

1:13:38
Locuteur

of

1:13:41
Présentateur

course I don't see the problem

1:13:42
Locuteur

I

1:13:50
Présentateur

put it back on the screen

1:13:59
Locuteur

so

1:14:00
Présentateur

you see it's like yeah 34 41 39 around like 30 something

1:14:06
Locuteur

now

1:14:06
Présentateur

let's say I replace my proxy

1:14:10
Locuteur

by

1:14:10
Présentateur

this yellow graphics widget which basically exactly I mean if you look this is the red widget so it's a q widget that was just a rectangle rectangle and here

1:14:22
Locuteur

it's

1:14:22
Présentateur

my yellow widget inherits from q graphics widget and does exactly the same thing but yellow right during a rectangle that's the size of the item and yellow right

1:14:31
Locuteur

and

1:14:32
Présentateur

you see the difference so I just replace it instead of

1:14:35
Locuteur

being

1:14:36
Présentateur

the proxy and with the red widget it's just the yellow item

1:14:39
Locuteur

and

1:14:45
Présentateur

then so you get exact same results but yellow right

1:14:52
Locuteur

and

1:14:52
Présentateur

then you wait up 1618 right so it's basically more than at least two times slower to use graphics proxy widgets in just the basic example I was showing so think about like you are doing text in the widget you are doing stuff like that right it will be even slower so please please please don't use qgraphics proxy widget if you don't have a good reason for it a very good reason actually

1:15:26
Locuteur

some

1:15:28
Présentateur

ninja tips and tricks use set flags with s

1:15:36
Locuteur

with

1:15:37
Présentateur

like and using flags and the or and the binary operator right for let's say flag one or flag two or flag three and or whatever

1:15:46
Locuteur

rather

1:15:46
Présentateur

than many set flag like set flag flag one true set flag flag two true

1:15:53
Locuteur

why

1:15:54
Présentateur

you why because first

1:16:00
Locuteur

whenever

1:16:00
Présentateur

you change a flag it it will go to the notification system of graphics item which will call the item change virtual function right so that you can react to the flag changes

1:16:11
Locuteur

so

1:16:12
Présentateur

you get many times call to item change so you don't want to do that actually sometimes like really what's the point you better have one call with all the flag changes and then you can do your stuff anyway also some flags

1:16:24
Locuteur

need

1:16:25
Présentateur

to update states internally for the graphics item let's say you change the way items clip children to shape which means that if you set it to a parent then all the children will be clipped to the shape of the parent

1:16:41
Locuteur

what

1:16:42
Présentateur

we do is on the children we say okay if you are out of the geometry of the item then we set an internal flag to say well then you don't need to be paint right pretty much I simplify the problem

1:16:55
Locuteur

so

1:16:55
Présentateur

we need to go sometimes through the hierarchy of items from the children to the parent and sometimes to the children from the parent to the children and so we need to go through the trees of parent and children and

1:17:07
Locuteur

you

1:17:07
Présentateur

want to do it one time right and so if you set flags with multiple flags we we could have done it one shot

1:17:22
Locuteur

so

1:17:23
Présentateur

use it want set flags with everything in one

1:17:27
Locuteur

if

1:17:28
Présentateur

you have like on my demo you remember I got this top level parent that was doing nothing right it was a QGraphics widget with no contents no paints nothing

1:17:36
Locuteur

I

1:17:37
Présentateur

should have set the flag item has no contents

1:17:40
Locuteur

I

1:17:41
Présentateur

didn't do because I wanted to keep it for the for this slide

1:17:44
Locuteur

so what

1:17:47
Présentateur

it means

1:17:48
Locuteur

if

1:17:48
Présentateur

you set that item has no contents it means that

1:17:52
Locuteur

in

1:17:52
Présentateur

the painting of graphic scene we won't set up the painter and call paint on the item because we know it has no contents it has nothing to draw

1:18:01
Locuteur

and

1:18:01
Présentateur

set up the painter with the opacity with the transformation and stuff like that

1:18:06
Locuteur

takes

1:18:07
Présentateur

a bit of time and calling a function also even though it's not if you know that you won't do anything on your paint event

1:18:16
Locuteur

so

1:18:17
Présentateur

if you just get a logical parent set item has no content to true it's a flag and then the painting will paint function won't be called

1:18:25
Locuteur

and

1:18:26
Présentateur

then you save some painter initializations item change so it's the notification thing I was explaining just before

1:18:38
Locuteur

calling

1:18:39
Présentateur

it is slow why it's because so you call item change with the changes that you have made on the item and qvariant is actually what you change on the item

1:18:58
Locuteur

so

1:18:58
Présentateur

for instance if you move the item you will get a notification saying oh the position has changed and here is the new position

1:19:06
Locuteur

and

1:19:07
Présentateur

we use qvariant so the appearing looks nice right you just have one function but it gives a qvariant as parameters you can pass everything it can be qpoints

1:19:15
Locuteur

if

1:19:16
Présentateur

the position has changed it can be real if it's the opacity that has changed and stuff like that right it's a nice API the problem is qvariant qvariant is not fast and we tried everything there is nothing we can do in q4 to make it faster

1:19:35
Locuteur

so

1:19:35
Présentateur

if we want to make it faster then we have to break the binary compatibility

1:19:39
Locuteur

at

1:19:40
Présentateur

least

1:19:41
Locuteur

so try

1:19:44
Présentateur

there is nothing I can change in q4 anyway so avoid to call it too much

1:19:49
Locuteur

try

1:19:50
Présentateur

to avoid to call it so

1:19:52
Locuteur

that's

1:19:52
Présentateur

why for set flags I recommend set flags because then you don't need to call it two times right you call it one time only so

1:20:00
Locuteur

be

1:20:01
Présentateur

careful of for instance there are some flags in graphics item that send the geometry changes

1:20:08
Locuteur

the

1:20:09
Présentateur

position changes and stuff like that

1:20:11
Locuteur

really be

1:20:13
Présentateur

careful when you set those flags

1:20:14
Locuteur

because

1:20:15
Présentateur

it will be slower really slow so sometimes it's better than you actually do a kind of listener you know and you basically react to I don't know let's say call to set pause or whatever and then by yourself actually listen to the changes that you want instead of calling item change

1:20:36
Locuteur

so

1:20:36
Présentateur

kind of action listener or a bit like on Java you know you listen to item and then you actually trigger by yourself the changes instead of going through the item change it's a bit unfortunate but that's how it is and there is nothing you can do for now I think that's all for the tips and tricks and presentation of Graphics View so now the lessons learned that

1:20:59
Locuteur

what

1:20:59
Présentateur

we learned when we actually did Graphics View because Graphics View has a canvas like it is now it's almost done like the core feature of Graphics View is pretty much done right you get an item you get a scene a view you can do transforms and so on features wise it's almost done

1:21:17
Locuteur

perhaps

1:21:18
Présentateur

we can use the subtree caching but I don't think it's like a proper subtree caching but I don't think it's worth the price to implement it actually

1:21:26
Locuteur

so

1:21:29
Présentateur

it's a good framework it can run fast on the devices right I mean Migo

1:21:34
Locuteur

Migo

1:21:35
Présentateur

Touch

1:21:36
Locuteur

Orbit

1:21:36
Présentateur

or the UI extension for CIMEN4 they are using it right and they will ship devices with it so you can do really nice things with Graphics View

1:21:47
Locuteur

but

1:21:47
Présentateur

it's not perfect and

1:21:50
Locuteur

what

1:21:51
Présentateur

we notice is like what people do in the pane functions influence a lot the performance what you do inside it's like matters a lot

1:22:01
Locuteur

it's

1:22:01
Présentateur

not very graphic card friendly because most of the work that we do is software sites clip pass calculation

1:22:09
Locuteur

and

1:22:11
Présentateur

like part of the transformation has to be done in CPU but some of them could be done in the graphic cards the effects

1:22:18
Locuteur

they

1:22:19
Présentateur

work fine on the device some of them work fine on the desktop but it's really fast slow effects we failed delivering fast graphics effects

1:22:34
Locuteur

making

1:22:34
Présentateur

QWidgets works in the canvas

1:22:37
Locuteur

it

1:22:38
Présentateur

helps many people but it opened a Pandora box and with a lot of bug reports and people trying to embed widgets inside the graphics view and expect it to work perfectly well in theory you could but the way the two frameworks works is too hard to make them communicate properly

1:22:58
Locuteur

also

1:22:59
Présentateur

what we learned is

1:23:01
Locuteur

the

1:23:01
Présentateur

expensive calculations for instance when you get the paint function then you can ask the exposed rate of the item like the dirty areas pretty much right

1:23:13
Locuteur

so that

1:23:14
Présentateur

was a bad idea to actually always trying to compute this exposed right because in many cases what you see in users code they don't use it some some

1:23:22
Locuteur

of

1:23:22
Présentateur

them do only sometimes some items in the scene actually use this exposed right for instance

1:23:29
Locuteur

but

1:23:29
Présentateur

all the others don't

1:23:31
Locuteur

and

1:23:32
Présentateur

what we learn actually is always calculating those things for instance always even though people don't use it is stupid we should make the expensive calculations like for instance the exposed right on demand so if you really need it then we calculate it it's slow but you ask for slowness kind of right

1:23:50
Locuteur

so we

1:23:53
Présentateur

change the behavior when we could it's a bit bad but that's that sometimes you have to do compromise and but it's one of the examples and there is I can't think of more but but yeah expensive calculation only on demand graphics item it's a pure virtual class right you need to implement at least bonding right and paint I think that was a bad idea to put it pure virtual we got a lot of problems that I mean it's mostly because of C++ right like when we actually catch the deletion of an item it's when it actually enter in the graphics item destructor right

1:24:35
Locuteur

because

1:24:35
Présentateur

you you have a subclass of graphics item it's your destructor that will be cool but the framework don't know yet that the item is about to die right

1:24:45
Locuteur

at

1:24:46
Présentateur

least when it's not a Q object and

1:24:50
Locuteur

so

1:24:50
Présentateur

when we know that the item is about to like it's being deleted is when we enter in the graphics item destructor but then it's too late to get the bonding right

1:25:00
Locuteur

because

1:25:01
Présentateur

like because of C++ you can't call the virtual method right

1:25:04
Locuteur

on

1:25:05
Présentateur

the graphics item level so

1:25:09
Locuteur

stuff

1:25:09
Présentateur

like that we have to add work counts in the index and so on because we don't know the geometry anymore and stuff like that so

1:25:18
Locuteur

I

1:25:18
Présentateur

think at the end it should have been pure virtual just normal geometry 0 0 0 like graphics widget and a paint that does nothing also multiple views

1:25:31
Locuteur

I've

1:25:31
Présentateur

seen some people using it you know but it makes the code really complex and optimization hard

1:25:39
Locuteur

but

1:25:39
Présentateur

at the end I think it's a nice feature and so

1:25:44
Locuteur

the

1:25:44
Présentateur

way it's implemented now I think it could have been better now it's like we can still improve it a bit but not that much actually I think we're pretty much done about optimization in graphic view it's not the common use case the multiple views so now it's like

1:26:04
Locuteur

how

1:26:05
Présentateur

we could have it easier to add another of it and support the default one view and somehow allows people to have different views I don't know by letting access easily I mean perhaps to let people access to the actual rendered content of the scene so they can actually grab a part of the scene and see it I don't know like exposing the surface of the scene or something like that but to improve the way it's implemented today

1:26:37
Locuteur

now

1:26:37
Présentateur

how we can make a better usage of the graphic card

1:26:40
Locuteur

well

1:26:41
Présentateur

I won't answer to that because now we'll do it I think it's tomorrow you better want to attend it's basically how you can write efficient paint method

1:26:53
Locuteur

could

1:26:54
Présentateur

we improve graphics view without breaking the API

1:26:56
Locuteur

I

1:26:57
Présentateur

don't think we can at least in the binary and source compatibility way nah

1:27:01
Locuteur

it

1:27:02
Présentateur

has to be like that for now

1:27:04
Locuteur

could

1:27:04
Présentateur

we have a high performance canvas in Q4 I think we can and I think the answer we given in the scene graph that was before this afternoon but for people that didn't go to that talk you can still download the videos when they will be available

1:27:18
Locuteur

I

1:27:21
Présentateur

would like to thanks everyone for coming and now you can throw questions to me and I try to do my best to answer

1:27:27
Locuteur

thank

1:27:28
Présentateur

you

1:27:28
Locuteur

any

1:27:44
Présentateur

questions

1:27:55
Locuteur non identifié

when you were explaining about the cache modes

1:27:57
Locuteur

and

1:27:58
Locuteur non identifié

especially about the trick you did to simulate the sub tree cache how do you define

1:28:07
Locuteur

when

1:28:08
Locuteur non identifié

the sub tree will be repainted or not is this something that is inside the

1:28:17
Locuteur

I

1:28:17
Locuteur non identifié

mean the plumbing of the effect thing

1:28:19
Locuteur

yeah

1:28:20
Présentateur

it's like the invalidating the big sub tree pixmap that you get from using the caching effect trick

1:28:28
Locuteur

you

1:28:28
Présentateur

don't need to care about invalidating it graphics does it for you

1:28:32
Locuteur

ok

1:28:33
Locuteur non identifié

so neither can you for instance move it to device coordinate cache or something similar to that

1:28:40
Locuteur

yeah

1:28:41
Présentateur

I mean it's like

1:28:42
Locuteur non identifié

it's a trick right

1:28:43
Présentateur

yeah it's a trick I actually it would be nice to have a support for a third cache now is it worth to spend the price to actually develop it and make it works really nice I don't know that's some people it's not perfect but it will help many people like in my case yeah I've seen some people using as well this trick so

1:29:15
Locuteur

any

1:29:16
Présentateur

other questions

1:29:18
Locuteur

wow

1:29:18
Présentateur

come on you have questions I had like I thought I would have a lot of questions so

1:29:31
Locuteur

hi

1:29:32
Locuteur non identifié

I was wondering

1:29:33
Locuteur

I

1:29:33
Locuteur non identifié

may not have understood this properly but when you draw the canvas I mean the graphics view and there's a lot of children items there's a first research of

1:29:45
Locuteur

all

1:29:46
Locuteur non identifié

the sub graphs or the sub trees

1:29:48
Présentateur

yeah top

1:29:49
Locuteur

levels

1:29:49
Locuteur non identifié

okay the top levels so what if you have

1:29:52
Locuteur

a

1:29:53
Locuteur non identifié

view in which you have for example one top level opacity for everything that's under it does this mean that

1:30:00
Locuteur

everything

1:30:01
Locuteur non identifié

will always be redrawn or is

1:30:03
Locuteur

like

1:30:04
Présentateur

you mean let's say you have

1:30:11
Locuteur non identifié

any number but

1:30:13
Présentateur

no no no it's like no no because like we we discard like on the subtree if we don't need to read because let's say for instance you get a parent and then clips the children and then there is a far away right it's it's possible in graphics view

1:30:26
Locuteur

this

1:30:26
Présentateur

one

1:30:28
Locuteur

will

1:30:29
Présentateur

never paint it

1:30:29
Locuteur

will

1:30:30
Présentateur

never paint it right it will be discarded so what we get from the index is only a list of top level not the complete subtree right it's then after that we recursively go to that subtree

1:30:41
Locuteur

and

1:30:41
Présentateur

then we discard the one that we don't need

1:30:44
Locuteur

thank

1:30:45
Présentateur

you

1:30:45
Locuteur

and

1:30:46
Présentateur

also opacity for instance if you have an opacity zero what we discard the guy right don't need to paint it

1:30:59
Locuteur

hi with

1:31:01
Locuteur non identifié

the Q graphics effect classes

1:31:03
Locuteur

for

1:31:04
Locuteur non identifié

example I've noticed the drop shadow effect is sometimes slow if you apply a drop shadow to a complete hierarchy of items is it possible to

1:31:13
Locuteur

get

1:31:13
Locuteur non identifié

the source image only for the top level item which may for example bound all of the entire subtree

1:31:19
Locuteur

or

1:31:19
Locuteur non identifié

does always get the source no

1:31:21
Locuteur

you always

1:31:22
Présentateur

get the sub trees complete complete subtree there's

1:31:28
Locuteur

no way

1:31:28
Présentateur

you can ask the the no there is no way you can actually ask for

1:31:36
Locuteur non identifié

optimization to have an extra boolean in there yeah

1:31:38
Locuteur

that's

1:31:39
Présentateur

actually a good idea and yeah I've already done actually could you please remind where we can find the copy of this presentation the what copy of this presentation I think the marketing people will send the presentation as well as the demos and everything I can't answer to be honest you can ask one of them when you see them

1:32:08
Locuteur

I

1:32:09
Présentateur

don't know there will be they will be available

1:32:13
Locuteur

you

1:32:13
Présentateur

will get them so

1:32:20
Locuteur

hi

1:32:20
Locuteur non identifié

we've heard a lot of tips for animated scenes

1:32:24
Locuteur

in

1:32:25
Locuteur non identifié

our projects we mostly have

1:32:28
Locuteur

static

1:32:28
Locuteur non identifié

scenes but there's a lot of activity in the views like zooming

1:32:32
Locuteur

moving

1:32:33
Locuteur non identifié

around do you have any tips for that

1:32:37
Présentateur

actually zooming is the worst case of graphics views as soon as you scale is not very friendly to be honest it's one of the weak point of graphics view

1:32:47
Locuteur

actually when

1:32:50
Présentateur

you actually scale the view I don't see really good trick like this

1:32:56
Locuteur

except

1:32:57
Présentateur

rendering into Pixmap the scene and then scale it by yourself but then you will get bad quality otherwise I would recommend to you the cache mode but that's one of the flows we have like the transformations is not fast

1:33:14
Locuteur

but

1:33:15
Présentateur

perhaps like if we sit down together we can probably try to find something

1:33:18
Locuteur

yeah

1:33:22
Locuteur non identifié

hi I'm really looking for comparison with

1:33:27
Locuteur

just

1:33:28
Locuteur non identifié

using QWidget as a framework and QGraphics view I mean

1:33:31
Locuteur

you

1:33:32
Locuteur non identifié

spoke about using QWidget within Graphics view

1:33:34
Locuteur

but

1:33:35
Locuteur non identifié

is there some kind of comparison like you use QWidget lonely does it perform worse or better with the same use case

1:33:46
Locuteur

it

1:33:47
Présentateur

depends actually Graphics view has its own use cases right I mean if you throw like a thousand widgets into a UI it would be slow Graphics view will work a bit better

1:33:58
Locuteur

so

1:33:59
Présentateur

stuff like that and I mean Graphics view you have to see it as a canvas where you yeah as a canvas right QWidget is yeah it's mostly like I mean UI right UI bits like buttons and so on so

1:34:15
Locuteur

I

1:34:16
Présentateur

would say Graphics view will perform sometimes better than widgets but I've been shown that sometimes it's not true actually yesterday someone actually showed me an app on the mobile phone and they told me that QWidget was faster than Graphics view for their use cases

1:34:31
Locuteur

so

1:34:32
Présentateur

really it depends

1:34:33
Locuteur

but

1:34:34
Présentateur

I agree that it's not easy to

1:34:37
Locuteur

when

1:34:37
Présentateur

you have to a new app you have to choose right you cannot afford to develop both versions right so

1:34:45
Locuteur

me

1:34:45
Présentateur

to be honest I I would go always for Graphics view but that's my own advice I mean I develop mobile apps in my spare time and I do it on Graphics view and if it's slow I fix Graphics view because I can do it so

1:35:01
Locuteur

I

1:35:01
Présentateur

do my best to fix it actually because

1:35:04
Locuteur

I

1:35:08
Présentateur

when I was doing that I fixed a lot of bugs and a lot of performance issues but Graphics view is not perfect I think we can come up with something better

1:35:24
Locuteur

no

1:35:24
Présentateur

one

1:35:27
Locuteur

yeah

1:35:28
Locuteur non identifié

I was

1:35:28
Locuteur

at

1:35:29
Locuteur non identifié

the scene graph presentation earlier and that was quite interesting but

1:35:32
Locuteur

I'm

1:35:33
Locuteur non identifié

wondering in the future say you have an app that's based on Graphics view

1:35:38
Locuteur

and

1:35:38
Locuteur non identifié

you want to have the optimizations from scene graph how can you migrate that to

1:35:44
Locuteur

scene graph

1:35:45
Locuteur non identifié

without I mean will you have to write the whole app again in

1:35:49
Locuteur

for

1:35:50
Présentateur

now I don't have an answer but I agree with you that's a migration path that we need to solve that's something that we should provide a proper migration path and the less painful with less pain as possible right

1:36:02
Locuteur

so

1:36:02
Présentateur

either by providing some kind of I don't want to say but like a kind of proxy widget but for the thing graph right but but yeah something we need to find a migration path for now I don't have the answer but I agree with you that it would be a problem and this is using my hat and say well we have lot of code as well on top of Q graphics view and we need to find a solution for that so yes I'll fight for migration that's that's it thanks everyone

1:36:37
Locuteur non identifié

one more question

1:36:39
Locuteur

I have

1:36:44
Locuteur non identifié

a question about the maximum number of items in a graphics scene

1:36:52
Locuteur

I

1:36:53
Présentateur

can't answer actually like ship demos has thousands and thousands items and it works fine

1:36:59
Locuteur

I

1:37:00
Présentateur

can't keep a number it depends what you do in the items depends the complexity of the items depends many parameters

1:37:07
Locuteur

in

1:37:08
Présentateur

theory it should be unlimited right but we know that it is not but I don't know it depends really what you do in the scene if you animate the scene if it's a static scene if the items are complex to draw or if it's just rectangles that you move around if it's just drawing pixel you can do a lot of them but if it's like drawing text then it will be slower right so it really depends the content it's a generalist framework we don't say oh it can handle like two millions items and it will be fine no we can't it's too complex and actually none of the canvas out there can actually say a number of items they can know depends what you do in the items

1:37:57
Locuteur non identifié

everybody enjoyed the