ImageList cache optimization

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #36078
    SzakiLaci
    Participant

    Hi,

    I would like to suggest to rewrite a bit the cashing system of TsAlphaImageList and TsVirtualImageList.

    – Currently it takes multiple seconds on program startup, if [UseCache = True]

    – no response from the program until it's converting/re-sampling, it simply “freeze“, even with only 30-40 pictures on a Celeron processor

    – if [UseCache=False] then it's good for load-up, BUT the panels with big pictures appear extremely slow each time.

    So the SOLUTION would be to combine the “good side” of both behavior. :a3:

    CACHE each picture only when FIRST TIME Accessed !

    This way:

    • won't take extra memory for pictures never beeing accessed
    • would still take less amount of time while loading, but summarized the same amount when all pic. is needed
    • loading could be controlled !!!
    • (Background / time-slice) or

      simply SHOW it on a splash screen while loading: Please wait, … converting pictures 47./max62

    #51708
    SzakiLaci
    Participant

    … I've looked into the code and I think it's very easy to do.

    1.) CUT out from

    Code:
    procedure TsVirtualImageList.GenerateStdList;

    CachedImages := CreateBmp32(Width, Height)

    part. Leave it NIL. (You can also use a boolean flag, but I think checking =nil later is fine too.

    2.) Paste it to a new procedure. Name it like:

    Code:
    RenderCacheNow(Index:integer);

    3.) Put a “caller” for it into:

    Code:
    function TsVirtualImageList.GetBitmap32(Index: Integer; Image: TBitmap): Boolean;

    if FUseCache then begin
    if CachedImages[Index] = nil then
    RenderCashNow(Index);
    #51709
    SzakiLaci
    Participant

    .. And if you want to have backward compatibility >> you can make property like

    CashALLatStartup:Boolean = True;

    and for that an “OnCaching” event.

    THANKS A LOT in forward!

    I could write it myself, but do not want to mess up your code, and rewrite/search for difference each time I want to install a new version of AC.

    I need this behavior badly, because my program startup is already TOO SLOW, and my clients are complaining that the “old version” was better 🙁

    Also I would like to change my old 32x32px ugly menu pictures to new 128x128px alpha-channel ones. And those are ca. +80 icons additionally to the current 40. :a1:

    PS: Donated some cash for the cache :a8:

    #51762
    Support
    Keymaster

    Hi! Thank you for donation.

    Your idea is good, I'll try to make it.

    But, what is purpose of the RenderCacheNow procedure? Users will not use it, I think..

    #51781
    SzakiLaci
    Participant
    'Support' wrote:

    But, what is purpose of the RenderCacheNow procedure? Users will not use it, I think..

    It is the MOST important part of my idea, because programmers (like me) could either:

    1. render each picture 1 by 1 at startup and show the progress (Caching pictures… 47 of 147 done.)

    or

    2. load it in background with a timer, so the app does not frees, but slowly sooner or later all pictures would be cashed.

    3. you can call it from your procedures, if needed but is not cached yet. (and should be, because [UseCache = True])

    4. users can pre-cache particular (mostly used) pictures, and not ALL.

    #51783
    SzakiLaci
    Participant

    So basically your cache Array will “look like this” in memory :

    Code:
    CachedImages[0] = nil;
    CachedImages[1] = BMP32; // this has been called at startup, because the main screen is using it already.
    CachedImages[2] = nil;
    CachedImages[3] = nil;

    … Than I'll call directly from a timer:

    Code:
    RenderCacheNow(2); // because I now, sooner or later that image will be needed, and want to short down showing the new window that's using that image.

    … if I would call :

    Code:
    RenderCacheNow(1); // >> nothing would happen, because it's ALREADY cached! So it's skipping
    (if Assigned(CachedImages[1]) then Exit;)
    #51834
    Support
    Keymaster

    Hello!

    This procedure will be added in the v9.02:

    procedure RenderCacheNow(ItemIndex: integer = -1);

    If ItemIndex is not defined then all items will be cached.

    #51844
    SzakiLaci
    Participant
    'Support' wrote:

    Hello!

    This procedure will be added in the v9.02:

    procedure RenderCacheNow(ItemIndex: integer = -1);

    If ItemIndex is not defined then all items will be cached.

    Perfect ! 🙂 THANKS !!

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.