 Alright, good afternoon and happy Friday to everyone around a few windows pause the previews How's it going to see Grover and Paul Culler and DJ Devon all over on the discord coffee time indeed. I've got My cup of right here Go and iced this afternoon. Let's see this one Background stop This way over the green screen a couple of pixels. No biggie Okay, up. Just not right. There we go. All right Good afternoon to everybody This is The deep dive live stream program. My name is Tim. I go by foamy guy on github and discord This is a weekly live stream program called the deep dive where we are working on things circuit python related Sometimes it will be in the circuit python core. Sometimes it will be the libraries or the infrastructure or other projects you know Related in some way to circuit python but That is kind of the common thread that does tie everything together is the fact that we're always working on something to do With circuit python if you are new to this if you've not watched this stream before you don't know what I'm talking about this website, which is actually Python org Is the main website for the project and you can head there if you want to learn some more about it Basically though, this is a version of Python that runs on tiny computers called microcontrollers There's a bunch of pictures over those over here on the downloads page All these devices can run circuit python, which means that when you plug them into your computer They will show up just like a small thumb drive with a couple of megs worth of space On that thumb drive. There will be a python code file. You can open that file with a text editor Write python code into it and then save it and when you save it the device will automatically Reset itself and run the latest version of that code. So that's kind of the central concept of circuit python is Connecting these devices to your computer They show up as a thumb drive and you're able to quickly iterate through different variations of your code by just writing code into that text file and saving it So like I said, if you do want to learn more circuit python org is a good place to go also Encourage you to join us over on the discord, which is linked down below ADA fru.it slash discord There's a circuit python dev channel There's also a help with circuit python channel as well as many other Channels that are outside the context of circuit python if there is something else that interests you So head there and check out all of those things circuit python is an open source project Anybody's allowed to use it on their own devices Anybody's allowed to port it to their own microcontrollers to add support to whatever microcontroller. They want for circuit python You don't have to pay to do this And the project is all Primarily funded by this company ADA fruit. This is their website ADA fruit comm Aida fruit is a hardware and software company based out of New York and they design and manufacturer many different You know PCB devices many different breakout devices with different things connected to it as well as some of the microcontrollers themselves Many of the devices that run circuit python are Aida fruit designed and manufactured hardware although lots of them are also third-party So if you want to help support the circuit python project one of the ways You can do that is just heading over to aida fruit comm Purchase some hardware from there and by doing so you're helping You know keep circuit python running because you buy hardware from them that keeps money going into the aida fruit factory So that they can keep doing their own things And that's where they are getting the money to pay the folks who are working on circuit python So you are pretty directly helping out if you just head there and purchase Yourself some toys so thanks to everyone who does that and thanks of course to aida fruit for paying myself and all the other folks who work on the project regularly so Today what I would like to get into is a little bug that I saw pop up in the issues the other day And I am a bit of a sucker for a good display. I owe bugs So I could not I could not resist wanting to jump in and try to Understand what's going on with this one? Well, let's see miss the stream yesterday and it kind of mess with me. Oh, no Yeah, I did stream a bit last night, but I was on on my own channel just doing my own thing. I was working on The Neopixel API bit last night got some more of the animation stuff going Yeah, so I was on last night, but over on my own channel Speaking of my own channel I I'm glad you mentioned that actually because I do want to mention Ordinarily I will stream also on Saturday morning. So so right now. It's Friday afternoon in my time zone Obviously wherever you're at it might be a different time of day So it's Friday afternoon in my time zone. Typically. I also stream on Saturday mornings But I will not be streaming tomorrow morning. I've got other plans tomorrow. I'm actually going to a concert So I'll be in the car headed There at the time that I would ordinarily be streaming so no stream for filming guy tomorrow But I should be back at the normal time 10 a.m. Central time on Saturdays starting next week I should be back. I will probably hop on at some point either Sunday or Monday For the day off, but I have no idea when and I'm not necessarily gonna like commit to it for certain It'll just be the kind of thing where one of those days When I sit down to mess with them stuff some stuff I may I may pop it on so You deserve it off. Thanks. Yeah Okay, but yeah, no no scheduled one this weekend for the foamy guy stream on Saturday So just keep that in mind if you are looking around tomorrow morning being like where's the foamy guy stream? Not going on for the day. Sorry This is an interesting bug that I saw popped up. So this person has uh, created a bunch of shapes using the display shapes library and They are saying that when the shapes are hidden hidden equals true, which is a concept for groups and tile grids as well as Vector IO shapes question mark. I'm I'm not sure about the last one at all vector IO shapes You can put them into a group that's hidden. They they might not have a hidden directly on themselves actually But in this case, it's not vector IO shapes in this case. It's ater for display shapes Which is the library this one makes bitmap shapes essentially whereas vector IO is different module inside the core It's not making bitmaps So they've basically made a bunch of these shapes and they've set a bunch of them to be hidden and it seems that that is causing The device to run really really slowly So the first thing we're gonna try to do is just replicate this because we can't really learn too much about it without replicating it I'm not just gonna copy paste the code though because I Don't have the exact same setup that this person does. I don't have the exact same excuse me the exact same display Or the exact same main device So and then the other thing I will say is the code uses a lot of capital letters for variables and things and and no spaces and Things there's syntactically. There's some stuff. That's just different from the way that I normally write my code that Makes me want to kind of rewrite this and hopefully Make our own version of the reproducer rather than having to copy paste this one It does strike me as very very odd that hidden true would make it run any slower Could be told I would kind of like off the top of my head I would expect hidden true to either have no effect on the speed Or make it faster Those are kind of the two Things off the top of my head that I would kind of have expected But it seems that the real behavior is a third thing which is that it is actually getting slower So they tested on a pico w and a teensie for I believe it said there pico w in C4 I am not gonna be testing on either of those what I have loaded up is a good ol trusty feather TFT we'll start with that obviously feather tft is Not the same port as the raspberry pi pico w or The teensie for so if we are unable to recreate it on that port then we may Go try pico w or something else. This looks different to me for some reason RSTP I don't feel like it normally has that maybe it updated or something normal concerts are a thing again. Yes A lot of shoddy text. It is indeed a lot of shoddy text You go to be I can believe but the teensie for should shred through most stuff. Yeah Yeah, and I mean in particular the the specific thing that's going on that the hidden attribute really should not Like I would not have thought that it made much any difference truthfully. Okay, this is a copy paste. This is a party parrot web server this is a learn guide where I submitted a fix for the latest version of HTTP server library so what we need is just a basic regular role setup We are gonna want to import these things We're gonna want to import board. We're gonna want to import display. Oh We're gonna go display is equal to board dot shoddy display We're gonna go main group Main group equals a new group Might as well from display. Oh import We knew we might not need tile grids. We need a group for sure Oh, we need actually so let's try that we make a group We want to make some shapes for now. I'm just gonna make one shape just to like make sure it's actually working In their case they are doing what they are making the shape Appending it to a list And then appending it from the list into the group Same thing for lines. They did some rectangles this way then they did some lines this way as well They append it to the group. I mean the the list Then they're setting hidden true On each one Then they are appending each one Through the group. So one thing is we have a list holding all of our What I'm just going to call like display objects Their shapes in this case rectangles and lines. We have a list holding all of those We also then have a group holding all of those two which a group pretty much is a list So for one thing we do have kind of duplicated Data here in a way, right? We don't you you could just use the group by itself. You don't necessarily need another list Um But this is also I think a smaller portion of their program Maybe there's like other reasons why they wanted to have that into a list Then they go and say display show The content they're calling refresh Because they're setting auto refresh to false Oh Okay, for one thing they are calling refresh Inside of this loop, which I would expect to probably be pretty slow because that's gonna be calling Refresh 70 times Hmm I wonder if that's part of it Is this like if you took this refresh back to here So that it happens after the for loop Then it would Make all 70 changes refresh once and show all of them Interesting. Okay, let's draw one thing to start with and just get it so we can see it And they were saying it took on the order of minutes. I believe right commenting out the hide One pass of the while loop at the end then takes 0.75 seconds That's somewhere Had mentioned how long it took Takes four minutes they say and it takes four minutes four minutes down to less than a second When the things are not hidden Is our display 240 I forget off the top of my 240 by 135 in our case Setting it to white for now. It's going to be four pixels tall Go to the main group We while true Pass it All right, there's our first rectangle there the white one on the top The amount of stuff that they have created is how many 70 rectangles and 150 lines I have auto refresh currently turned to true though Can calculating If hidden cost that much time if refresh is called each change. I don't know. I mean, I would not expect so But I mean something's going on not very confident. Oh, yeah. I mean that's nothing to be sorry for That's running really really fast Obviously, we only have one thing and and actually at this point We don't even have our one thing because we have not called refresh now. I took auto refresh off um Got a refresh off. So now it doesn't ever actually get refreshed So then maybe we could go in here and go display to refresh Still very very very fast and now it does actually draw our white rectangle. Okay, so We're looking for 70 of those and 150 lines 70 I have 135 pixels Only so if I make 70, they're not actually gonna fit on the screen At four pixels or even at two pixels Maybe we should do them the other way The one thing we actually want this at zero zero and then we want let's say width What's uh 240 over Four pixels how much is that? That's not enough And it would be 80 for three pixels. It should be enough actually so we'll go width of three We will go height of Let's just say like display Height over two Okay, so now we have a vertical line And are they changing colors? And they're creating them or doing all the same color. They're doing all the same color when they create them But they're changing colors inside of the Loop here and they're calling refresh before they Know after they change the color, but before they Increment After they change the color on the display object, but before they alter the color for next iteration They started on white But in our case we'd be doing something like r dot Still okay now that is changing colors a bunch Going all crazy on us and it's slower than it was before Uh, I think anecdotally just looking at these numbers scroll past us here, but it's still obviously very very fast But we also only have one thing So let's make 60 70 of those range 70 of those and I'm sure the exact numbers don't matter But I do want to hit roughly the same amount of like scale so Might as well go with the exact number Uh, I will let's see. We're gonna be doing that. I'm gonna skip the list I guess we'll go back and maybe add the list if it We don't see the issue occur then maybe we'll start trying to match their code more, but So this is gonna be i times three That's gonna make them 70 across Gonna append it to there and then we don't want to be doing r anymore. So instead what we'll do is maybe like for I'll say display object in main group display object fill equals And like it's still going pretty fast to me and then We have I've certainly slowed down some I feel like we're seeing the next seconds digit there Come in a bit quicker than we were before But still obviously very fast. So let's now try r dot hidden equals through If this is affecting us already yet or not We'll go in pretty fast Seems pretty fast and what does Maybe let's do something like if I Every other one hidden. I think that would probably It's kind of a neat effect 70 of those were not really running into the same thing to keep pushing it closer and their example they Are adding the lines they're creating these lines and adding them But the things that they're changing the color on is only Only the rectangles not the lines We want to make 150 lines I'm just gonna come at those for now so that we go back to fully visible Hope x0 They've actually just hard coded But it's always in the exact same place In the line to the guy way slower. I'll give it that it's way slower Now we're getting about one refresh every two seconds or so So it is without a doubt way slower this Is there detection logic in display? I oh yeah, uh a bit like Which group at this pixel I can remember But some get the long-term issue Group at this pixel I don't think so As far as I'm aware you There's nothing inside core display. I oh where you can give it a pixel coordinate like an x y and then it will tell you Which groups occupy that pixel? I don't think that Is the thing that exists that I'm aware of see the thing about it is inside the core The group does not have width or height. It doesn't have size It has an x y to represent its top left corner So the x y of main group is in the top left corner up here But the core does not know the width or the height of that group. It doesn't have those concepts of size so The core by itself can't really tell you The rectangle that a group occupies the only thing that you could do is iterate through Every child object inside the group and then calculate its bounding box by trying to look at its x and y and width and height but Groups can go inside of groups So you also you have to do this recursively because you need to like Go inside of subgroups and find all those things um And then for a thing like line, it's not going to have a height or a width So your code would also have to calculate Based on x zero y zero x one y one it would have to calculate the width and height so Through the best of my knowledge that that functionality is not there Or it can tell you like which group occupies a given pixel And then is it tile grids with x y To relative to groups, uh, the tile grids x y is relative to the group that contains it that part's true. I'm pretty sure Get tile grid visible on top at this pixel Uh, I don't recall seeing a function like that ever it could very well be in there, but oh, that's interesting We got one weird line there Ah If we got like a garbage collect in the middle there Um, yeah that that function doesn't ring a bell for me, but that does not mean that it doesn't exist for certain It very well could be there Uh, so yeah, let's save this with that true and see if we slow down considerably more here Indeed we do What's fascinating is that we uh We went through twice Then we got stuck And we went through two more times That is weird. So Now we're getting two in a row really really fast Got another one of those extra vertical lines of a different color there a second ago We get two really really fast, but then we do have a very very long pause Before we get the next one But it's I well very I say very very long. I mean it's 14 seconds Compared to only Like about two seconds With them visible Yeah, for one thing we don't get two at a time when they're like this Well, you get one at a time and the one that we get is pretty much every two seconds So we go from one successful refresh every two seconds while they are visible to Two refreshes every like 14 seconds and the two of them come pow pow rapid fire, but then You have another 14 seconds Interesting, let's Tinker with this a bit. What if we had a line group is equal to another different group? And then we said we wanted to put these in the line group Then we will of course want to go main group that append the In group That's gonna put it before all the rectangles I don't know that it matters, but I think I want it after the rectangles. I'm gonna do that That's gonna then fill it with lines. We're back to hidden not true So I would assume this is the same Here we should get the same thing. So about once every two seconds Line group right right right because now we have a group inside there Uh if Is instance or Has adder has adder display object Fill signal magic the clarification. Yeah for sure Okay, yeah, so we do get basically the same thing here one refresh every two seconds Which is what I expected because we haven't really the only thing we changed is just put that in a different group Not expecting that to make any difference Now what I am curious though, and I do not have a good guess for is when we say line group dot hidden like this Is that gonna slow way down again? Yes And we get back to our two Refreshes pretty interesting Uh, okay. Oh while it's in that 14 second, uh, wait, you can't actually control c very effectively either One thing I will say I mean it it will depend I guess on what you are trying to do One thing I will say though so far we're drawing basic shapes And we're using data for shapes library, which means that we're ending up with a bitmap for every single one of our shapes A slightly different approach could be make one bitmap That's the exact size of the screen and then use bitmap tools in order to draw things into that bitmap The difference would be we don't end up having individual objects that represent every one of our shapes But visually we could draw all the same stuff by Putting all of it inside one bitmap Using bitmap tools. I think there's a function called maybe draw rect or something maybe fill rect And then I'm pretty sure there's a line function as well inside bitmap tools So like visually You could achieve the same thing as this by doing that and I suspect you would not run into the same kind of issue However, you also don't have objects to call hidden on so like you can't Hide and unhide things that you draw this way. Yeah, there's a draw line And then there's a draw polygon, which you could do for a rectangle Oh fill region is pretty much draw rectangle. I think as well actually That's one thing to consider as well, but for all I know maybe they chose this example just To illustrate this specific thing with hidden which again, like I said, you would not be able to do with uh With bitmap tools since you wouldn't have individual objects. Let's try every other one here Do we slow down to seven seconds if we do this? Okay, so we got Two about one second apart Then we're in a big weight Actually, it's feeling like it's longer than 14 seconds Yeah, maybe we found one of those full minute ones here. Were they setting all of them? Commenting out this line solves the lag issue. Oh, yeah, we've made it last way way longer now Oh Yeah, and because it's stuck I can't control c either Oh, there it goes I was trying to see what it would do if I dropped it down to only two And then made one of them hidden That seems like it didn't really have an adverse effect on the speed But definitely relies on there being a lot this time we kept the Two quick hits And then delay but obviously our delay is much less More like one second, which is one tenth of about what we were getting before at 150 So that feels linear pretty close. I think Guestimation wise We had 150 there. We were getting about 14 seconds. We have 10 here now. We're getting about one second Very unscientifically measured and again same thing here We don't make them hidden then we go back to fast Okay Let's test a few more things before we jump in jump into the core I'm gonna turn just I'm gonna turn auto refresh off I am gonna not refresh here And put this back to 150 So we're getting kind of like weird or looking stuff here because it's refreshing at different intervals When more or less stuff has happened Let's make it a bit difficult to follow like when anything is happening We are super fast if we don't call refresh So now we are back to about our one refresh for two seconds And you know one thing we still have yet to do so I'm doing my refresh out here Currently what if we did it in here, which is more like how the other one was That hasn't gone st. Over on youtube evening um Display to refresh that right Put this out when it's still about one every two seconds not making that big of a difference You know what the name for the board is called. I'm not sure if it's called perforated board five millimeter holes or protoboard I've been searching and searching you came across my channel um I have heard of a thing called protoboard. I have also heard of a thing called perf board Um truth be told I'm probably not the best person person to know The like specific actual definition of either of them This is at least what Adafruit sells as universal perf board I don't know the measurements if that's five millimeters or what you'd have to look a little more into here um There are like proto breadboards. So these have breadboard sizing, but it's actually a PCB instead of a plastic thing Um That's about all I know about it truthfully. I don't really know the the actual specific definitions So this one is very slow We are back to another very very slow one Because we have not even printed the first one of these yet. Okay So we know that And and this does feel slower even than the alternative like this It will but also we're even more stuck now because it's running That first one we're stuck in it. We can't control C or anything Like a flexible panel. Thanks for your help appreciate it. Oh, interesting. Yeah, I've never seen flexible Perf board that sounds Difficult because if you solder to it the solder joints will not be flexible So then if you flex the board afterwards, I would assume the solder would pop Off Sorry, I missed a couple of the I used round direct on feather wing I did Freaking complete snippets show the idea near not coming Perf board. Oh, sorry, though. That was that was probably loud in my bad Perf board is made to be easily cut into shapes. Oh, okay proto board is harder With copper fill can't really cut them There's a key there's a link there on the uh On the discord if you're interested I think over on youtube, there's a link in here for digikey for searching up some of that stuff So like proto board is like pcb Red board perf board doesn't have holes connected. Oh, that's a good one. Yeah, perf board like each hole is independent You kind of have to run those wires to make your connections whereas Yeah, the proto board some of them. They'll have like rows of pins connected on the copper Wow, there we finally got one, but it was uh 70 68 seconds Over a minute not the four minutes that the OP from the user, of course, I also only have Half of them hidden Okay I think we have seen enough to get started So for one thing I have got a modified version of this from when I was working on Uh Trying to do sd card initialization. So what I'm just going to do is throw that onto a branch Commit it Push it, but it doesn't matter truth be told I probably will not be picking this one back up the sd card Maybe one of these days, but For the actual project that I was intending to use it in I have come around to not wanting it to be Initialized in the core anymore I am making good progress on that that project as well. At some point I will try to distill the parts of it that I can share out and Publish a project based on it But the the specific one that it's actually doing is not something I can publish But it turns out that I want I don't want the sd card initialized inside the core because I want to be able to initialize it Read the file off of it update the display and then unmount it so that that way If we reset or if anything else happens, we don't have it initialized that way We won't get corrupt files and stuff Whereas if it's initialized inside the core, then it's like always initialized and mounted if anything goes wrong It could be like halfway through writing a file or something like that, which we wouldn't want um, so we want to go inside of Display refresh I'll start in shared bindings. My guess is we're going to want to be going into a shared module probably but Okay, we're fully in true auto refresh So there are also these things which I don't actually know the The real way to use these It's false immediately. That sounds like it might be helpful Target frames per second frames per second per second stuck in that last one I've never actually worked out Precisely how these uh to target frames and the minimum frame stuff works It does not seem like that's having really any effect on it though because we Again got our first couple this time. It's three instead of two which is interesting but we got our first couple and then still Get stuck in one that's just taken forever okay We're in here and we are Calling to common howl display or display refresh. So we want to go into there Why does that that's annoying? Okay, we want to find that that one's going to be over in shared module That's going to be where the actual business happens This stuff here is all validation of the argument things I don't really suspect nothing in there as long as double as needle point canvas And so your gpu to do 5 000 fps Let's try Yeah I mean like Conceptually I get what it is saying But like I've put different numbers in there and not Really figured out what the different behavior that's resulting from those numbers is I've tried putting different numbers in there and figuring out what it does differently and not like walked away really understanding anything at all that it I It as far as I can tell I get what it says it does. I just don't see like functionally Doesn't seem to me like it does that or really much of anything in the times that I have tried to use it But most likely I assume I'm passing the wrong Arguments essentially just not using it right. Okay, so common howl display refresh is here So first thing it says if not self auto refresh if and not first manual refresh and target millisecond frames per second is not equal to a large hex number guessing is that max int I don't know what that is for sure, but current time equals supervisor ticks That uh current millisecond since real refresh current time minus last Refresh time test to see if the real time is below our minimum. So here's I mean, this is the logic inside those things um Below so this one will raise an error actually interesting current millisecond since refresh greater than maximum Per real frame below minimum frame rate. So will this raise an exception if we have a minimum here We did eventually get these and it is Hmm 30 They're different actually well, we got 147 and then 149 Interesting we got or within the span of two seconds and the same thing up here If we go minimum We put that as two is it gonna raise exceptions on us Okay, we do have to wait because now it's stuck in there switch back to here following through this Every if you're in CPU is capable of hitting the target then it'll attempt to do that FPS I've done an overclocked the tft display to a little bit of a room on the m4 Yeah, m0s can't do much of anything on displays For samd 21s, I mean m0 they call the pico and m0 as well or m0 plus or something I think I've seen it which like pico is a different class than the uh md 21s in my mind Okay, so that one is Looking like it should raise I don't know. We didn't actually get an error raised And it's definitely taken longer than two seconds right like we told it here But we told it minimum frames per second and then we told it two. So that's actually one frame per One frame per one second Yeah, no minimum frames Per second. No, we told it two. So that's one frame per half second And it's definitely way slower than that and it's not raising Not raising so far. So yeah, I don't get I don't get what that This is my ignorance. I'm sure though not like I don't know how to how it works Don't a bust limit because we're not in the original reproducer Since I already don't understand them. I don't want to bring those into the mix But we could see here it would raise an exception in some case maybe If ms since last call so that's current time minus last refresh call Last refresh call then gets updated to current time Got set here Returns false. So there's the skipping in order to catch up. That's again, that's part of the logic of those two numbers Or this should return false I'm gonna leave that alone for now remaining time. We're still calculating stuff based on this We're ahead of time. So wait until we align with the frame rate I'm going to guess Go to expressive We want to Activate which is called what? um Dot space dot slash esp That's it. It's called export. That's what it is export Oh export activate Um now we can make Okay, all right. First of all, I don't know if I did this right But we'll find out and then I don't really expect to see this print anything. Mostly I'm confirming My hypothesis here, which is going to be that I don't think this is going to print anything While we are in these long wait periods here Basically, I don't think that we are Inside of this when we are waiting, but if we are this will tell us that will spam Uh while that's building we can continue on with the logic. So that's a like a while loop that's just waiting Then it says first manual refresh equals false. Then it says refresh display which is this Fixed a display object Nope called object is not a function or function print f I did it wrong I wish there was a good resource to go to to look at this I cannot for whatever reason this always eludes me the the way to print it's such a basic thing But I just do not remember It grep Is it not really I thought it was print f You know It is and and I think I got it right actually, but what We don't have a Rose not touched. I Could have done this before I started the stream. I forgot I updated the main branch, but I forgot to fetch sub modules my guess is that my local copy of Micro lab was different than the one that's in the main repo now. Like I guess it probably got updated Hopefully that's what's causing those errors Or be it's a dependent on display hurts. You get a little more herp of Yes Or be it with po to improve fps for neopixels Our pcs or as repies. Yeah Yeah That's definitely true. I just think it shouldn't We shouldn't be hitting the limit by making our thing hidden shouldn't slow down as much as it does From us making a thing hidden realistically hidden should make less work. Not more I would have thought might be like looping through the pixels for some reason Okay, now we got all that updated All right fingers crossed I should be doing clean also. Maybe I should have done clean a while ago. Honestly, that should have been one of the first things I tried In advance use your su. Let's use it Money for most projects Oh, yeah Yeah, display. That was good for like I mean, honestly, like if you're not trying to do motion if you're not trying to have a thing move necessarily if you're just trying to pull data from Whatever any kind of system ever and put it on the screen and update it every, you know, a few minutes or a few seconds or whatever Uh display. I was more than adequate for that But if you're trying to have like real time 3d animation spinning of 3d rendered sphere or something like Then it's a bit much or if you're trying to animate smoothly across the screen Like you could get by with one thing maybe animating pretty smooth But you start adding more than one thing animating or the thing that you're animating is too big And then you do start slowing down a fair fair trunk But this is even beyond what I have seen like Display is relatively slow, especially if you're changing a an object that's big but this is even slower than I In fact, you know, it'd be interesting to see is if we made these lines either straight vertical or straight horizontal If it slows down the same amount because Inside of here line, I'm pretty sure it's making a bitmap. And so in our case, it's going from zero zero To 100 100, which means our bitmap actually has to be 100 by 100 So we have 10 000 pixels in memory in order to only draw on The hypotenuse of the half of that Dang, I don't know. That's not 100, but it's like 100 and something. Okay, this did build. Let's run this Vector IO. Yeah, it would be interesting to try that as well. I'm curious if Vector IO like How that would interact with this little cork that we have found here Like if we changed our rectangles and our lines to Vector IO I wonder if we would still slow down the same rate or if it would be different or not at all Gotta tell it where But even if it doesn't slow down with Vector IO, I think we want to still chase this. So I'm not I'm not gonna go and Taste the the Vector IO part of it just yet Because even if it turns out that Vector IO is fast I think like this feels broken. This feels like there's something that That we should hopefully be able to fix internally to make this faster Even if there is a better way to do it, it'll be good. I think to make this way work as good as it can Which maybe it turns out that it is as good as it can in which case That's as good as it can then Vector IO would be a good Potential work around to try to make it faster, but It's at least worth a good Deep dive. Pardon the pun to take a look around and see if we can't figure out where we're losing the time Okay, so as expected this did not we're not seeing this print. So we're not stuck inside of there Which I thought was a long shot, but it's worth a quick test So we are then going inside of refresh display Here it says if not display IO display core start refresh Refresh on this bus is already in progress. Try the next display First thing I wonder how simply returning from here would make it try the next display But we're not worried about multi displays right now. So I'm not gonna I'm gonna think too much about that We have display IO area current area equals get refresh areas while current area is null refresh area Refresh area. So we're calling refresh area on each area Then we're saying current area equals area dot next. So we're looping over areas With some kind of linked list type thing here get refresh areas And then we're able to like get one out of it here pass it into this and then we update this With the next one. So it's like that node is pointing to the next one. We're grabbing that and pointing it to here And then it says display IO core finish refresh Let's add some prints to here. I should not have deleted that print Also worth noting I keep saying that I can't remember this but I have actually gotten it correct I think the last two times that I tried But even when I didn't think I had it correct I'm gonna take that there I'm gonna say here after Get refresh areas I'd be curious to see how many refresh areas there are as well like Is every object a refresh area? And who's responsible for making it so hidden things don't get an area That's probably Deeper inside here. I'm guessing so we'll do after this we'll do another one After these so after all of these after Wow Wow loop don't have semicolons on any of these And then we'll do one more after this to see after the finish after finish refresh Okay, make the build I gotta run to the restroom. So I'll be RB Hey, I've got a build bootloader Missed it asked Let's finish Got a semicolon I think that was from before well. It must be because we got a build must have been from Getting every 50 minutes from seven apis That works pretty good off display recently Okay and running so the period where we get stuck is after Get refresh areas and before After the while loop so we get We're getting stuck in that while loop In here. This is where our time black hole is at I don't think that's the right way Maybe it'll work anyway I don't know if you can do that I'm really bad about semicolons If I thought I was looking at our cleanup project Uh, that's not the right way to print a number You need to do this thing Then pass it After a comma But I don't know is percent o2x. Is that what we want? percent d I'm pretty sure that's actually what At line d. Yeah, maybe d for int. I think percent d comma i Yeah, thank you Get up. Mr. Good bits Oh, I did not go to bootloader first Not sure who the author of the project is so they might want to get in touch with those a w I just get up right away Yeah, well, I think it depends a little bit if the Like I don't know if the sample I suspect the sample they submitted is not like their literal project I think they made a reproducer It went really fast up until about 70 or so Now it is much slower But Fresh areas We have 150 Plus 70 we have 220 objects Because so I think we currently still have the line group. Is that true? um Well for slowdown, not sure That's a little bit too coincidental. I think that we exactly at 69 which were zero based so number 70 Also, the fast one stopped there for some reason Did not go to 220 like I had expected either Oh where it got the number from It's pretty random 144 But it definitely slows way down right at number 70 Which we have 70 rectangles So I presume it slows down after those If we make these rectangles also Yeah, that's a bit too That's a bit too coincidental. I'm curious if it's just lines. Are lines just slow? But I also am curious if we go back and put these in main group instead Let's do that first But then I'm gonna try making rectangles here 150 new rectangles and see if we still go slow Okay, we are in the uh, we can't reset while it's doing its thing. So I'm gonna push reset button Ordinarily I hesitate to do because then it disconnects and reconnects from my computer I think there's like a off chance that eventually sometimes my computer can crash from that Cross knock on wood. Hopefully that's not gonna be happening Okay, we still slow we we still slow right down at 70 So this makes me think that being inside of a different group does not matter Now we're back in the same group, but it does seem that lines are slow so far right now. It's looking like lines are slow So let's see if that's the case by changing these directs We'll just do r again Another set of these ones and it's making them all just layered right on top of each other So I'm just gonna do the same thing. I'm gonna say x equals zero. I'm gonna say y equals Let's just go down below the other one by a little bit display dot height over two But then just plus like I don't know five or something six. Maybe let's just do that with uh, let's go, um I don't know a hundred maybe height uh six Okay, one thing too though. This would be changing Does line have fill I actually know if well, it's not changing colors. So it must not line extends polygon polygon extends tile grid back to spend points The line is just making a special polygon It's just passing those two points right back in. We're giving it x zero y Zero x1 y1. It's just taking those two points passing them right into polygon Let's calculate the size Does not seem to have fill though. So those fills would not be doing anything um I'm gonna go back to using the line group actually so here. I'm gonna say line group dot append R. Even though it's not a line anymore. It's a rect so Yeah line group Not do hit and true That's going to be looping over main group. So only the rects that are in the main group will be having fill Line group is technically inside main group, but it won't have a fill and this is not recursive So it's not going to go inside of it Yeah, line is just slow for some reason Well, okay. Hold on though, right? Hold on. Hold on. Hold on. Fill R dot hidden I will say too like this would go way faster if we weren't printing either like if we went back and took out all these print statements again We would iterate through this even faster But this is way faster than what we were seeing With the lines. So yeah, something about the lines Just slows the refresh way down Honestly, I'm assuming it probably doesn't even matter if they're hidden or not They seem to slow down worse when it's hidden Probably slows down some even when they're not hidden compared to like what we're seeing here Um, okay next thing I want to try is what if our line was not diagonal? I think if our line is not diagonal, it might actually go faster. Okay, let's get this back to slow There we go. We get all the way up to the lines and then we slow way down Interestingly, I mean these seem to be taking about the same amount of time as each other Is a little bit weird because like hidden seems to slow it down, but We only hid half of them So I would kind of expect like one fast one and then one slow one and then one fast one and one slow one, but I'm not actually seeing that pattern either Okay, what if we go from 100 Zero 100 to 100 100. So we're making a fully horizontal line Instead of a diagonal When it's horizontal or vertical it could just use pixel fill and say yeah, I mean there's a but a lot of things could use other things instead for sure Definitely for sure. There's otherwise it could work instead But I'm trying to get at though is like what is the what is the thing that's causing it? That is way faster again. So definitely Using that Diagonal line is making it way worse than if it's a horizontal And then I would guess we go let's say like say like zero zero Zero 100 so vertical line Assuming we stay fast again. Yeah But it's definitely specifically that diagonal line Let's say as though I'm that surprised by because that diagonal line is about the least efficient Shape that you can get right because it it has to build an entire bitmap. That's a rectangle It has to build that 100 by 100 rectangle And then the only thing I could think of is we must be iterating through those pixels in there I guess it seems like we must be iterating those pixels That's kind of interesting. Oh, I see we're in the uh, I see right right right We're in the repel here, but I have uh because I've added all these prints and the display is now refreshing With auto refresh because we're in the repel Uh, this is now happening okay I kind of I wish I could like stop it for I could like can't even see what I'm doing. I don't know. It's not worth messing with Happening for now So refresh area. Let's keep chasing it. Cannot find. That's a good start. What is this? Fresh area. I don't know why it couldn't find it. It's in the same file, but whatever Uh, buffer size 100 I don't know what that 32 t's don't know what that means really Uh area clipped so creating a display area called clipped display area is an interesting one I'm pretty sure this is a core only concept. I don't think this concept shows up on the python side Clip The area to the display by overlapping the areas if there's no overlap then we're done Go in here say not clip Areas no overlap Done hypothesis here is that this is not where we are losing time Basically, I'm expecting to not see this get printed. I'm thinking I don't know what the clipped areas is doing truthfully Those per buffer pixels per word Pixels per buffer We could print those out. Maybe Sub rectangles equals one We're currently on the vertical. Let's change it back to the diagonal We don't see those getting printed. We're not having that Whatever that condition is we're not Not finding it. We're not getting it Having it not going in here. We're not printing this That's not factoring it or time at all I'm gonna print these out those per buffer d pixels per word pixels per word I have no idea what these values are pixels per word. I don't even I like I don't know what kind of word it's talking about oops pixels per buffer See if those are big maybe these are like way smaller for rectangles and way bigger for lines or something But for performance and memory Lines line is horizontal or vertical. It could use pixel fill instead Only with lines that aren't horizontal or vertical but a polygon would be necessary. Yeah, that's true. Yeah, you could do uh For either horizontal or vertical you could use rectangle instead essentially instead of line although I think it's the It's not the it's not Not by virtue of being a line object that's making it slow. It's by virtue of being a line object and being big like The diagonal which is making it a lot more pixels. I'm assuming the number of pixels is Is uh factoring into it Bootloader Because yeah, we did the horizontal and the vertical lines and those went way fast So Those are still line objects. So we know it's not just merely line objects are slow It is specifically those line objects that are using that diagonal In which case they're kind of like the least efficient of the line objects since they have to have a full Rectangle, but then they're only filling in, you know one pixel all the way Per row or whatever across the diagonal there Now those don't seem that different In fact, there were more pixels per buffer for the rectangles at 402 Then for the lines Are 202 The other two numbers appear to be the exact same I I just had a quick clients 202 changes, but it gets smaller. So that's interesting I'm gonna comment this one for now. Maybe we'll turn that back on but i'm not sure So then after that we say sub rectangles is a Uint number. I think this is a number equals one SH 1107 Boundary, so I don't we're not doing that. That's gonna be false for us. I'm pretty sure Uh, let's see the bird bird the word. It's the bird bird is the word Birdie birdie It's a combination of techniques for speeding up real-time digitizer proving from five to Five plus frames per second to 2.5. Do you think there? I have to squeeze out another 10 to 20 percent I'm pretty sure we're not going to be in there. I'm going to go in here and it's saying what display area size clipped greater than Buffer size times pixels per word. So that's going to be pretty big right buffer size Now we don't know buffer. Well buffer size actually is up here. So that's 128 Times pixels per word, which was the last one. Nope pixels per word was here. So that was a big That was a very big number 128 times that very big number If display i o area size Clipped greater than I don't know what that means Another bird bird bird's the word. So I'm going to print these values out Done this wrong. I've done this very wrong. Hold up. Hold Hold up. Hold up. We put percent d's here and then we never passed anything So those really big numbers probably were wrong I wow, I'm I don't need what where did where did those values even come from I don't even know what it was printing We're just like random memory. I guess I don't even know what that was. That's weird. Okay. I'm surprised that compiled honestly Okay, I gotta BRB again Discovered the power of micro lab A lot of stuff with that micro lab. That's definitely true But a number trenching goodness Okay, now we got some real numbers here much smaller and We start to get maybe a hint here because we actually do have a lot More now pixels per buffer we have More rows per buffer. We have the same pixels per word, but we have 10,000 more pixels per buffer Okay Maybe the overall size is important. Maybe the type of object is not important, but the overall size So because I changed this to rectangles and we sped back up, but the rectangles I changed it to We're smaller What if we did this as 100 by 100, which is the same as what our line is ending up It's gonna draw over the top of our other things Does this go slow as? You're down there, buddy stuck in the old one. I'm gonna reset. It's still quite a bit faster It does have 10,000 Pixels per buffer. So we still have that 100 pixels times 100 pixels And it's slower than The other rectangles. It's slower than the smaller rectangles, but It is still way faster than The lines Wish we had a way to not do this in the rebel did At least displays that doesn't seem like the best I feel like we might have just stumbled on to something though because we're not seeing any 10 thousands here And to my eye, we're seeing a I'm seeing a lot of 67s here. I don't I'm not sure if it's counting up Oh, I can stop it if I scroll actually We're stopping we're stopping at 69. We're not doing We're not doing the other ones so When it's a rectangle How did I What did I do here? Hit an equal string. I know what I was doing there when it's a rectangle and it's not hidden When it's visible we don't We don't have Now we reached the end of the buffer. So now it just wants to scroll We don't iterate through it. We stop there. We we don't iterate through the visible Rectangles, but when they're hidden we do Because here we're going on into the 70s So I will say already that feels kind of wrong to me because so what that means is that When they When the rectangles are hidden They are getting returned into here as part of get refresh areas But when they're visible, they're not Probably because they're not changing That would be my guess is because they're not changing If we were to make another loop inside of there and change the color of those other rectangles also Then I think they would be part of this loop Because then they would be changing But when they're visible And they don't change they don't get looped. They don't get iterated over here So that's one key difference that definitely is part of our Part of our slowdown is the fact and and it doesn't make any sense to me because if they are hidden We should we should be able to skip iterating them not not the vice versa. It seems like we're getting the opposite it seems like when they are Hidden we are iterating over them Refreshing them, but when they are visible we're not So it feels like something has marked them as dirty, which is like Tells the system that it needs to refresh Can a rectangle be on adult a diagonal? It cannot. Uh, nope has to be Squared up on the 90s there for a rectangle Rectangle can use fill instead of polygon. Yeah, again, there's definitely Different ways to do this other than polygon and rectangle But what we're like we're trying to look specifically into those things because it doesn't they seem slower than they should be So yes, there are ways. I think you could speed it up by doing it differently But also we want to understand why it's going slow when we do it this way And so it's worth continuing to do it this way even though we know that we could probably change it to a different way And speed it up That's very weird the fact that we iterate over them when they are hidden That's Definitely feeling like part of the puzzle here So let's keep looking at our logic. Well, you know what actually let's go look at see I mean the crux here is they're getting returned by this. Let's look in here This come from static const area But Usually we have an ampersand at the beginning of the function name, which I don't I don't understand, but So this is saying if self.core.full refresh Then self.core.area.next equals null Then it returns area else if core.currentGroup Not null Then return getRefreshAreas So I would assume that we are in this one Core.dot. I don't know what core.dot.fullRefresh is. I'm assuming that we don't come into here though I say assuming I mean hypothesizing it probably would be a better term Maybe it's because rectangle will never have any transparent pixels. So there's no need to Check what's below it Yeah Good thought. Yeah with with the line we have to draw stuff underneath basically Rectangle we don't because with the rectangle it's always all or none It is it's still weird to me though that we get those extra iterations It feels like we should somehow be skipping the iterations of the hidden ones like if they're hidden We shouldn't really have any kind of refreshing or anything to do. We should be able to just skip it all together. I think um That does make sense. Yeah when when there's trend and and the line polygon in this case the line it's a 100 by 100 bitmap and then it will have mostly pixels that have been on the palette turned to make transparent But then that one diagonal in the middle in our case would be the pixels that state opaque Yeah, see make transparent here. So most of the pixels in our line polygon are transparent Whereas in our rect none of those pixels are actually transparent But I do still think like we should be able to skip it if it's hidden It still strikes me as awkward that it When they are hidden they get iterated and refreshed, but when they are not hidden They don't get iterated What if we Go back to like this We don't have a Better make it go faster. We just wait. Okay. There we go So yeah, so here we they're now visible and so now we're not iterating over them There's only because they're not changing I would I would guess like the first time it probably did iterate over them But then after that it stopped since we aren't changing them But what if we made the pixels transparent? How do we get the palette off of this? We just say like r dot palette or something like that Maybe that's it If it variable in here in palette underscore palette So the palette has two Colors in it We are setting Pixels to index of one Fill is none. Why would you use fill none? I don't know why you would ever use fill none What if we said r dot palette? make transparent one Does this mean that they now get iterated? Okay. Well for one thing it's visible. I don't Maybe we need to do 20 40 50 Nope Not currently iterating so that actually did not change behavior at all So zero I guess is the Or I guess is the actual color But we also still are not iterating over them. Why do we iterate over things when they are hidden? And The line goes so much slower than the rectangle I think that's probably more like what the ship is because the line has to Pair way more about its transparency. It has to get the stuff underneath it or whatever If rect is using fill not sure you could specify a rect not to have a fill Or to have a transparent center. Oh Transparent center I forgot the fact that rect it can do an outline as well Which is exactly why you would want to potentially set it to fill none If you want the outline, but no infill. Yeah, good call on that Forgot that it does outlines But yeah, that's that's almost certainly that's the case. I think um full refresh true Fine If that's to make colon save that build We are getting pretty close to time For the evening I don't necessarily have an exact hard cut off. Although I'm getting a little hungry. So I'll probably be Not sticking around for too long Uh ordinarily This would be the part of the show where I would say that you could join me tomorrow morning Saturday at 10 a.m Central time and I'd be back streaming again But like I mentioned at the top of the show, there will be no Saturday morning stream tomorrow. So Next Saturday morning, not tomorrow, but eight days away Saturday morning, then I will be streaming at 10 a.m central but not tomorrow Probably what I'll do is when I wrap it up here. I will put a comment Onto that issue with my findings which so far I would say the findings are We re we reproduced it for one different code um We found out that lines Specifically are slower than rects And we found out that When you set hidden true they are still getting iterated over inside of The place that's using this inside of uh this Refresh Fresh area that refresh area is getting called from Refresh display They get iterated over inside this while loop inside of refresh display When they are hidden, but they do not when they are visible Okay, and we are not seeing that new output That full refresh Not having that They are iterating over all of them But they are rectangles, so they are faster than lines Correct with the fill color of none is transparent. Yeah. Yep. Thank you. I was For for a minute. I was like, why would you ever do that instead of just not making the rectangle? But I forgot about the outlines you can have outlines on them I was not thinking of but That would make perfect sense if you want to outline only then you would set the fill to none And you would set the outline to whatever color you want Which we haven't even really messed with outlines I don't know how the outline works on polygon though. I don't I don't think you can do an outline for polygon, but I'm not actually sure Wait, where did I add that other print? Area lost in here. Okay in here get in get refresh areas. That's where we went. Okay, so we're not getting that Instead we must be going in here Or All together like not none of those are being true Let's add this one See if that prints every time so core current group not null oops for Current group Not null shouty Then I would guess that we do see this one printed if we don't see this Then we know that neither of those are true and instead we're just returning null, but I don't I think that's the case probably Twitter while it's building But I actually covered up chat a while ago youtube chat else in there That either But are we looping so this only gets called once and then we're just immediately spamming Inside that while loop actually we need to probably turn that off Just join. What are we doing? How's it going? First of all, Steve you were I will say Uh, I hate to be the bearer of bad news, but I ain't gonna be wrapping it up pretty soon here. So unfortunately you joined Pretty quick right before we're getting ready to go That being said obviously the vod's there so you can still check out the the rest of what we worked on And with all that aside what we are working on is we're hunting for a bug inside display io Which is the circuit python. I don't know your level of familiarity familiarity with the project or not But display io is one way to draw in displays in circuit python What a person has submitted as an issue is that with display io When you have a bunch of line objects that are hidden The display takes a very long time to refresh And if you make those line objects visible instead of hidden Then the display refreshes much faster and that's weird and we're trying to figure out why it's doing that and then Hopefully once we understand why it's doing that We will also be able to make it not do that because Should not probably it should be able to go fast if uh You'll be able to go fast especially like The more things are hidden Then that means the less things that need to be drawn. So like We would expect it to go faster. I think Rather than slower I would expect it to go faster rather than slower That being said like I probably I know for a fact that I don't have the full mental picture of display io yet that being said I do understand a lot of it I would guess That amongst people who did not work on it initially in the core I probably have about the deepest level of understanding of anyone who did not actually work on it At this point in the core I don't really see too many other people mucking about with display io inside the core all that often Hey match occasionally pops up does some work in there gave us a lot of stuff in bitmap tools as well Jeff does a bit uh from time to time, but I think jeff was probably working on it when it was originally created The shippu done some updates in the core With uh like the pew pew stuff as well. I think the shippu is the one that made groups Hey like lists that was in the core this way. Oh not too long ago I mean I say not too long ago maybe a year or two at this point, but Getting a lot of these I guess we need to turn that off too probably is that that must be inside the loop then Yeah, for sure sizes Uh-oh killed this one. Okay. Yeah Indeed We do get that looks like every time or current group not equals null and figure out back to where that was now It's here or current group not equals null. So we are doing this therefore we are then going inside Calling this on the current group Get refresh areas of the current group or dot current group I don't know what core dot current group represents either necessarily It's going inside of here, which does not have a definition in this file I'm not sure where that comes from display.io group get refresh areas The inside group I guess or 40 inside group. I could click that get refresh areas inside of here we say If self that item removed then self that dirty area equals next No dot dot next equals tail tail equals Delft that dirty area. I don't know this is probably this looks more like some more linked list stuff going on there But I'm not entirely sure I self members length that's going to be looping over all the members inside the group So for one thing I would say here before we go inside of here We should probably be checking hidden If hidden is true then just don't do any of this for one thing. I think right Get refresh areas So what does it basically say when it does go in here? So if vector.io is enabled on the build Then it's going to say like try to get the like like we're looping over the current like the items inside the group The display objects is what I was calling them before although this calls the members We're looping over those display objects each one of those display objects could be one of Three things it could either be a vector.io shape which we're not messing with in this example So none of ours are that it could be a group So you can nest one group inside of another group Or it can be a tile grid Those are the only three things that you can put inside of a group. So while we're looping over all the things here It's going to be one of those three things and now of course you can have subclasses, right? Like we're putting a line object and the line object extends the polygon object and polygon object extends the tile grid So like not directly the tile grid, but eventually if you follow up the chain Then you get to the tile grid So here it's going Basically figuring out which type of object it is if it's a vector.io object We do this one if it's a tile grid object We do this one if it's a group object then we do this one and in our case We mostly have tile grid objects. So we are mostly doing this one And I would guess then that that is inside of tile grid here deed And here is finally where it looks like we might be doing something with hidden We're finally starting to check hidden inside of here, but I I feel like we might be a little too Deep in there. I think we could have bailed earlier Like for one thing this entire group could be hidden That were the loop the the group that we're looping through Could be hidden in which case we don't need to bother looping the children because we know everything will be hidden But then the other thing is maybe we could be checking outside of here instead of going inside Let's look so we go first draw hidden equals self hidden or hidden by parent If hidden if not first draw Previous area next equals tail Return self previous area. So that's like it's advancing or something. I think Otherwise if it is the first straw then just return tail Else if it's not hidden It's not hidden but it moved And it's not the first draw So it's not hidden it's visible And it moved and it's not the first draw then area union dirty area size Who you know what that's all about unsigned. I guess never seen a you like that It Pretty area next tail doing some more stuff with the next thing Yes area next and we have checking on types so we're saying if it's a bitmap type if it's a shape type If it's a palette type Well, no, not if it's a palette type. This is getting the palette to do something with a Partial change. So we go through and all that stuff. Okay. I wonder if these are not getting set properly Anyway, I think I'm gonna start Putting my Comment in Thanks for the stream. Hope you have a wonderful week and get outside. Let's do some music. Yeah. Yep. Thank you appreciate it Um, we'll be that will be the plan for tomorrow You just crossed for some good weather We post our reproducer One thing the reproducer right now is not in the exact right State I think I'm not gonna post the reproducer shit Did you want to link to that loop? I found It was in refresh Display fresh display 344 ish. It's not gonna be the exact same because I have a bunch of I have many comments though. Do I maybe? Oh, 340 not 440. Okay That's a little oh Eat this and refresh this Lines we swish down again Okay, so we'll check we're not putting anything crazy here Successfully recreated the issue learned a bit about it, but uh, but do still need Say I don't I never use commas, right? I'm like terminally never using commas correctly. I don't know why It's supposed to be easy. Like do you pause if you say it out loud? I know the rule I try to do it in my head and like literally I still never do it correct. So I don't know Let's still need to dig a bit further. Do not have an actual solution to propose yet a few findings The test An object makes it go much slower than wrecked objects. I tested by changing the 150 loop Loop to make wrecked Set of lines and the display refresh is much faster in that case let's say even Even if I make the wrecked the 100 by 100 is the size of the bitmap where the line fully horizontal or a fully vertical line Plays the display to refresh much faster than the diagonal line Which makes sense because the diagonal line is the least efficient since it has to make the bitmap Big enough to contain the full rectangle that encloses that diagonal line and many pixels will be transparent Whereas with horizontal or vertical the map gets to be the exact size it needs to be in order to show without without any Place where our losing time seems to be inside of this loop Usually we get iterations within this loop for things that are hidden When the lines are hidden we are still iterating through them once per each line This loop and calling refresh area on them Thinking that may be a logic bug somewhere because I would think that we could skip them in the refresh loop if they are hidden Trying to chase a bit further into get refresh areas Which is where they come from before it starts looping over them I'll have to dig further another time. I've got to stop for now. Cool. Okay. All right So I will head out for the evening now. Thank you everybody for watching I hope everyone has a good rest of your evening tonight as well as a good weekend a long weekend If you are in the u.s. And celebrating the the national holiday So for all the folks who do get to have a long weekend this week. I hope you all have a happy and good and fun long weekend Like I said, I will not be back tomorrow morning at 10 a.m But I do typically stream at that time saturdays at 10 a.m So if you come back next week 10 a.m on saturday, I should be around then most of the saturdays thereafter So yeah, I think needing to iterate even when hidden is in case they They move but remain hidden That's a good thought Yeah, but shouldn't we only refresh like when it gets shown again like if it moves do we need What do we need? Why do we need to do any calculation if it moves when it's hidden if it moves while it's hidden We're not showing it. So nothing changes at that point still I don't know. That's an interesting thought Interesting thought Although I will say something seems to be smart enough to skip them sometimes because like the rectangles here When we did not have them hidden these rectangles here They got skipped in that loop because they're not moving because they're not changing colors because nothing is changing about them They got skipped by that loop Which the lines I guess the lines do when they're visible, but they don't when they're hidden. So that part's the same when they are hidden They do get looped But yeah, I don't I don't know something like because it can skip because it skips those iterations when they're visible I don't feel like it should need to be different when they're not visible Like it it knows if they changed and in our case, they didn't actually change They haven't moved they haven't changed colors So it should be able to skip them the same way whether or not they are hidden And further in my mind, I think it should be able to skip them All together if they are hidden But even if we take that out of the mix Even if we don't worry about skipping them when they're hidden The fact of the matter is they're not moving and they're not changing colors and with With these ones in that situation when they don't move and they don't change colors It is able to skip them somehow It should skip them the same way. I think when they are hidden unless if there's something that I'm not Considering somewhere in there If it later unhides Already rendered doesn't seem efficient, but maybe it needs true Uh, maybe oh excuse me. It doesn't seem efficient, but maybe a need and then the next message is true Not moving should be super fast. Yeah, that's my thought is we should be able to use the same trick Whatever the trick is that causes them to get skipped while they're visible At a minimum, we should be able to do that same trick while they're hidden because they aren't actually moving So we should we should be getting the same benefit Of that whole like not becoming dirty basically What if they're moving causes them to become visible? So that can't I mean with the hidden That can't happen because if you move it Moving it will never change this hidden property Hidden is different than simply off the screen. You might think like you could hide something by moving it off the screen like to negative X and y values and you can do that if you move a thing to negative values It will you know render off the screen. It won't be visible But it's in that case it's it's different than the hidden property It doesn't get drawn on the screen And then if you move it back on the screen, you know, it could become visible in that scenario It could it could move itself back to the screen and then needs to be drawn again But that is a different situation than the property hidden true or false The property hidden does different logic that is different from just moving it off the screen It's like a extra little flag in there that it checks Um Good thought though. All right, I will wrap it up there. Thank you everybody for watching. Thanks, mr. Good bits for bouncing off some ideas with me here in the chat appreciate that and steve as well over in the youtube Appreciate everybody who's watching and I will see you all later. See you