roTextureManager skipping some images

I am working on a newer version of my application. In my previous app I was using roUrlTransfer to download images to local file system. But this time I am using roTextureManager to grab images from remote sources. But roTextureManager does not seem to be as reliable as roUrlTransfer has been. Some of the images (not some specific but randomly) are not being downloaded on almost each time I load a screen. Whereas my previous version of the app which uses roUrlTransfer to download images is working fine and all the images are downloaded. Have anybody else has had same issue? And what can be the reason that images are downloaded fine with roUrlTransfer but not with roTextureManafer although I think underlying processing of grabbing the image must be same for both of them?

I had the same problem. There was a time when I would use the roTextureManager to download about 50 images when the channel started. There were often a random handful of images that failed to download for no apparent reason. I received a texture request event with a state of 4 (failed). I’d retry the failed downloads, which were successful the next time around. I don’t believe I had any memory issues or networking issues at my end. However, the images were coming from servers 5,000 miles away, so maybe were taking too long and exceeding some timeout value used by roTextureManager.

I ended up writing my own texture manager that used roUrlTransfer, and haven’t had any problems with downloading those same images that way.

The HTTP services may be the same as any other net-aware component but storage and memory management is different. The best way to learn the texturemanager is to observe its behavior with telnet and r2d2_bitmaps. I have used it quite extensively over the last year, and the only problems I encountered were mostly related to my misunderstanding of it. It is not well documented. Can’t say that I ever have experienced what you describe. Have to wait a few seconds on very rare occasions for that last bitmap to pop in, but it always comes. Resending usually was the the result of a bad url or connection error. But then I have not tried it with a server 5000 miles away or multiple servers in the same batch of requests. There may be timeout issues. I notice that when I use it with roSystemLog there are a number of connection errors that are observed but I still get the bitmap in the end. So far I think its a great component for what I need it for. And I have really put the pedal to the metal as it applies to consistently requesting, cancelling or unloading. Could never have produced the same quality dynamic grids without it.

“NewManLiving” wrote:
The HTTP services may be the same as any other net-aware component but storage and memory management is different. The best way to learn the texturemanager is to observe its behavior with telnet and r2d2_bitmaps. I have used it quite extensively over the last year, and the only problems I encountered were mostly related to my misunderstanding of it. It is not well documented. Can’t say that I ever have experienced what you describe. Have to wait a few seconds on very rare occasions for that last bitmap to pop in, but it always comes. Resending usually was the the result of a bad url or connection error. But then I have not tried it with a server 5000 miles away or multiple servers in the same batch of requests. There may be timeout issues. I notice that when I use it with roSystemLog there are a number of connection errors that are observed but I still get the bitmap in the end. So far I think its a great component for what I need it for. And I have really put the pedal to the metal as it applies to consistently requesting, cancelling or unloading. Could never have produced the same quality dynamic grids without it.
I have tried to observe its behaviour through telnet and r2d2_bitmaps. It downloads images to some memory in file format which does not seem to be neither of both “tmp:/” and bitmaps memory that is examined by r2d2_bitmaps. Only bitmaps that take r2d2_bitmaps memory are which we set a bitmap handle for using msg.GetBitmap() of roTextureRequestEvent. The images that I am downloading with it take around 15mb of bitmaps memory so they must take quite less file memory that roTextureManager is using, 1 to 2mb probably. So it mist not be out of memory or file storage issue. I will try to check today whether it is an Http issue or not because that is the onky possibility left. But it should not be so too as in that case roUrlTransfer should not work either.

“belltown” wrote:
However, the images were coming from servers 5,000 miles away, so maybe were taking too long and exceeding some timeout value used by roTextureManager.
I have tried on 2 locations and for me strangly more images were loading 5000 miles away from the server and less were loading near the server :).
I ended up writing my own texture manager that used roUrlTransfer, and haven’t had any problems with downloading those same images that way.
So requesting for images again did not resolved the issue?

“scorpiontahir02” wrote:

“belltown” wrote:
However, the images were coming from servers 5,000 miles away, so maybe were taking too long and exceeding some timeout value used by roTextureManager.
I have tried on 2 locations and for me strangly more images were loading 5000 miles away from the server a d less were loading near the server :).
I ended up writing my own texture manager that used roUrlTransfer, and haven’t had any problems with downloading those same images that way.
So requesting for images again did not resolved the issue?
When I requested the images again, they did load. I don’t really think it’s the distance that matters, just how slow that particular server is at serving up images. In that particular channel (when using roTextureManager), I’d wait until all texture requests had completed then retry the ones that had failed. I just didn’t like the holes it left on the initial screen in the time it took before the retried images were downloaded. I didn’t have to worry about that when using my own texture manager. However, the main reason I decided to write my own texture manager was because roTextureManager wasn’t supported on the legacy Rokus, and I wanted that channel to work on all Roku devices. That was just before they announced that they’d no longer support the legacy Roku devices through channel updates, etc. So that exercise turned out to be a waste of time, and I’ll probably go back to using roTextureManager in future projects.

Ok, re-requesting images once failed resolved this, although this should not happen in the first place. I just checked the msg.GetState() = Failed and re-requested image, did not have enough time to log error with roSystemLog to reach underlying cause of it.

I had the same problem with my custom grid. Are u invalidating the roTextureRequest before the roTextureRequestEvent is received? If so, try to maintain it until the response is received. I’m not sure abt this, but might solve the issue.

“sonnykr” wrote:
I had the same problem with my custom grid. Are u invalidating the roTextureRequest before the roTextureRequestEvent is received? If so, try to maintain it until the response is received. I’m not sure abt this, but might solve the issue.
No I have only one roTextureManager instance that is created at the start and used throughout the application and is never invalidated until application exits. Moreover if that would have been the case then requesting the images for the 2nd time should not work eother but is working.

“scorpiontahir02” wrote:

“sonnykr” wrote:
I had the same problem with my custom grid. Are u invalidating the roTextureRequest before the roTextureRequestEvent is received? If so, try to maintain it until the response is received. I’m not sure abt this, but might solve the issue.
No I have only one roTextureManager instance that is created at the start and used throughout the application and is never invalidated until application exits. Moreover if that would have been the case then requesting the images for the 2nd time should not work eother but is working.

I agree. You should have only one instance of roTextureManager for the entire app. There is no point in invalidating it. But, what Im talking abt is keeping the roTextureRequest instance alive until its corresponding roTextureRequestEvent is returned.

What he means is your texturerequest must persist until completed. If you are using asynchronous services it is important that you keep your texturerequest in scope until it actually completes with a return code. Creating a texture request locally in a function and then returning from the function after sending the request will of course invalidate any local variable created in the function as well as your request.

I agree. You should have only one instance of roTextureManager for the entire app. There is no point in invalidating it. But, what Im talking abt is keeping the roTextureRequest instance alive until its corresponding roTextureRequestEvent is returned.
Oh sorry you wrote roTextureRequest and I misinterpreted it with roTextureManager. And thanks for the info that we need to keep the reference to roTextureRequest until it is completed, I did not know that. But I am keeping the reference to all the roTextureRequest objects until the screen that these roTextureRequest objects belong to closes. And I am using same roTextureRequest to rerequest image in case of failure instead of creating new one.

each time you request a texture create a new request. I reused them initially and had problems. Generally you want to keep your request in an AA by ID. You can also use an AA as a structure which contains an rotexturerequest member as well as other information that identifies the purpose of the bitmap including a bitmap member where you keep the bitmap. Keep a list of these structures in an AA by the texturerequest ID. When the request returns pull it from the list by the returning requests ID ( you will have to convert to string on both ends). In case of failure do not reuse but create a new one from the information stored in the associated structure and resend. You can also keep a resend count in the structure so you know how many times you requested it.

“NewManLiving” wrote:
each time you request a texture create a new request. I reused them initially and had problems. Generally you want to keep your request in an AA by ID. You can also use an AA as a structure which contains an rotexturerequest member as well as other information that identifies the purpose of the bitmap including a bitmap member where you keep the bitmap. Keep a list of these structures in an AA by the texturerequest ID. When the request returns pull it from the list by the returning requests ID ( you will have to convert to string on both ends). In case of failure do not reuse but create a new one from the information stored in the associated structure and resend. You can also keep a resend count in the structure so you know how many times you requested it.

This is exactly what I am doing now, except for the part that I am using URL as the key in AA (I am using it like AA[url] because url contains charachters that dot(.) does not support) instead of roTextureRequest id because it makes it easy for me to use it afterwards in my application, also I am reusing previous roTextureRequest objects. So thanks for the heads up on future issues with reusing same roTextureRequest objects, I will replace my code to create new requests.

One thing I would like to know though, when I am using roTextureManager, should I load my local images too using it or using CreateObject(“roBitmap”)? Although both will be fine but what should be the practice?

I use roURLTranfer to file for images that I need to persist for the entire application or module. I designed my framework to load and unload these bitmaps from temp which are primarily top-level interface objects. Right now I use CreateObject for these bitmaps and the texturemanager for grid bitmaps. So far, I have not had a problem mixing the two

“NewManLiving” wrote:
I use roURLTranfer to file for images that I need to persist for the entire application or module. I designed my framework to load and unload these bitmaps from temp which are primarily top-level interface objects. Right now I use CreateObject for these bitmaps and the texturemanager for grid bitmaps. So far, I have not had a problem mixing the two

Ok, actually I was talking about the image we load from pkg:/ but as you said you are using createobject for tmp:/ so using it for pkg:/ will be ok too. In roTextureManager’s example I saw it to be used for pkg:/ images that is why I asked.

“scorpiontahir02” wrote:

“NewManLiving” wrote:
I use roURLTranfer to file for images that I need to persist for the entire application or module. I designed my framework to load and unload these bitmaps from temp which are primarily top-level interface objects. Right now I use CreateObject for these bitmaps and the texturemanager for grid bitmaps. So far, I have not had a problem mixing the two

Ok, actually I was talking about the image we load from pkg:/ but as you said you are using createobject for tmp:/ so using it for pkg:/ will be ok too. In roTextureManager’s example I saw it to be used for pkg:/ images that is why I asked.
Just be aware that using CreateObject(“roBitmap”) does not count against the roTextureManager’s LRU management, so if you’re loading bitmaps outside of the roTextureManager, then you could very easily overrun the memory. It’s also worth noting that roTextureManager isn’t aware of you keeping bitmap references alive, so its LRU management may unload a bitmap from its own cache, and think that memory is available to it again, even though it isn’t. I believe the general rule of thumb I was told was to keep bitmap references that aren’t fully managed by roTextureManager down to under 5mb.

“TheEndless” wrote:

Just be aware that using CreateObject(“roBitmap”) does not count against the roTextureManager’s LRU management, so if you’re loading bitmaps outside of the roTextureManager, then you could very easily overrun the memory. It’s also worth noting that roTextureManager isn’t aware of you keeping bitmap references alive, so its LRU management may unload a bitmap from its own cache, and think that memory is available to it again, even though it isn’t. I believe the general rule of thumb I was told was to keep bitmap references that aren’t fully managed by roTextureManager down to under 5mb.
I have tried to look for roTextureManager behaviour using r2d2_bitmaps, what i have seen is that images pulled by roTextureManager does not take space in bitmaps memory until we load bitmap by callingmsg.GetBitmap() and keep a reference to it. So as far as i know roTextureManager takes only that much space which we know of as we have references to those bitmaps. So either we are creating bitmaps with CreateObject or msg.GetBitmap it shouldn’t make a difference as we know what total memory is consumed by bitmaps created by both the requests. Although I don’t know where roTextureManager stores images (not bitmaps but files) which it downloads. But it surely is not bitmap memory otherwise it would have shown using r2d2_bitmaps. Am I getting roTextureManager wrong here?

“scorpiontahir02” wrote:

“TheEndless” wrote:

Just be aware that using CreateObject(“roBitmap”) does not count against the roTextureManager’s LRU management, so if you’re loading bitmaps outside of the roTextureManager, then you could very easily overrun the memory. It’s also worth noting that roTextureManager isn’t aware of you keeping bitmap references alive, so its LRU management may unload a bitmap from its own cache, and think that memory is available to it again, even though it isn’t. I believe the general rule of thumb I was told was to keep bitmap references that aren’t fully managed by roTextureManager down to under 5mb.
I have tried to look for roTextureManager behaviour using r2d2_bitmaps, what i have seen is that images pulled by roTextureManager does not take space in bitmaps memory until we load bitmap by callingmsg.GetBitmap() and keep a reference to it. So as far as i know roTextureManager takes only that much space which we know of as we have references to those bitmaps. So either we are creating bitmaps with CreateObject or msg.GetBitmap it shouldn’t make a difference as we know what total memory is consumed by bitmaps created by both the requests.
It may or may not make a difference to consumed memory, but it does affect the roTextureManager’s ability to manage its memory automatically. One of the primary benefits of the roTextureManager is its LRU cache based memory management. If you’re keeping references to bitmaps open and/or loading bitmaps into memory outside of the roTextureManager, then that LRU cache functionality is hindered. This is especially important on the older Roku 2 XD/XS and the Roku Streaming Stick, as their texture memory is much more volatile. If you’re only testing on a Roku 3, then you’re unlikely to see any issues as it has significantly more memory to work with.

“scorpiontahir02” wrote:
Although I don’t know where roTextureManager stores images (not bitmaps but files) which it downloads. But it surely is not bitmap memory otherwise it would have shown using r2d2_bitmaps. Am I getting roTextureManager wrong here?
r2d2_bitmaps will list the file location, if it’s saved to a file somewhere. For example (see the path in the 6th column):

0x7d4affde  1280    720   4  3686400 /nvram/theme/HD/BackgroundBitmap.jpg
0x3161a9e    100    100   4    44800 /nvram/theme/HD/LabelListFocusBitmap.9.png
0x3ab82ce    100    100   4    44800 /nvram/theme/HD/LabelListFocusFootprintBitmap.9.png

In the case of downloaded images, it usually looks something like this:

0x7d91bbb6   210    300   4   268800 /tmp/download/ec852ebb64f01df79d7cf610c2e92e41
0x7da884c6   210    300   4   268800 /tmp/download/a3ccbd24b8abe15ecb36b655ed0e88fb
0x7d91c646   210    300   4   268800 /tmp/download/c3c31e84e9b0619b84eb1dc91b965849