Does someone know how ifDraw2D.DrawScaledObject() scales images, in particular reducing an image?
(There are different algorithms possible)
Specifically, say i have scaleX and scaleY being 0.5 or 0.25 (i.e. reducing image 2x or 4x). Will each of the new pixels be a kind of “average” (bi-linear or bi-cubic interpolation over 4 or 16 pixels respectively) - or will it pick a single pixel (nearest-neighbour)?
“EnTerr” wrote:
Specifically, say i have scaleX and scaleY being 0.5 or 0.25 (i.e. reducing image 2x or 4x). Will each of the new pixels be a kind of “average” (bi-linear or bi-cubic interpolation over 4 or 16 pixels respectively) - or will it pick a single pixel (nearest-neighbour)?
I love your questions, I’m not optimistic about you getting an answer to this one. Just based on what i’ve seen happen, my guess is bicubic, with nearest-neighbor being the least likely. You can usually tell if its N-N, it really creates a lot of contrast that wasn’t in the original.
“Komag” wrote:
You could set up an original image that is every other line red and green, and see what happens!That occurred to me but will be unreliable, since depending on the model, different (>1) graphic engines are used. And even if i tested on every model in existence, results may be valid only in this point of time, today.
And maybe SetScaleMode(mode as Integer) changes it to one vs the otherYou mean ifRegion.SetScaleMode()? I am not using roRegions, so not directly applicable but thanks for letting me know about its existence. Looking at the folksy description
“SetScaleMode(mode as Integer) as Void” wrote:
Set the scaling mode used for DrawScaledObject
0 = fast scaling operation (may have jaggies)
1 = smooth scaling operation (may be slow)now i wonder (question #2):
Is it trying to say that 0 does nearest-neighbor and 1 does bilinear interpolation?
(Source for my speculation, the unrelated ifTextureRequest.SetScaleMode)
“EnTerr” wrote:
You mean ifRegion.SetScaleMode()? I am not using roRegions, so not directly applicable but thanks for letting me know about its existence. Looking at the folksy description
EDIT: My assertion here was entirely incorrect, so removed here to avoid confusion in the future.
“EnTerr” wrote:
now i wonder (question #2):
Is it trying to say that 0 does nearest-neighbor and 1 does bilinear interpolation?
(Source for my speculation, the unrelated ifTextureRequest.SetScaleMode)
Yes, I believe so. There’s a much more obvious visual difference on 3.1 firmwares than on 5.x+, but there’s a significant speed improvement when using a scale mode of 0 on both. Generally speaking, I use a scale mode of 0 for animations, and a scale mode of 1 for static drawing. If the source needs to be scaled (to the same size) on every frame, then it’s best to cache it to a bitmap, so you only need to do the scaling once.
“TheEndless” wrote:
Note that to use SetScaleMode, you set it on the target region, not the source. Even if you’re not drawing to a specific region of your target, you can still wrap the whole bitmap in a region to take advantage of the scale modes (also applies to roScreen): …
Thank you for the practical tips. The part about SetScaleMode() applying to the target region should be added to the docs, not obvious at all.
Do you have observations about performance penalty from extra wrapping a bitmap in a region? (ballpark. are we talking 0.3%, 3%, 30% etc)
EDIT: My assertion above was entirely incorrect, so removed here to avoid future confusion.
“EnTerr” wrote:
Do you have observations about performance penalty from extra wrapping a bitmap in a region? (ballpark. are we talking 0.3%, 3%, 30% etc)
I honestly can’t say I’ve noticed any performance penalty, and I use regions for just about everything. I’d be interested in seeing the results of one of your infamous benchmark tests on it, though..
i have never noticed it either and I also use them all the time
Would not think so since it is essentially a viewport.
Most importantly though is what a region can do.
1, It clips (can even make regions on roScreen)
So calculations occur only once prior to creating
The region, then the region itself has
It’s own coordinate layout at 0,0. Don’t forget the
Undocumented 2d interface which lends nicely to
The clipping
2, it scrolls wonderfully. Beats dragging bitmaps
Across the screen, especially on lower models
Giving a more smoother look and feel
It pretranslates , saving you from creating a complex
BS formula for us which woud be slower
There are other things it is useful for especially with
It’s 2d interface
For the last 6 months I have been working on
A grid which mimics the best of some of the ones available
It is completed now and I am impressed on how well it performs
On the boxes that I have. I could not have done it without regions
Since the textures are coming and going all the time and the grid needed
To be updated even while the user is scrolling it. If I was not Offsetting regions
But changing the xy coordinates of the cells then each texture object would
Need to update itself with the new coordinates until the texture was received. With region
Offsettibg the bitmap is fixed and the region moves
So the point is that optimizing is relevant to what it can do
As opposed to how long it takes to create one
By the way this grid is a perfect example
Of observing the texturemanagers lru
Caching. Textures initially pop in nicely
But with repeated scrolling they literally
Melt in at fast speeds although there is
No difference in the number released and
The number requested at any given time
“NewManLiving” wrote:
By the way this grid is a perfect example
Of observing the texturemanagers lru
Caching. Textures initially pop in nicely
But with repeated scrolling they literally
Melt in at fast speeds although there is
No difference in the number released and
The number requested at any given time
Not to go too far off-topic, but have you tested it with an roVideoPlayer playing at the same time? In my experience, the roTextureManager is virtually useless when used along side video playback. You can implement your own LRU cache to compensate, but that negates 75% of the benefits that roTextureManager provides. The single-threadedness of BrightScript just makes it all that much worse (i.e., pauses in rendering while updating the custom LRU cache).
Yes the TextureManager takes a back seat when roVideoPlayer is active. Seems to be allocating all available resources to the player. Ironically this is how I tested the grid. After starting a video I would return to the grid and then scroll fast to make sure each cell was updating properly when the texture arrived. Since the lru was scrapped I was able to see the re-popping in of each requested texture :D. So I will not be using anything TextureManager intensive along side the video. But in relation to the grid it is phenomenal. Once I learned how to use it and then taking advantage of everything built-in to the 2D ( as apposed to doing things in BS ) such as regions and yes, the compositor, I was able to produce a grid in function and quality as the stock grid, but customizable. I use a region to fade the scrolled out rows to mimic the new Netflix interface. Performance wise there is no perceptible difference on the three environments that I own. The 3, 2xd and the stick. Although the 2xd and stick have an occasional flicker at the bottom of the screen, suspect it has something to do with refresh rates. It does not happen often and is not really an issue for me. Maybe you can shed some light on this. As far as legacy boxes I don’t know. I tried using only bitmaps, just the screen, etc so that I could put out an example for those who don’t like compositors, sprites, and regions, but performance was good but differential on the lower end boxes with some processor lag. I was able to alleviate this by removing all DrawText calls and making the labels bitmaps and removing all alpha blends that rode above the grid such as the cell counter. But I was not satisfied. By returning to my tried and true method, performance was the same on all the three environments. But I only have the 3 to test on so that is all I can provide. So far I am very impressed with it. But it is new and probably I will encounter minor problems (leaving it to you to point them out). I just popped it into a theme based framework for a client and its looks and works great.
FYI - DrawScaledObject is generally going to be faster than using roTextureManager to scale images as the hardware does the scaling, where roTextureManager implements scaling in software. The one place where you will probably want to use roTextureManager to scale is when you have images larger than 2048x2048 that you want to use as an roBitmap source.
“RokuJoel” wrote:
FYI - DrawScaledObject is generally going to be faster than using roTextureManager to scale images as the hardware does the scaling, where roTextureManager implements scaling in software.
Interesting. Shed some light on the original questions, RokuJoel:
What’s the scaling mode used by ifDraw2D.DrawScaledObject()? (E.g. is it nearest-neghbour or bi-linear)
The meaning of ifRegion.SetScaleMode() - is 0=nearest-neighbour and 1=bi-linear?
“NewManLiving” wrote:
Although the 2xd and stick have an occasional flicker at the bottom of the screen, suspect it has something to do with refresh rates. It does not happen often and is not really an issue for me. Maybe you can shed some light on this.
Yep. That sounds like you have bitmaps being disposed while you’re mid-screen draw. It’s a known issue with the Roku 2 XD/XS and Streaming Stick (At least known to us in the forum. Roku hasn’t acknowledged it.) See this thread where Enterr and I narrowed it down to the cause: viewtopic.php?f=34&t=54513&p=438741#p438058
After I posted I remembered what you said about bitmap.finish
I had not used it since I never had any problems on the 3 box
So I “assumed” that compositor.drawall must do all the work
But after placing it back into the code I have not noticed any
Flicker. It’s been two days and I have been scrolling away
So possibly that may have solved the problem. You are a
Treasure Chest of experience! Thanks