uiacceltk/hitchcock/coretoolkit/src/HuiTextureManager.cpp
changeset 0 15bf7259bb7c
child 6 10534483575f
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implementation of CHuiTextureManager, texture objects loading 
       
    15 *                and management.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include <eikenv.h>
       
    22 #include <eikappui.h>
       
    23 #include <eikapp.h>
       
    24 
       
    25 #include "uiacceltk/HuiTextureManager.h"  // Class definition
       
    26 #include "uiacceltk/HuiTextureProcessor.h"
       
    27 #include "HuiRenderPlugin.h"
       
    28 #include "uiacceltk/HuiEnv.h"
       
    29 #include "uiacceltk/HuiTexture.h"
       
    30 #include "uiacceltk/HuiFont.h"
       
    31 #include "uiacceltk/HuiUtil.h"
       
    32 #include "uiacceltk/HuiPanic.h"
       
    33 #include "uiacceltk/HuiDisplay.h"
       
    34 #include "huitextureanimationstate.h"
       
    35 
       
    36 /**
       
    37  * Granularity of CHuiTextureManager::iAnimations and 
       
    38  * CHuiTextureManager::iAnimatedTextureGroupItems arrays.
       
    39  */
       
    40 const TInt KHuiAnimationsGranularity = 4;
       
    41 
       
    42 EXPORT_C MHuiBitmapProvider::~MHuiBitmapProvider()
       
    43     {
       
    44     }
       
    45 
       
    46 EXPORT_C CHuiTextureManager::CHuiTextureManager(CHuiEnv& aEnv)
       
    47         : CActive(EPriorityHigh),
       
    48         iEnv(aEnv), iState(EIdle), iReleaseState(ENormal), iFS(CHuiStatic::FsSession()),
       
    49         iAnimatedTextureGroupItems( KHuiAnimationsGranularity ),
       
    50         iAnimations( KHuiAnimationsGranularity ),
       
    51         iEnableTexMemCalculation( EFalse )  //Texture memory calculation is disabled by default
       
    52     {}
       
    53 
       
    54 
       
    55 EXPORT_C void CHuiTextureManager::BaseConstructL()
       
    56     {
       
    57     iEnv.SetTextureManager(*this);
       
    58 
       
    59     SetImagePathL(_L(""));
       
    60 
       
    61     // Create a small initial bitmaps for decoder output.
       
    62     iBitmap = new (ELeave) CFbsBitmap();
       
    63     User::LeaveIfError( iBitmap->Create(TSize(4, 4), EColor64K) );
       
    64     iMaskBitmap = new (ELeave) CFbsBitmap();
       
    65     User::LeaveIfError( iMaskBitmap->Create(TSize(4, 4), EGray256) );
       
    66 
       
    67     // Create blank texture
       
    68     iBlankTexture = CHuiStatic::Renderer().CreateTextureL();
       
    69     iBlankTexture->SetImageFileNameL(_L("blank"));
       
    70 
       
    71     CActiveScheduler::Add(this);
       
    72     
       
    73     // Enabling logging will cause diagnostics and debugging messages to be
       
    74     // printed to a file.
       
    75     CHuiStatic::EnableLogging(EFalse);
       
    76     }
       
    77 
       
    78 
       
    79 EXPORT_C CHuiTextureManager::~CHuiTextureManager()
       
    80     {
       
    81     Cancel();
       
    82 
       
    83     delete iAnimationWithoutGroup;
       
    84     iAnimatedTextureGroupItems.Close();
       
    85     iAnimations.ResetAndDestroy();
       
    86     iAnimations.Close();
       
    87 
       
    88     // Delete the texture processor.
       
    89     delete iProcessor;
       
    90 
       
    91     // Clear any remaining entries in the load queue.
       
    92     for(TInt i = 0; i < iLoadQueue.Count(); ++i)
       
    93         {
       
    94         delete iLoadQueue[i].iDecoder;
       
    95         iLoadQueue[i].iDecoder = 0;
       
    96         }
       
    97     iLoadQueue.Reset();
       
    98 
       
    99     delete iBlankTexture;
       
   100 
       
   101     // Remove all texture entries (from last to first -order)
       
   102     /*while (iTextures.Count()>0)*/
       
   103     for(TInt i = iTextures.Count()-1; i >= 0; --i)
       
   104         {
       
   105         CTextureEntry * te = iTextures[i];
       
   106         
       
   107         if (te->iTexture)
       
   108             {
       
   109             delete te->iTexture;
       
   110             }
       
   111         else
       
   112             {
       
   113             // This texture was defined but never loaded.
       
   114             HUI_DEBUG2(_L("CHuiTextureManager::~CHuiTextureManager() - Notice, texture id %i (\"%S\") was never loaded!"), te->iId, te->iFileName);
       
   115             }
       
   116         }
       
   117         
       
   118     iTextures.ResetAndDestroy();
       
   119     iStateObservers.Close();
       
   120     iLoadObservers.Close();
       
   121     iAnimatedTextures.Close();
       
   122     iTextureAutoSizeObservers.Close();
       
   123 
       
   124     delete iBitmap;
       
   125     delete iMaskBitmap;
       
   126     delete iImagePath;
       
   127     }
       
   128 
       
   129 
       
   130 EXPORT_C CHuiEnv& CHuiTextureManager::Env()
       
   131     {
       
   132     return iEnv;
       
   133     }
       
   134 
       
   135 
       
   136 EXPORT_C CHuiTexture* CHuiTextureManager::Texture(TInt aId)
       
   137     {
       
   138     TInt index = CheckTexture(aId);
       
   139     if(index == -1)
       
   140         {
       
   141         HUI_DEBUG1(_L("CHuiTextureManager::Texture() - Texture id %i not found! Returning blank."), aId);
       
   142         // NOTE: there is a danger of editing the blank texture
       
   143         // instead of the real texture..
       
   144         return &BlankTexture();
       
   145         }
       
   146     CHuiTexture * texture = iTextures[index]->iTexture;
       
   147     if(texture)
       
   148         {
       
   149         return texture;
       
   150         }
       
   151     else
       
   152         {
       
   153         HUI_ASSERT(EFalse); // texture exists but is not loaded! (defined but not loaded)
       
   154         return &BlankTexture();
       
   155         }
       
   156     }
       
   157 
       
   158 
       
   159 EXPORT_C const CHuiTexture* CHuiTextureManager::Texture(TInt aId) const
       
   160     {
       
   161     TInt id = CheckTexture(aId);
       
   162     if(id == -1)
       
   163         {
       
   164         return &BlankTexture();
       
   165         }
       
   166     const CHuiTexture * texture = iTextures[id]->iTexture;
       
   167     if(texture)
       
   168         {
       
   169         return texture;
       
   170         }
       
   171     else
       
   172         {
       
   173         HUI_ASSERT(EFalse); // texture exists but is not loaded! (defined but not loaded)
       
   174         return &BlankTexture();
       
   175         }
       
   176     }
       
   177 
       
   178 
       
   179 EXPORT_C CHuiTexture* CHuiTextureManager::TextureL(TInt aId)
       
   180     {
       
   181     // try to get the index for the texture id
       
   182     TInt index = CheckTexture(aId);
       
   183     if(index != -1)
       
   184         {
       
   185         // If the texture has content and a filename, we can do a load-on-demand.       
       
   186         if(!iTextures[index]->iTexture->HasContent() && iTextures[index]->iFileName)
       
   187             {
       
   188             // we don't want to return textures without content
       
   189             // so load-on-demand      
       
   190                     
       
   191             // texture has an entry but the
       
   192             // actual texture object has not been loaded yet
       
   193 
       
   194             // we can load the texture if there's a filename
       
   195             // available for this id
       
   196             return &LoadTextureL(aId);
       
   197             }
       
   198             
       
   199         // texture found  
       
   200         return iTextures[index]->iTexture;
       
   201         }
       
   202 
       
   203     User::Leave(KErrNotFound);
       
   204     return NULL; // never
       
   205     }
       
   206 
       
   207 
       
   208 EXPORT_C void CHuiTextureManager::SetImagePathL(const TDesC& aPath)
       
   209     {
       
   210     delete iImagePath;
       
   211     iImagePath = NULL;
       
   212 
       
   213     TParsePtrC parse(aPath);
       
   214     CEikonEnv* coe = CEikonEnv::Static();
       
   215     if (aPath.Length() && !parse.DrivePresent() && coe && coe->EikAppUi() && coe->EikAppUi()->Application())
       
   216         {
       
   217         iImagePath = HBufC::NewL(aPath.Size()+2); // two extra characters for drive
       
   218         TPtr ptr = iImagePath->Des();
       
   219         ptr.Append(coe->EikAppUi()->Application()->AppFullName().Left(2));
       
   220         ptr.Append(aPath);
       
   221         }
       
   222     else
       
   223         {
       
   224         iImagePath = aPath.AllocL();        
       
   225         }
       
   226     }
       
   227 
       
   228 EXPORT_C const TDesC& CHuiTextureManager::ImagePath() const
       
   229     {
       
   230     return *iImagePath;
       
   231     }
       
   232 
       
   233 
       
   234 EXPORT_C const CHuiTexture& CHuiTextureManager::BlankTexture() const
       
   235     {
       
   236     HUI_ASSERT(iBlankTexture!=NULL); // this MUST have a valid pointer otherwise access violation will follow..
       
   237     return *iBlankTexture;
       
   238     }
       
   239 
       
   240 
       
   241 EXPORT_C CHuiTexture& CHuiTextureManager::BlankTexture()
       
   242     {
       
   243     HUI_ASSERT(iBlankTexture!=NULL); // this MUST have a valid pointer otherwise access violation will follow..
       
   244     return *iBlankTexture;
       
   245     }
       
   246 
       
   247 
       
   248 EXPORT_C TBool CHuiTextureManager::SetTextureId(CHuiTexture* aTexture, TInt aId)
       
   249     {
       
   250     
       
   251     if(!aTexture)
       
   252         {
       
   253         // Cannot set texture ID for null texture.
       
   254         return EFalse;
       
   255         }
       
   256     
       
   257     // Iterate through all the managed textures to find the one we
       
   258     // are interested in, and then set its texture ID.
       
   259     for(TInt i = 0; i < iTextures.Count(); ++i)
       
   260         {
       
   261         if(iTextures[i]->iTexture == aTexture)
       
   262             {
       
   263             // Texture was found in the list, so set the new identifier.
       
   264             iTextures[i]->iId = aId;
       
   265             return ETrue;
       
   266             }
       
   267         }
       
   268 
       
   269     // Texture was not found in the manager's list.
       
   270     return EFalse;
       
   271     }
       
   272 
       
   273 EXPORT_C TBool CHuiTextureManager::IsLoaded(const CHuiTexture * texture) const
       
   274     {
       
   275     if(texture != NULL && texture->HasContent() && !IsInLoadQueue(texture))
       
   276         {
       
   277         return ETrue;
       
   278         }
       
   279     return EFalse;
       
   280     }
       
   281 
       
   282 
       
   283 EXPORT_C TBool CHuiTextureManager::IsLoaded(const TDesC& aImageName, const TInt aFrameNumber) const
       
   284     {
       
   285     TFileName fileName = *iImagePath;
       
   286     fileName.Append(aImageName);
       
   287     TInt index = CheckTexture(fileName, aFrameNumber);
       
   288     if(index < 0)
       
   289         {
       
   290         HUI_DEBUG1(_L("CHuiTextureManager::IsLoaded() - Texture \"%S\" was not found. Assuming not loaded."), &aImageName);
       
   291         return EFalse;
       
   292         }
       
   293     return IsLoaded(iTextures[index]->iTexture);
       
   294     }
       
   295 
       
   296 
       
   297 EXPORT_C TBool CHuiTextureManager::IsLoaded(TInt aId) const
       
   298     {
       
   299     HUI_ASSERT(aId!=0);
       
   300     TInt index = CheckTexture(aId);
       
   301     if(index < 0)
       
   302         {
       
   303         HUI_DEBUG1(_L("CHuiTextureManager::IsLoaded() - Texture having id %i was not found. Assuming not loaded."), aId);
       
   304         return EFalse;
       
   305         }
       
   306     return IsLoaded(iTextures[index]->iTexture);
       
   307     }
       
   308 
       
   309 
       
   310 EXPORT_C void CHuiTextureManager::AppendTextureL(CHuiTexture* aTexture, TInt aId)
       
   311     {
       
   312     // Panic if the manager is currently restoring or releasing textures.
       
   313     if(iReleaseState == EReleasing)
       
   314         {
       
   315         THuiPanic::Panic(THuiPanic::ETextureManagerTextureDestroyedDuringRelease);
       
   316         }
       
   317     else if(iReleaseState == ERestoring)
       
   318         {
       
   319         THuiPanic::Panic(THuiPanic::ETextureManagerTextureConstructedDuringRestore);
       
   320         }
       
   321     else
       
   322         {
       
   323         // for PC lint
       
   324         }
       
   325 
       
   326     HUI_ASSERT(aTexture != NULL);
       
   327 
       
   328 #ifdef _DEBUG
       
   329     // Look for an existing entry for this.
       
   330     // There must not be any duplicates present!
       
   331     for(TInt i = 0; i < iTextures.Count(); ++i)
       
   332         {
       
   333         if(iTextures[i]->iTexture == aTexture)
       
   334             {
       
   335             User::Leave(KErrAlreadyExists);
       
   336             }
       
   337         }
       
   338 #endif
       
   339 
       
   340     // Create a new texture entry
       
   341     CTextureEntry * te = new (ELeave) CTextureEntry(aId, aTexture);
       
   342     CleanupStack::PushL(te);
       
   343     // Add the new entry to the list of new textures
       
   344     User::LeaveIfError( iTextures.Append(te) );
       
   345     CleanupStack::Pop(); // pop the texture entry
       
   346 
       
   347     HUI_DEBUG1(_L("CHuiTextureManager::AppendTextureL() - Registered texture 0x%x."), aTexture);
       
   348     }
       
   349 
       
   350 
       
   351 EXPORT_C void CHuiTextureManager::RemoveTexture(CHuiTexture& aTexture)
       
   352     {
       
   353     // Panic if the manager is currently restoring or releasing textures.
       
   354     if(iReleaseState == EReleasing)
       
   355         {
       
   356         THuiPanic::Panic(THuiPanic::ETextureManagerTextureDestroyedDuringRelease);
       
   357         }
       
   358     else if(iReleaseState == ERestoring)
       
   359         {
       
   360         THuiPanic::Panic(THuiPanic::ETextureManagerTextureDestroyedDuringRestore);
       
   361         }
       
   362     else
       
   363         {
       
   364         // for PC lint
       
   365         }
       
   366     
       
   367     // Cancel loading of the texture to be removed.
       
   368     CancelLoadingOfTexture(aTexture);
       
   369 
       
   370     // Manual sequential search.
       
   371     for(TInt index = iTextures.Count() - 1; index >= 0; --index)
       
   372         {
       
   373         if(iTextures[index]->iTexture == &aTexture)
       
   374             {
       
   375             CTextureEntry * entry = iTextures[index];
       
   376             if ( entry->iFileName )
       
   377                 {
       
   378                 HUI_DEBUG4(_L("CHuiTextureManager::RemoveTexture() - Removing texture 0x%x  (Name: \"%S\", Id: %i). Number of textures after deleting: %i."),
       
   379                               &aTexture, &(aTexture.ImageFileName()), entry->iId, iTextures.Count()-1);                     
       
   380                 }
       
   381             else
       
   382                 {
       
   383                 HUI_DEBUG3(_L("CHuiTextureManager::RemoveTexture() - Removing unnamed texture 0x%x  ( Id: %i). Number of textures after deleting: %i."),
       
   384                               &aTexture, entry->iId, iTextures.Count()-1);                     
       
   385                 }
       
   386 
       
   387             iTextures.Remove(index);
       
   388             delete entry;
       
   389             return;
       
   390             }
       
   391         }
       
   392 
       
   393     HUI_DEBUG2(_L("CHuiTextureManager::RemoveTexture() - Error! Failed to remove texture 0x%x \"%S\". Texture not found."), &aTexture, &aTexture.ImageFileName());
       
   394     // this is a programming error.. texturemanager is aware of all textures in the toolkit!!
       
   395     #ifdef _DEBUG
       
   396     HUI_PANIC(THuiPanic::ETextureNotValid)
       
   397     #endif
       
   398     }
       
   399 
       
   400 
       
   401 EXPORT_C CHuiTexture& CHuiTextureManager::LoadTextureL(
       
   402     const TDesC& aImageName,
       
   403     THuiTextureUploadFlags aFlags,
       
   404     TInt aId,
       
   405     TInt aFrameNumber)
       
   406     {
       
   407     return LoadTextureL(aImageName, TSize(0, 0), aFlags, aId, aFrameNumber);
       
   408     }
       
   409 
       
   410 
       
   411 EXPORT_C CHuiTexture& CHuiTextureManager::LoadTextureL(const TInt aId,
       
   412                                        const TSize& aTextureMaxSize,
       
   413                                        THuiTextureUploadFlags aFlags)
       
   414     {
       
   415     return LoadTextureL(KNullDesC(), aTextureMaxSize, aFlags, aId);
       
   416     }
       
   417 
       
   418 
       
   419 EXPORT_C CHuiTexture& CHuiTextureManager::LoadTextureL(const TDesC& aImageName,
       
   420         const TSize& aTextureMaxSize,
       
   421         THuiTextureUploadFlags aFlags,
       
   422         TInt aId,
       
   423         TInt aFrameNumber)
       
   424     {
       
   425     // Ignore EHuiTextureFlagAllowDirectBitmapUsage flag
       
   426    	aFlags = (THuiTextureUploadFlags)(aFlags & ~EHuiTextureFlagAllowDirectBitmapUsage);		
       
   427     
       
   428     TFileName fileName;
       
   429 
       
   430     CTextureEntry * entry = NULL;  
       
   431 
       
   432     // If the name is invalid, and there was no filename available
       
   433     // based on id, return a dummy texture.
       
   434     if((aImageName.Length() == 0) && (aId == 0))
       
   435         {
       
   436         HUI_DEBUG(_L("CHuiTextureManager::LoadTextureL() - No filename or id provided for texture. Returning blank."));
       
   437         return BlankTexture();
       
   438         }
       
   439 
       
   440     // add path to filename if filename has been passed
       
   441     if(aImageName.Length() > 0)
       
   442         {
       
   443         // assume relative pathname and prepend the image path to get full filename
       
   444         fileName = aImageName;
       
   445         PrependImagePath(fileName);
       
   446         }
       
   447 
       
   448     // if no name has been passed as a parameter but
       
   449     // a nonzero id has been passed, we
       
   450     // can assume that there's a predefined name available
       
   451     if((aImageName.Length() == 0) && (aId != 0))
       
   452        {
       
   453         // search for a texture filename based on the id.
       
   454         TInt index = CheckTexture(aId);
       
   455         if(index >=0)
       
   456             {
       
   457             entry = iTextures[index];
       
   458             HUI_ASSERT(entry->iFileName);
       
   459             fileName = *(entry->iFileName);
       
   460             }
       
   461         else
       
   462             {
       
   463             HUI_DEBUG1(_L("CHuiTextureManager::LoadTextureL() - Unable to load texture without filename or pre-defined id (filename definition for id %i not found)."), aId);
       
   464             User::Leave(KErrNotFound);
       
   465             }
       
   466        }
       
   467 
       
   468     // a guarantee that there's a filename available
       
   469     HUI_ASSERT(	fileName.Length()>0 );
       
   470 
       
   471     // Reuse pre-existing entries:
       
   472     // try first finding an entry based on id
       
   473     if(entry == NULL && aId != 0)
       
   474         {
       
   475         TInt previouslyLoadedIndex = CheckTexture(aId);
       
   476         if (previouslyLoadedIndex >= 0)
       
   477             {
       
   478             entry = iTextures[previouslyLoadedIndex];
       
   479             }
       
   480         }
       
   481 
       
   482     // We are not allowed to change required texture id so we can't 
       
   483     // try again with the filename unless user does not care about id
       
   484     if(aId == 0 && entry == NULL)
       
   485         {
       
   486         TInt previouslyLoadedIndex = CheckTexture(fileName, aFrameNumber);
       
   487         if (previouslyLoadedIndex >= 0)
       
   488             {
       
   489             entry = iTextures[previouslyLoadedIndex];
       
   490             }
       
   491         }
       
   492 
       
   493     // create new texture entry if there's not one
       
   494     // available at this point
       
   495     if(entry == NULL)
       
   496         {
       
   497         HUI_DEBUG(_L("CHuiTextureManager::LoadTextureL() - Creating new texture."));
       
   498 
       
   499         // in the case that a previously loaded slot was not found,
       
   500         // create a new texture, which automatically registers a new
       
   501         // texture entry in the iTextures list.
       
   502         CHuiTexture::NewL();
       
   503 
       
   504         // we assume that the newest entry was added the last
       
   505         entry = iTextures[iTextures.Count()-1];
       
   506 
       
   507         entry->iId = aId;
       
   508         }
       
   509     else
       
   510         {
       
   511         // We have a valid texture name and ID.
       
   512         HUI_ASSERT(entry->iTexture);
       
   513       
       
   514         // we have a pre-existing texture,
       
   515         // but check that the texture is loaded ok, we can also
       
   516         // return unloaded textures that are in the load queue
       
   517         if (entry->iTexture->HasContent() || IsInLoadQueue(entry->iTexture))
       
   518             {
       
   519             // a previous texture exists!
       
   520             HUI_ASSERT(entry->iTexture!=NULL);            
       
   521             
       
   522             HUI_DEBUG3(_L("CHuiTextureManager::LoadTextureL() - Reusing texture 0x%x (\"%S\", id: %i) No need to load."),
       
   523                       entry->iTexture, &entry->iTexture->ImageFileName(), entry->iId);
       
   524             return *(entry->iTexture);
       
   525             }
       
   526         }
       
   527 
       
   528     HUI_ASSERT(entry!=NULL);
       
   529     HUI_ASSERT(entry->iTexture!=NULL);
       
   530        
       
   531     // replace filename
       
   532     // File names are relative to the image path.
       
   533     entry->SetFileName(fileName);
       
   534     entry->iTexture->SetImageFileNameL(fileName);
       
   535     entry->iTexture->EnableShadow((aFlags & EHuiTextureUploadFlagGenerateShadow) != 0);
       
   536     entry->iFrameNumber = aFrameNumber;
       
   537 
       
   538     // add a content observer so that we can reload the texture
       
   539     // during restoring
       
   540     if (entry->iTexture->iContentObservers.Count()==0)
       
   541         {
       
   542         HUI_DEBUG2(_L("CHuiTextureManager::LoadTextureL() - Adding content observer 0x%x for texture 0x%x."),  entry, entry->iTexture);
       
   543         entry->iTexture->iContentObservers.AppendL(*entry);
       
   544         }
       
   545 
       
   546     HUI_DEBUG3(_L("CHuiTextureManager::LoadTextureL() - Enqueuing texture 0x%x (Name: \"%S\", Id: %i)."),
       
   547                entry->iTexture, &entry->iTexture->ImageFileName(), entry->iId);
       
   548 
       
   549     // Prepare for loading by creating a load queue entry.
       
   550     SLoadQueueEntry loadqentry;
       
   551     Mem::FillZ(&loadqentry, sizeof(loadqentry));
       
   552     loadqentry.iLoading = entry;
       
   553     entry->iMaxTextureSize = aTextureMaxSize;
       
   554     entry->iFlags = aFlags;
       
   555 
       
   556     // Textures are loaded one at a time, in the order they were requested.
       
   557     User::LeaveIfError( iLoadQueue.Append(loadqentry) );
       
   558 
       
   559     // Start loading images.
       
   560     if(iState == EIdle)
       
   561         {
       
   562         StartLoading();
       
   563         
       
   564         if(iState == ELoading)
       
   565             {
       
   566             // Notify observers that loading has started.
       
   567             NotifyStateChange();
       
   568             }
       
   569         }
       
   570 
       
   571     return *entry->iTexture;
       
   572     }
       
   573 
       
   574 EXPORT_C CHuiTexture&
       
   575 CHuiTextureManager::CreateTextureL(TInt aId,
       
   576                                    MHuiBitmapProvider* aBitmapProvider,
       
   577                                    THuiTextureUploadFlags aFlags)
       
   578     {
       
   579     CHuiTexture* tex;
       
   580     
       
   581     // can't create texture without id (or filename)
       
   582     if (aId==0)
       
   583         {
       
   584         HUI_DEBUG(_L("CHuiTextureManager::CreateTextureL() - ERROR! Can't create texture without valid id. Please use nonzero ids."));
       
   585         User::Leave(KErrArgument);
       
   586         }
       
   587 
       
   588     // Provide an already created texture if such exists.
       
   589     CHuiTexture* texture = NULL;
       
   590     TRAPD(err, texture = TextureL(aId));
       
   591     if(err == KErrNone)
       
   592         {
       
   593         ASSERT( texture );
       
   594 
       
   595         // Update flags here because there is no other way to change flags. 
       
   596         CTextureEntry* entry = TextureEntry(CheckTexture(aId));
       
   597         if (entry)
       
   598             {
       
   599             entry->iFlags = aFlags;        
       
   600             }
       
   601         
       
   602         return *texture;
       
   603         }
       
   604 
       
   605     // Assert that the bitmap provider object exists.
       
   606     HUI_ASSERT(aBitmapProvider != NULL);
       
   607 
       
   608     HUI_DEBUG1(_L("CHuiTextureManager::CreateTextureL() - Requesting bitmap content from provider 0x%x .."), aBitmapProvider);
       
   609 
       
   610     // Initialize bitmap and mask bitmap pointers to zero.
       
   611     CFbsBitmap* bitmap = NULL;
       
   612     CFbsBitmap* maskBitmap = NULL;
       
   613 
       
   614     // Call the bitmapProvider method to load the bitmaps.
       
   615     ASSERT( aBitmapProvider );
       
   616     aBitmapProvider->ProvideBitmapL(aId, bitmap, maskBitmap);
       
   617 
       
   618     // Error if main bitmap could not be loaded
       
   619     User::LeaveIfNull(bitmap);
       
   620     CleanupStack::PushL(bitmap);
       
   621     
       
   622     UpdateFlags(*bitmap, maskBitmap, aFlags);
       
   623     
       
   624     if (maskBitmap)
       
   625         {
       
   626         // A mask was provided, so pass this to texture creation.
       
   627         CleanupStack::PushL(maskBitmap);
       
   628         // create textures right away for these bitmaps
       
   629         tex = &CreateTextureL(*bitmap, maskBitmap, aFlags, aId);
       
   630         // get rid of bitmap and mask
       
   631         CleanupStack::PopAndDestroy(maskBitmap);
       
   632         }
       
   633     else
       
   634         {
       
   635         // No mask, so create texture without one.
       
   636         // create textures right away for these bitmaps
       
   637         tex = &CreateTextureL(*bitmap, NULL, aFlags, aId);            
       
   638         }
       
   639         
       
   640     CleanupStack::PopAndDestroy(bitmap);        
       
   641 
       
   642     // store the provider with the texture for Restore operations
       
   643     HUI_ASSERT(CheckTexture(aId)>=0);
       
   644     CTextureEntry * entry = TextureEntry(CheckTexture(aId));
       
   645     entry->iBitmapProvider = aBitmapProvider;
       
   646     entry->iFlags = aFlags;
       
   647 
       
   648     HUI_ASSERT(entry->iTexture);
       
   649 
       
   650     // add a content observer so that we can reload the texture
       
   651     // during restoring
       
   652     if (entry->iTexture->iContentObservers.Count()==0)
       
   653         {
       
   654         HUI_DEBUG2(_L("CHuiTextureManager::CreateTextureL() - Adding content observer 0x%x for texture 0x%x."),  entry, entry->iTexture);
       
   655         entry->iTexture->iContentObservers.AppendL(*entry);
       
   656         }
       
   657 
       
   658     return *tex;
       
   659     }
       
   660 
       
   661 EXPORT_C CHuiTexture& CHuiTextureManager::CreateTextureL(CFbsBitmap& aBitmap,
       
   662                                    const CFbsBitmap* aMask,
       
   663                                    THuiTextureUploadFlags aFlags,
       
   664                                    TInt aId)
       
   665     {
       
   666     TBool hasAlpha = (aMask != NULL);
       
   667     TSize bitmapSize = aBitmap.SizeInPixels();
       
   668 
       
   669     CHuiStatic::Tic(2);
       
   670 
       
   671     // Verify that the bitmap size is same as the mask size.
       
   672     if(hasAlpha && (bitmapSize != aMask->SizeInPixels()))
       
   673         {
       
   674         HUI_DEBUG(_L("CHuiTextureManager::CreateTextureL() - Bitmap size is not compatible with the mask bitmap!"));
       
   675         User::Leave(KErrArgument);
       
   676         }
       
   677 
       
   678     // Leave if the name and the id are empty.
       
   679     if(aId==0)
       
   680         {
       
   681         HUI_DEBUG(_L("CHuiTextureManager::CreateTextureL() - ERROR! Can't create texture without valid id or name."));
       
   682         User::Leave(KErrArgument);
       
   683         }
       
   684 
       
   685     // If the texture has already been loaded, just return a reference.
       
   686     TInt previouslyLoadedIndex = CheckTexture(aId);
       
   687 
       
   688     if((previouslyLoadedIndex != -1) && IsLoaded(aId))
       
   689         {
       
   690         CHuiTexture * tex = iTextures[previouslyLoadedIndex]->iTexture;
       
   691         HUI_ASSERT(tex);
       
   692         HUI_DEBUG3(_L("CHuiTextureManager::CreateTextureL() - Reusing previously loaded texture (0x%x, \"%S\", id: %i)."),
       
   693                      tex, &tex->ImageFileName(), iTextures[previouslyLoadedIndex]->iId);
       
   694         return *tex;
       
   695         }
       
   696 
       
   697     // create and append to the textures list (automatic)
       
   698     CHuiTexture* texture = CHuiTexture::NewL();
       
   699     // Set texture name
       
   700     texture->SetImageFileNameL(_L(""));
       
   701     // Set the texture id.
       
   702     HUI_ASSERT(TextureEntryCount()>0);
       
   703     CTextureEntry * te = TextureEntry(TextureEntryCount()-1);
       
   704     te->iId = aId;
       
   705 
       
   706     HUI_DEBUG3(_L("CHuiTextureManager::CreateTextureL() - Created new texture 0x%x (\"%S\", id: %i)."),
       
   707                      texture, &texture->ImageFileName(), aId);
       
   708 
       
   709     // Let the texture know its size as soon as possible.
       
   710     texture->SetSize(bitmapSize);
       
   711 
       
   712     HUI_DEBUG6(_L("CHuiTextureManager::CreateTextureL() - Image for texture 0x%x is \"%S\": w=%i, h=%i, dm=%i, mdm=%i"),
       
   713                texture,
       
   714                &texture->ImageFileName(),
       
   715                bitmapSize.iWidth,
       
   716                bitmapSize.iHeight,
       
   717                aBitmap.DisplayMode(),
       
   718                (aMask != NULL ? aMask->DisplayMode() : ENone));
       
   719 
       
   720     // Enable texture shadow.
       
   721     texture->EnableShadow((aFlags & EHuiTextureUploadFlagGenerateShadow) != 0);
       
   722 
       
   723 	if (bitmapSize.iWidth != 0 && bitmapSize.iHeight != 0)
       
   724 	    {
       
   725     	if (aFlags & EHuiTextureFlagAllowDirectBitmapUsage) 
       
   726     		{
       
   727        		texture->UploadDirectL(aBitmap, aMask, aFlags);		
       
   728     		}
       
   729     	else 
       
   730     		{
       
   731        		texture->UploadL(aBitmap, aMask, aFlags);		
       
   732     		}
       
   733 
       
   734 	    }
       
   735 
       
   736     HUI_DEBUG1(_L("CHuiTextureManager::CreateTextureL() - Upload for texture 0x%x done, notifying possible observers.."), texture);
       
   737 
       
   738     // Store bits per pixel info to calculate texture memory usage
       
   739     te->iBitDepth = TDisplayModeUtils::NumDisplayModeBitsPerPixel( aBitmap.DisplayMode() );
       
   740     if( aMask )
       
   741     	{
       
   742     	 te->iBitDepth =  te->iBitDepth + TDisplayModeUtils::NumDisplayModeBitsPerPixel( aMask->DisplayMode() );
       
   743     	}
       
   744 
       
   745     // Notify the observers
       
   746     NotifyTextureLoaded(*texture, aId, KErrNone);
       
   747 
       
   748     HUI_DEBUG2(_L("CHuiTextureManager::CreateTextureL() - Finished with texture 0x%x, toc: %f seconds"), texture, CHuiStatic::Toc(2));
       
   749     return *texture;
       
   750     }
       
   751 
       
   752 
       
   753 EXPORT_C void CHuiTextureManager::UpdateTextureFromBitmapL(TInt aId, MHuiBitmapProvider* aBitmapProvider)
       
   754     {
       
   755     TInt previouslyLoadedIndex = CheckTexture(aId);
       
   756     if (previouslyLoadedIndex == KErrNotFound)
       
   757     	{
       
   758     	User::Leave(KErrNotFound);
       
   759     	}
       
   760 
       
   761 	// Unload
       
   762 	
       
   763     UnloadTexture(aId);      
       
   764 
       
   765 	// Upload with the new content
       
   766 	
       
   767 	CTextureEntry* entry = iTextures[previouslyLoadedIndex];
       
   768     
       
   769     HUI_DEBUG1(_L("CHuiTextureManager::UpdateTextureFromBitmapL() - Requesting bitmap content from provider 0x%x .."), aBitmapProvider);
       
   770 
       
   771     // Initialize bitmap and mask bitmap pointers to zero.
       
   772     CFbsBitmap* bitmap = NULL;
       
   773     CFbsBitmap* maskBitmap = NULL;
       
   774 
       
   775     // Call the bitmapProvider method to load the bitmaps.
       
   776     if (!aBitmapProvider)
       
   777     	{
       
   778     	aBitmapProvider = entry->iBitmapProvider;
       
   779     	}
       
   780     if (aBitmapProvider)
       
   781     	{
       
   782    	    aBitmapProvider->ProvideBitmapL(aId, bitmap, maskBitmap);
       
   783     	}
       
   784 
       
   785     // Error if main bitmap could not be loaded
       
   786     if (!bitmap)
       
   787     	{
       
   788     	User::Leave(KErrNotFound);
       
   789     	}
       
   790     CleanupStack::PushL(bitmap);
       
   791     
       
   792     if (maskBitmap)
       
   793         {
       
   794         CleanupStack::PushL(maskBitmap);
       
   795         }
       
   796 
       
   797     TBool hasAlpha = (maskBitmap != NULL);
       
   798     TSize bitmapSize = bitmap->SizeInPixels();
       
   799 
       
   800     CHuiStatic::Tic(2);
       
   801 
       
   802     // Verify that the bitmap size is same as the mask size.
       
   803     if(hasAlpha && (bitmapSize != maskBitmap->SizeInPixels()))
       
   804         {
       
   805         HUI_DEBUG(_L("CHuiTextureManager::UpdateTextureFromBitmapL() - Bitmap size is not compatible with the mask bitmap!"));
       
   806         User::Leave(KErrArgument);
       
   807         }
       
   808 
       
   809     CHuiTexture* texture = entry->iTexture;
       
   810     // Set texture name
       
   811     texture->SetImageFileNameL(_L(""));
       
   812 
       
   813     HUI_DEBUG6(_L("CHuiTextureManager::UpdateTextureFromBitmapL() - Image for texture 0x%x is \"%S\": w=%i, h=%i, dm=%i, mdm=%i"),
       
   814                texture,
       
   815                &texture->ImageFileName(),
       
   816                bitmapSize.iWidth,
       
   817                bitmapSize.iHeight,
       
   818                bitmap->DisplayMode(),
       
   819                (maskBitmap != NULL ? maskBitmap->DisplayMode() : ENone));
       
   820 
       
   821     UpdateFlags(*bitmap, maskBitmap, entry->iFlags);
       
   822     
       
   823 	if (bitmapSize.iWidth != 0 && bitmapSize.iHeight != 0)
       
   824 	    {
       
   825     	if (entry->iFlags & EHuiTextureFlagAllowDirectBitmapUsage) 
       
   826     		{
       
   827        		texture->UploadDirectL(*bitmap, maskBitmap, entry->iFlags);		
       
   828     		}
       
   829     	else 
       
   830     		{
       
   831        		texture->UploadL(*bitmap, maskBitmap, entry->iFlags);		
       
   832     		}
       
   833 	    }
       
   834     HUI_DEBUG2(_L("CHuiTextureManager::UpdateTextureFromBitmapL() - Finished with texture 0x%x, toc: %f seconds"), texture, CHuiStatic::Toc(2));
       
   835      
       
   836     // Store bits per pixel info to calculate texture memory usage
       
   837     entry->iBitDepth = TDisplayModeUtils::NumDisplayModeBitsPerPixel( bitmap->DisplayMode() );
       
   838     if (maskBitmap)
       
   839     	{
       
   840     	entry->iBitDepth = entry->iBitDepth + TDisplayModeUtils::NumDisplayModeBitsPerPixel( maskBitmap->DisplayMode() );
       
   841     	}
       
   842     
       
   843     if (maskBitmap)    
       
   844     	{
       
   845     	CleanupStack::PopAndDestroy(maskBitmap);   	
       
   846     	}
       
   847     	
       
   848     CleanupStack::PopAndDestroy(bitmap);        
       
   849     
       
   850     // Store provider in case it has changed
       
   851     if (aBitmapProvider)
       
   852     	{
       
   853     	entry->iBitmapProvider = aBitmapProvider;
       
   854     	}
       
   855    }
       
   856     
       
   857  
       
   858 void CHuiTextureManager::UpdateFlags(const CFbsBitmap& aBitmap, const CFbsBitmap* aMaskBitmap, 
       
   859 	                                 THuiTextureUploadFlags& aFlags)
       
   860 	{
       
   861 	// Update EHuiTextureFlagUseBitmapDirectly flag if needed
       
   862 	
       
   863 	if (aFlags & EHuiTextureFlagAllowDirectBitmapUsage)
       
   864 		{
       
   865 		TBool isDirectBitmapOk = !aBitmap.IsCompressedInRAM() && 
       
   866 		                     (!aMaskBitmap || !aMaskBitmap->IsCompressedInRAM());
       
   867 		// Check texture formats from the display
       
   868 		// Note: if there is no display the check cannot be done
       
   869 		if (isDirectBitmapOk)
       
   870 			{
       
   871 			isDirectBitmapOk = EFalse;		
       
   872 			if (CHuiStatic::Env().DisplayCount() > 0)
       
   873 				{
       
   874 				RPointerArray<CHuiDisplay::CTextureBitmapFormat> formatArray;
       
   875     			TInt err = CHuiStatic::Env().PrimaryDisplay().GetPreferredTextureFormats(formatArray);
       
   876     			if (!err)
       
   877     				{
       
   878     				for (TInt i = 0; i < formatArray.Count(); i++)
       
   879     					{
       
   880    			   			if ((aBitmap.DisplayMode() == formatArray[i]->iImage) &&
       
   881    			   				((!aMaskBitmap) || (aMaskBitmap->DisplayMode() == formatArray[i]->iMask)))
       
   882    			   				{
       
   883    			   				isDirectBitmapOk = ETrue;
       
   884    			   				}
       
   885     					}
       
   886 					}
       
   887 				formatArray.ResetAndDestroy();
       
   888 				}
       
   889 			}
       
   890 		// Update	
       
   891 		if (!isDirectBitmapOk)
       
   892 			{
       
   893    			aFlags = (THuiTextureUploadFlags)(aFlags & ~EHuiTextureFlagAllowDirectBitmapUsage);		
       
   894 			}
       
   895 		}
       
   896 	}
       
   897 
       
   898     
       
   899 RFs& CHuiTextureManager::FsSession() const
       
   900     {
       
   901     return iFS;
       
   902     }
       
   903 
       
   904 
       
   905 EXPORT_C void CHuiTextureManager::PrependImagePath(TDes& aFileName) const
       
   906     {
       
   907     TFileName buf;
       
   908 
       
   909     //allow app to load textures from different drive with complete path
       
   910     TParse p1;
       
   911     p1.Set(aFileName,0,0);
       
   912 
       
   913     if (p1.DrivePresent())
       
   914         {
       
   915         return;
       
   916         }
       
   917 
       
   918     if(aFileName.Find(*iImagePath) == KErrNotFound)
       
   919         {
       
   920         buf = *iImagePath;
       
   921         buf.Append(aFileName);
       
   922         aFileName = buf;
       
   923         }
       
   924     }
       
   925 
       
   926 
       
   927 EXPORT_C void CHuiTextureManager::UnloadTexture(const TDesC& aImageName, const TInt aFrameNumber)
       
   928     {
       
   929     TFileName fileName = aImageName;
       
   930     PrependImagePath(fileName);
       
   931     TInt index = CheckTexture(fileName, aFrameNumber);
       
   932     if (index >= 0)
       
   933         {
       
   934         HUI_DEBUG2(_L("CHuiTextureManager::UnloadTexture() - Unloading texture 0x%x (id: %i)."),
       
   935                    iTextures[index]->iTexture,
       
   936                    iTextures[index]->iId);
       
   937         DoUnload(index);
       
   938         return;
       
   939         }
       
   940     HUI_DEBUG1(_L("CHuiTextureManager::UnloadTexture() - Warning! Unable to unload \"%S\" - No such texture(s) found. Already unloaded?"), &fileName);
       
   941     }
       
   942 
       
   943 
       
   944 EXPORT_C void CHuiTextureManager::UnloadTexture(TInt aId)
       
   945     {
       
   946     TInt index = CheckTexture(aId);
       
   947     if (index >= 0)
       
   948         {
       
   949         HUI_DEBUG2(_L("CHuiTextureManager::UnloadTexture() - Unloading texture 0x%x (id: %i)."),
       
   950                    iTextures[index]->iTexture,
       
   951                    iTextures[index]->iId);
       
   952         DoUnload(index);
       
   953         return;
       
   954         }
       
   955     HUI_DEBUG1(_L("CHuiTextureManager::UnloadTexture() - Warning! Unable to unload id %i. No texture with such id. Already unloaded?"), aId);
       
   956     }
       
   957 
       
   958 
       
   959 EXPORT_C void CHuiTextureManager::DefineFileNameL(TInt aId,
       
   960                                                   const TDesC& aImageName)
       
   961     {
       
   962     if (aId==0)
       
   963         {
       
   964         HUI_DEBUG(_L("CHuiTextureManager::DefineFileNameL() - ERROR! Defining filename for texture id 0 is not allowed. Please use nonzero ids."));
       
   965         User::Leave(KErrArgument); // can't specify filename for "no id"
       
   966         }
       
   967 
       
   968     // Look for an existing entry for the id.
       
   969     for(TInt i = 0; i < iTextures.Count(); ++i)
       
   970         {
       
   971         if(iTextures[i]->iId == aId)
       
   972             {
       
   973             // Just set the new image name.
       
   974             iTextures[i]->SetFileName(aImageName);
       
   975             return;
       
   976             }
       
   977         }
       
   978 
       
   979     // create a new texture, which automatically registers a new
       
   980     // texture entry in the iTextures list.
       
   981     CHuiTexture::NewL();
       
   982     // we assume that the newest entry was added last
       
   983     CTextureEntry* entry = iTextures[iTextures.Count()-1];
       
   984     entry->iId = aId;
       
   985     entry->SetFileName(aImageName);
       
   986     }
       
   987 
       
   988 
       
   989 EXPORT_C TInt CHuiTextureManager::CheckTexture(const TDesC& aImageName, TInt aFrameNumber) const
       
   990     {
       
   991     if(aImageName.Length()==0)
       
   992         {
       
   993         // name empty, can't check
       
   994         return -1;
       
   995         }
       
   996     for(TInt i = 0; i < iTextures.Count(); ++i)
       
   997         {
       
   998         CTextureEntry * te = iTextures[i];
       
   999         // compare against texture manager entry filename (iFileName)
       
  1000         if((te->iFileName != NULL)
       
  1001             && (aImageName.Compare(*(te->iFileName)) == 0)
       
  1002             && te->iFrameNumber == aFrameNumber)
       
  1003             {
       
  1004             return i;
       
  1005             }
       
  1006 
       
  1007         // compare against texture object imagefilename
       
  1008         if( te->iTexture 
       
  1009             && te->iTexture->ImageFileName().Compare(aImageName) == 0
       
  1010             && te->iTexture->iFrameNumber == aFrameNumber)
       
  1011             {
       
  1012             return i;
       
  1013             }
       
  1014         }
       
  1015     // not found
       
  1016     return -1;
       
  1017     }
       
  1018 
       
  1019 
       
  1020 EXPORT_C TInt CHuiTextureManager::CheckTexture(TInt aId) const
       
  1021     {
       
  1022     if(aId == 0)
       
  1023         {
       
  1024         // id not defined, can't search
       
  1025         return -1;
       
  1026         }
       
  1027     for(TInt i = 0; i < iTextures.Count(); ++i)
       
  1028         {
       
  1029         if(iTextures[i]->iId == aId)
       
  1030             {
       
  1031             return i;
       
  1032             }
       
  1033         }
       
  1034     // not found:
       
  1035     return -1;
       
  1036     }
       
  1037 
       
  1038 
       
  1039 TBool CHuiTextureManager::IsInLoadQueue(const CHuiTexture * texture) const
       
  1040     {
       
  1041 
       
  1042     if (texture == NULL)
       
  1043         {
       
  1044         return EFalse;
       
  1045         }
       
  1046 
       
  1047     // textures in the load queue are not loaded yet,
       
  1048     // the others are assumed to be loaded..
       
  1049     for(TInt i = 0; i < iLoadQueue.Count(); ++i)
       
  1050         {
       
  1051         CTextureEntry* textureEntry = iLoadQueue[i].iLoading;
       
  1052         if(textureEntry->iTexture == texture)
       
  1053             {
       
  1054             // Still in the queue.
       
  1055             return ETrue;
       
  1056             }
       
  1057         }
       
  1058     return EFalse;
       
  1059     }
       
  1060 
       
  1061 TBool CHuiTextureManager::IsInLoadQueue(TInt id) const
       
  1062     {
       
  1063     // textures in the load queue are not loaded yet,
       
  1064     // the others are assumed to be loaded..
       
  1065     for(TInt i = 0; i < iLoadQueue.Count(); ++i)
       
  1066         {
       
  1067         if(iLoadQueue[i].iLoading->iId == id)
       
  1068             {
       
  1069             // Still in the queue.
       
  1070             return ETrue;
       
  1071             }
       
  1072         }
       
  1073     return EFalse;
       
  1074     }
       
  1075 
       
  1076 
       
  1077 void CHuiTextureManager::StartLoading()
       
  1078     {
       
  1079     // Start the texture load active object if we're not loading
       
  1080     if(iState == EIdle)
       
  1081         {
       
  1082         HUI_DEBUG(_L("CHuiTextureManager::StartLoading() - Starting load queue."));
       
  1083 
       
  1084         // loop that finds next entry to load
       
  1085         while (1)
       
  1086             {            
       
  1087             HUI_DEBUG(_L("CHuiTextureManager::StartLoading() - Find next to be loaded."));
       
  1088             
       
  1089             // try to schedule next image for loading..
       
  1090             TRAPD(err, DoLoadNextL());
       
  1091             // ok?
       
  1092                 
       
  1093             if(err != KErrNone)
       
  1094                 {
       
  1095                 HUI_DEBUG(_L("CHuiTextureManager::StartLoading() - Found an error."));
       
  1096                 
       
  1097                 HUI_ASSERT(iLoadQueue.Count()>0);
       
  1098                 // remove the entry from the queue
       
  1099                 SLoadQueueEntry entry = PopLoadedQueueEntry();
       
  1100                 switch (err)
       
  1101                     {
       
  1102                     case KErrNoMemory:
       
  1103                         {
       
  1104                         HUI_DEBUG3( _L("CHuiTextureManager::StartLoading() - Unable to start loading \"%S\" (id %i): Out of memory. Trying to continue with %i items in the queue.."), &(entry.iLoading->iTexture->ImageFileName()), entry.iLoading->iId, iLoadQueue.Count());
       
  1105                         break;
       
  1106                         }
       
  1107                     default:
       
  1108                         {
       
  1109                         HUI_DEBUG4( _L("CHuiTextureManager::StartLoading() - Unable to start loading \"%S\" (id %i): Leave error code %i. Trying to continue with %i items in the queue.."), &(entry.iLoading->iTexture->ImageFileName()), entry.iLoading->iId, err, iLoadQueue.Count());
       
  1110                         break;
       
  1111                         }
       
  1112                     }
       
  1113                 // Notify observers about the image loading error
       
  1114                 NotifyTextureLoaded(*entry.iLoading->iTexture, entry.iLoading->iId, err);
       
  1115                 // Image loading has been completed.
       
  1116                 iState = EIdle;
       
  1117                 continue;
       
  1118                 }
       
  1119             else
       
  1120                 {
       
  1121                 HUI_DEBUG(_L("CHuiTextureManager::StartLoading() - Found next texture to load."));
       
  1122                 if(iLoadQueue.Count() == 0 && iLoadQueueHadValidTexture)
       
  1123                     {
       
  1124                     // During the load loop that has passed we have succesfully started to load
       
  1125                     // at least one texture. So the state has been changed to ELoading, thus
       
  1126                     // it is now changed back to EIdle.
       
  1127                     NotifyStateChange();
       
  1128                     iLoadQueueHadValidTexture = EFalse;
       
  1129                     }
       
  1130                 }
       
  1131                 
       
  1132             // leave the loop if we had no trouble scheduling the next
       
  1133             // image decode
       
  1134             break;
       
  1135             }
       
  1136 
       
  1137         HUI_DEBUG(_L("CHuiTextureManager::StartLoading() - Load queue started."));
       
  1138         }                     
       
  1139     }
       
  1140 
       
  1141 
       
  1142 CHuiTextureManager::SLoadQueueEntry CHuiTextureManager::PopLoadedQueueEntry()
       
  1143     {
       
  1144     SLoadQueueEntry entry = iLoadQueue[0];
       
  1145     HUI_DEBUG2( _L("CHuiTextureManager::PopLoadedQueueEntry() - Cleaning up load queue entry for \"%S\" (id %i)."),
       
  1146                 &(entry.iLoading->iTexture->ImageFileName()), entry.iLoading->iId);
       
  1147     iLoadQueue.Remove(0);
       
  1148     // Delete the decoder.
       
  1149     delete entry.iDecoder;
       
  1150     entry.iDecoder = 0;
       
  1151     return entry;
       
  1152     }
       
  1153 
       
  1154 
       
  1155 void CHuiTextureManager::DoLoadNextL()
       
  1156     {
       
  1157 	HUI_DEBUG(_L("CHuiTextureManager::DoLoadNextL() - Going into assert."));    
       
  1158     __ASSERT_ALWAYS(iState == EIdle, THuiPanic::Panic(THuiPanic::EInternal));
       
  1159     HUI_DEBUG(_L("CHuiTextureManager::DoLoadNextL() - Survived assert."));
       
  1160 
       
  1161     // Any loading tasks left?
       
  1162     if(iLoadQueue.Count() == 0)
       
  1163         {
       
  1164         HUI_DEBUG(_L("CHuiTextureManager::DoLoadNextL() - No more items to load. Changing state to idle."));
       
  1165         return; // nothing else to be loaded.
       
  1166         }
       
  1167 
       
  1168     // Start timing
       
  1169     CHuiStatic::Tic(2);
       
  1170 
       
  1171     // Manager is now busy.
       
  1172     iState = ELoading;
       
  1173 
       
  1174     HUI_DEBUG(_L("CHuiTextureManager::DoLoadNextL() - Fetching next load queue entry."));
       
  1175 
       
  1176     // Fetch a load queue entry
       
  1177     SLoadQueueEntry& entry = iLoadQueue[0];
       
  1178     CHuiTexture* texture = entry.iLoading->iTexture;
       
  1179     HUI_ASSERT(texture != NULL);
       
  1180     HUI_DEBUG1(_L("CHuiTextureManager::DoLoadNext() - Starting to decode %S"), &texture->ImageFileName());
       
  1181 
       
  1182     // Create a new image decoder for loading the image.
       
  1183     TFileName imageFileName = texture->ImageFileName(); // does not include image path
       
  1184     PrependImagePath(imageFileName);
       
  1185     
       
  1186     delete entry.iDecoder;
       
  1187     entry.iDecoder = NULL;
       
  1188     
       
  1189     TRAPD( err,  entry.iDecoder = CImageDecoder::FileNewL(FsSession(), imageFileName, CImageDecoder::EOptionAlwaysThread) );
       
  1190     
       
  1191     // check for errors..
       
  1192     if(err != KErrNone)
       
  1193         {
       
  1194         // Try to cancel the decoding (if possible)
       
  1195         if(entry.iDecoder)
       
  1196             {
       
  1197             entry.iDecoder->Cancel();
       
  1198             }
       
  1199         switch (err)
       
  1200             {
       
  1201             case KEComErrNoInterfaceIdentified:
       
  1202                 {
       
  1203                 HUI_DEBUG1( _L("CHuiTextureManager::DoLoadNext() - CImageDecoder failed to decode \"%S\". No plugin decoders were found."), &texture->ImageFileName() );
       
  1204                 User::Leave(err); // re-leave with the error
       
  1205                 }
       
  1206             case KErrPathNotFound:
       
  1207                 {
       
  1208                 HUI_DEBUG1( _L("CHuiTextureManager::DoLoadNext() - CImageDecoder failed to decode \"%S\". Path not found."), &texture->ImageFileName() );
       
  1209                 User::Leave(err); // re-leave with the error
       
  1210                 }
       
  1211             case KErrAccessDenied:
       
  1212             case KErrPermissionDenied:
       
  1213                 {
       
  1214                 HUI_DEBUG1( _L("CHuiTextureManager::DoLoadNext() - CImageDecoder failed to decode \"%S\". Access denied."), &texture->ImageFileName() );
       
  1215                 User::Leave(err); // re-leave with the error
       
  1216                 }
       
  1217             case KErrNotFound:
       
  1218                 {
       
  1219                 HUI_DEBUG1( _L("CHuiTextureManager::DoLoadNext() - CImageDecoder failed to decode \"%S\". Resource not found."), &texture->ImageFileName() );
       
  1220                 User::Leave(err); // re-leave with the error
       
  1221                 }
       
  1222             case KErrUnderflow:
       
  1223                 {
       
  1224                 HUI_DEBUG1( _L("CHuiTextureManager::DoLoadNext() - CImageDecoder failed to decode \"%S\". Not enough data in file to identify which plugin decoder to use."), &texture->ImageFileName() );
       
  1225                 User::Leave(err); // re-leave with the error
       
  1226                 }
       
  1227             case KErrNotSupported:
       
  1228                 {
       
  1229                 HUI_DEBUG1( _L("CHuiTextureManager::DoLoadNext() - CImageDecoder failed to decode \"%S\". Format not supported."), &texture->ImageFileName() );
       
  1230                 User::Leave(err); // re-leave with the error
       
  1231                 }
       
  1232             default:
       
  1233                 {
       
  1234                 HUI_DEBUG2( _L("CHuiTextureManager::DoLoadNext() - CImageDecoder failed to decode \"%S\". Unknown error (code %i)."), &texture->ImageFileName(), err );
       
  1235                 User::Leave(err); // re-leave with the error
       
  1236                 }
       
  1237             }
       
  1238         }
       
  1239      
       
  1240     entry.iDecoder->SetDecoderThreadPriority(EPriorityAbsoluteBackgroundNormal);
       
  1241         
       
  1242     // There is a valid texture in the load queue that we now start to load.
       
  1243     iLoadQueueHadValidTexture = ETrue;        
       
  1244         
       
  1245     // from decoder's frame info retrieve the framesize
       
  1246     const TInt frameCount = entry.iDecoder->FrameCount();
       
  1247     entry.iLoading->iFrameCount = frameCount;
       
  1248     if (frameCount && entry.iLoading->iFrameNumber>frameCount)
       
  1249         {
       
  1250         entry.iLoading->iFrameNumber = frameCount-1;
       
  1251         }
       
  1252 
       
  1253     CHuiTextureAnimationState* textureAnimationState = NULL;
       
  1254     
       
  1255     TInt groupId = 0;
       
  1256     TBool foundGroup = FindGroupIdByTextureId( entry.iLoading->iId, groupId );
       
  1257     
       
  1258     if ( frameCount > 1 && NeedsAnimationState( *entry.iDecoder ) )
       
  1259         {
       
  1260         // It's animated texture which needs to be produced sequentially.
       
  1261         if ( !foundGroup )
       
  1262             {
       
  1263             HUI_DEBUG(_L("CHuiTextureManager::DoLoadNextL() - Animation: Group not found."));
       
  1264 
       
  1265             if ( iAnimationWithoutGroup && 
       
  1266                  iAnimationWithoutGroup->CheckIfCanProduce( 
       
  1267                     imageFileName,
       
  1268                     entry.iLoading->iFrameNumber,
       
  1269                     frameCount ) )
       
  1270                 {
       
  1271                 // use iAnimationWithoutGroup
       
  1272                 }
       
  1273             else
       
  1274                 {
       
  1275                 delete iAnimationWithoutGroup;
       
  1276                 iAnimationWithoutGroup = NULL;
       
  1277                 
       
  1278                 iAnimationWithoutGroup = 
       
  1279                     CHuiTextureAnimationState::NewL( 
       
  1280                         0, imageFileName, frameCount );
       
  1281                 }
       
  1282             textureAnimationState = iAnimationWithoutGroup;
       
  1283             }
       
  1284         else
       
  1285             {
       
  1286             HUI_DEBUG(_L("CHuiTextureManager::DoLoadNextL() - Animation: Group found."));
       
  1287             textureAnimationState = CreateAnimationStateL( 
       
  1288                 groupId, imageFileName, 
       
  1289                 entry.iLoading->iFrameNumber, frameCount );
       
  1290             }
       
  1291         }
       
  1292     else
       
  1293         {
       
  1294         // No need to produce sequentially.
       
  1295         if ( foundGroup )
       
  1296             {
       
  1297             RemoveAnimationState( FindAnimationState( groupId ) );
       
  1298             }
       
  1299         }
       
  1300 
       
  1301     if ( textureAnimationState != iAnimationWithoutGroup )
       
  1302         {
       
  1303         delete iAnimationWithoutGroup;
       
  1304         iAnimationWithoutGroup = NULL;
       
  1305         }
       
  1306 
       
  1307     const TInt frameToBeLoaded = 
       
  1308         !textureAnimationState ? 
       
  1309         entry.iLoading->iFrameNumber : 
       
  1310         textureAnimationState->GetNextFrameNumber();
       
  1311         
       
  1312     TFrameInfo frameInfo(entry.iDecoder->FrameInfo(frameToBeLoaded));
       
  1313     entry.iLoading->iFrameInterval = frameInfo.iDelay.Int64();
       
  1314 
       
  1315     if ( textureAnimationState )
       
  1316         {
       
  1317         textureAnimationState->OfferNextFrameInfo( frameInfo );
       
  1318         }
       
  1319     
       
  1320     // check for alpha channel
       
  1321     // Gifs don't have alpha but support tranparency so the alpha flag is ignored currently
       
  1322     if(frameInfo.iFlags & TFrameInfo::ETransparencyPossible/* &&
       
  1323             frameInfo.iFlags & TFrameInfo::EAlphaChannel*/)
       
  1324         {
       
  1325         entry.iHasAlpha = ETrue;
       
  1326         }
       
  1327     else
       
  1328         {
       
  1329         entry.iHasAlpha = EFalse;
       
  1330         }
       
  1331 
       
  1332     // Get the image original size
       
  1333     TRect bitmapSize = frameInfo.iFrameCoordsInPixels;
       
  1334     TSize overallSize = 
       
  1335         !textureAnimationState ? 
       
  1336             bitmapSize.Size() : 
       
  1337             textureAnimationState->OverallSize();
       
  1338     
       
  1339     entry.iOriginalSize = overallSize;
       
  1340 
       
  1341     HUI_DEBUG6(_L("CHuiTextureManager::DoLoadNext() - (sub)Image %S (id %i): w=%i, h=%i, bpp=%i, dm=%i"),
       
  1342                &texture->ImageFileName(),
       
  1343                entry.iLoading->iId,
       
  1344                bitmapSize.Size().iWidth,
       
  1345                bitmapSize.Size().iHeight,
       
  1346                frameInfo.iBitsPerPixel,
       
  1347                frameInfo.iFrameDisplayMode);
       
  1348 
       
  1349     HUI_DEBUG(_L("CHuiTextureManager::DoLoadNext() - Setting logical size of the bitmap."));
       
  1350 
       
  1351     // Try to assign the original size to the image
       
  1352     texture->SetSize(overallSize);
       
  1353 
       
  1354     // target resolution for texture, initially equal to bitmap size
       
  1355     TInt widthResolutionTarget = overallSize.iWidth;
       
  1356     TInt heightResolutionTarget = overallSize.iHeight;
       
  1357 
       
  1358     TSize maxTexSize = entry.iLoading->iMaxTextureSize;
       
  1359 
       
  1360     // Assign new texture resolution target dimensions
       
  1361     // if we have explicitly requested them
       
  1362     if( (entry.iLoading->iFlags & EHuiTextureUploadFlagDoNotRetainResolution)
       
  1363             && maxTexSize.iWidth > 0
       
  1364             && maxTexSize.iHeight > 0)
       
  1365         {
       
  1366         HUI_DEBUG3(_L("CHuiTextureManager::DoLoadNext() - Custom texture size for image %S: w=%i, h=%i"),
       
  1367                    &texture->ImageFileName(),
       
  1368                    maxTexSize.iWidth,
       
  1369                    maxTexSize.iHeight);
       
  1370 
       
  1371         // assign new target resolution for decoder-based scaling
       
  1372         if(maxTexSize.iWidth < widthResolutionTarget)
       
  1373             {
       
  1374             widthResolutionTarget = maxTexSize.iWidth;
       
  1375             }
       
  1376         if(maxTexSize.iHeight < heightResolutionTarget)
       
  1377             {
       
  1378             heightResolutionTarget = maxTexSize.iHeight;
       
  1379             }
       
  1380         }
       
  1381 
       
  1382     // Set up segmentation so we know what kind of texture (and texture
       
  1383     // size) we are dealing with
       
  1384     texture->SetupSegmentsL(overallSize,
       
  1385                            TSize(widthResolutionTarget, heightResolutionTarget),
       
  1386                            entry.iLoading->iFlags);
       
  1387 
       
  1388     // we can do direct decoder-based scaling,
       
  1389     // if only a single segment texture is used
       
  1390     if( !textureAnimationState &&
       
  1391         texture->SegmentCount() == 1 &&
       
  1392         (texture->SegmentTextureSize(0).iWidth < bitmapSize.Size().iWidth ||
       
  1393          texture->SegmentTextureSize(0).iHeight < bitmapSize.Size().iHeight))
       
  1394         {
       
  1395 
       
  1396         // assign new texture size target dimensions from the calculated segment 0
       
  1397         widthResolutionTarget = texture->SegmentTextureSize(0).iWidth;
       
  1398         heightResolutionTarget = texture->SegmentTextureSize(0).iHeight;
       
  1399 
       
  1400         // we need to do some downscaling, but can we do arbitrary
       
  1401         // scaling as well?
       
  1402         if(frameInfo.iFlags & TFrameInfo::EFullyScaleable)
       
  1403             {
       
  1404             // .. yes, arbitrary scaling is possible
       
  1405             // just assign the new size to the bitmap
       
  1406             // so that it will be scaled accordingly during
       
  1407             // conversion
       
  1408             HUI_DEBUG3(_L("CHuiTextureManager::DoLoadNext() - Downscaling image %S to size %ix%i."),
       
  1409                        &texture->ImageFileName(),
       
  1410                        widthResolutionTarget,
       
  1411                        heightResolutionTarget);
       
  1412             }
       
  1413         else
       
  1414             {
       
  1415             // all decoders should be able to do 1/2, 1/4, 1/8 DCT Scaling
       
  1416             // calculate nearest half size for the decoder-downscaled bitmap
       
  1417             // halve image width&height to size which is closest larger match
       
  1418             // of the bitmap size
       
  1419             TInt halvedWidth = bitmapSize.Size().iWidth;
       
  1420             TInt halvedHeight = bitmapSize.Size().iHeight;
       
  1421             TInt halveFactor = 1; // this limits the halving to 1/8 max
       
  1422             while ( ((halvedWidth >> 1) > widthResolutionTarget) &&
       
  1423                     ((halvedHeight >> 1) > heightResolutionTarget)
       
  1424                     && (halveFactor << 1) <= 8)
       
  1425                 {
       
  1426                 halveFactor <<= 1;
       
  1427                 }
       
  1428             halvedWidth = halvedWidth / halveFactor;
       
  1429             halvedHeight = halvedHeight / halveFactor;
       
  1430             // .. the bitmap will be downscaled further to the correct
       
  1431             // dimensions by ImageLoadingCompleteL after the bitmap has been decoded
       
  1432             HUI_DEBUG4(_L("CHuiTextureManager::DoLoadNext() - Halving image %S size to %ix%i (factor %i)."),
       
  1433                        &texture->ImageFileName(),
       
  1434                        halvedWidth,
       
  1435                        halvedHeight, halveFactor);
       
  1436             widthResolutionTarget = halvedWidth;
       
  1437             heightResolutionTarget = halvedHeight;
       
  1438             }
       
  1439         }
       
  1440     else
       
  1441         {
       
  1442         // either multi-segmented or no need for scaling..
       
  1443         HUI_DEBUG(_L("CHuiTextureManager::DoLoadNext() - Decoder-based downscaling not required/possible."));
       
  1444         }
       
  1445 
       
  1446     if ( textureAnimationState )
       
  1447         {
       
  1448         // we convert subframe completely
       
  1449         widthResolutionTarget = bitmapSize.Size().iWidth;
       
  1450         heightResolutionTarget = bitmapSize.Size().iHeight;
       
  1451         }
       
  1452 
       
  1453     if (!(entry.iLoading->iFlags & EHuiTextureUploadFlagRetainColorDepth) && iBitmap->DisplayMode()!=EColor64K)
       
  1454         {
       
  1455         // (Re)Create the bitmap in EColor64K (16bit) mode to save memory
       
  1456         iBitmap->Create(TSize(widthResolutionTarget, heightResolutionTarget), EColor64K);
       
  1457         }
       
  1458     else if ((entry.iLoading->iFlags & EHuiTextureUploadFlagRetainColorDepth) && iBitmap->DisplayMode()==EColor64K)
       
  1459         {
       
  1460         // (Re)Create the bitmap in EColor16MU (24bit) mode retain the color information
       
  1461         iBitmap->Create(TSize(widthResolutionTarget, heightResolutionTarget), EColor16MU);
       
  1462         }
       
  1463     else
       
  1464         {
       
  1465         // no need to recreate the bitmap, but assign the new size!
       
  1466         iBitmap->Resize(TSize(widthResolutionTarget, heightResolutionTarget));
       
  1467         }
       
  1468 
       
  1469     if (iBitmap->DisplayMode()==EColor64K)
       
  1470         {
       
  1471         HUI_DEBUG(_L("CHuiTextureManager::DoLoadNext() - Decoding to 16bit image to conserve memory."));
       
  1472         }
       
  1473     // Decode ( and rescale ) to bitmap.
       
  1474     if(entry.iHasAlpha)
       
  1475         {
       
  1476         // set the alpha channel bitmap to the same size than the color bitmap
       
  1477         iMaskBitmap->Resize(TSize(widthResolutionTarget, heightResolutionTarget));
       
  1478         entry.iDecoder->Convert(&iStatus, *iBitmap, *iMaskBitmap, frameToBeLoaded);
       
  1479         }
       
  1480     else
       
  1481         {
       
  1482         // Save some memory by making the unused alpha channel bitmap
       
  1483         // very small.
       
  1484         iMaskBitmap->Resize(TSize(4, 4));
       
  1485         entry.iDecoder->Convert(&iStatus, *iBitmap, frameToBeLoaded);
       
  1486         }
       
  1487 
       
  1488     // Wait for completion.
       
  1489     SetActive();
       
  1490 
       
  1491     HUI_DEBUG1(_L("CHuiTextureManager::DoLoadNext() - Exiting, toc %.2f sec"), CHuiStatic::Toc(2));
       
  1492     }
       
  1493 
       
  1494 CHuiTextureAnimationState* CHuiTextureManager::CreateAnimationStateL( 
       
  1495         TInt aGroupId, const TDesC& aImageFile, 
       
  1496         TInt aFrameNumber, TInt aFrameCount )
       
  1497     {
       
  1498     CHuiTextureAnimationState* result = FindAnimationState( aGroupId );
       
  1499     
       
  1500     TBool recreate = !result || !aFrameNumber;
       
  1501     if ( !recreate )
       
  1502         {
       
  1503         // result != NULL => check if result is animation state of some
       
  1504         // previous frame
       
  1505         recreate = 
       
  1506             !result->CheckIfCanProduce( aImageFile, aFrameNumber, aFrameCount );
       
  1507         }
       
  1508         
       
  1509     if ( recreate )
       
  1510         {
       
  1511         // First frame, let's just recreate animation state.
       
  1512         RemoveAnimationState( result );
       
  1513         result = NULL;
       
  1514         
       
  1515         result = CHuiTextureAnimationState::NewL( 
       
  1516             aGroupId, aImageFile, aFrameCount );
       
  1517         CleanupStack::PushL( result );
       
  1518         iAnimations.AppendL( result );
       
  1519         CleanupStack::Pop( result );
       
  1520         }
       
  1521         
       
  1522     return result;
       
  1523     }
       
  1524 
       
  1525 CHuiTextureAnimationState* CHuiTextureManager::FindAnimationState( 
       
  1526         TInt aGroupId )
       
  1527     {
       
  1528     CHuiTextureAnimationState* result = NULL;
       
  1529     const TInt count = iAnimations.Count();
       
  1530     for ( TInt i = 0; i < count; i++ )
       
  1531         {
       
  1532         CHuiTextureAnimationState* state = iAnimations[ i ];
       
  1533         if ( state->OwnerTextureGroupId() == aGroupId )
       
  1534             {
       
  1535             result = state;
       
  1536             break;
       
  1537             }
       
  1538         }
       
  1539     return result;
       
  1540     }
       
  1541 
       
  1542 void CHuiTextureManager::RemoveAnimationState( 
       
  1543         CHuiTextureAnimationState* aState )
       
  1544     {
       
  1545     if ( aState )
       
  1546         {        
       
  1547         TInt pos = iAnimations.Find( aState );
       
  1548         if ( pos != KErrNotFound )
       
  1549             {
       
  1550             iAnimations.Remove( pos );
       
  1551             }
       
  1552         delete aState;
       
  1553         }
       
  1554     }
       
  1555 
       
  1556 TBool CHuiTextureManager::FindGroupIdByTextureId( 
       
  1557         TInt aTextureId, TInt& aGroupId ) const
       
  1558     {
       
  1559     TBool found = EFalse;
       
  1560     const TInt count = iAnimatedTextureGroupItems.Count();
       
  1561     TInt i = 0;
       
  1562     while ( !found && ( i < count ) )
       
  1563         {
       
  1564         const TAnimatedTextureGroupItem& item = iAnimatedTextureGroupItems[ i ];
       
  1565         if ( item.iTextureId == aTextureId )
       
  1566             {
       
  1567             found = ETrue;
       
  1568             aGroupId = item.iGroupId;
       
  1569             }
       
  1570         i++;
       
  1571         }
       
  1572     return found;
       
  1573     }
       
  1574 
       
  1575 TBool CHuiTextureManager::NeedsAnimationState( const CImageDecoder& aDecoder )
       
  1576     {
       
  1577     // If this image contains any special image disposal methods, then
       
  1578     // use animation state.
       
  1579     
       
  1580     const TInt frames = aDecoder.FrameCount();
       
  1581     TBool result = EFalse;
       
  1582     
       
  1583     for ( TInt i = 0; !result && i < frames; ++i )
       
  1584         {
       
  1585         const TFrameInfo& info = aDecoder.FrameInfo( i );
       
  1586         const TUint32 disposalFlags =
       
  1587             info.iFlags & 
       
  1588                 ( TFrameInfo::ELeaveInPlace |
       
  1589                   TFrameInfo::ERestoreToBackground |
       
  1590                   TFrameInfo::ERestoreToPrevious );
       
  1591                   
       
  1592         result = result || disposalFlags;
       
  1593         }
       
  1594     
       
  1595     return result;
       
  1596     }
       
  1597 
       
  1598 void CHuiTextureManager::DoUnload(TInt index)
       
  1599     {
       
  1600     HUI_ASSERT(index>=0 && index < iTextures.Count());
       
  1601     CHuiTexture * t = iTextures[index]->iTexture;
       
  1602     if (t == NULL)
       
  1603         {
       
  1604         HUI_DEBUG1(_L("CHuiTextureManager::UnloadTexture() - Not unloading a NULL texture at index %i."), index);
       
  1605         return;
       
  1606         }
       
  1607 
       
  1608     HUI_DEBUG3(_L("CHuiTextureManager::UnloadTexture() - Unloading texture \"%S\" id %i at index %i."), &t->ImageFileName(), iTextures[index]->iId, index);
       
  1609     // Is this in the queue?
       
  1610     if(IsInLoadQueue(t))
       
  1611         {
       
  1612         // Not loaded yet, can't unload. Mark it as unloaded, though,
       
  1613         // so it will be discarded when the loading completes.
       
  1614         for(TInt i = 0; i < iLoadQueue.Count(); ++i)
       
  1615             {
       
  1616             if(iLoadQueue[i].iLoading->iTexture == t)
       
  1617                 {
       
  1618                 HUI_DEBUG1(_L("CHuiTextureManager::UnloadTexture() - Marking \"%S\" as unloaded (still in the load queue). "), &t->ImageFileName());
       
  1619                 iLoadQueue[i].iUnloaded = ETrue;
       
  1620                 return;
       
  1621                 }
       
  1622             }
       
  1623         }
       
  1624 
       
  1625     // Just delete the contents of the texture
       
  1626     t->Reset();
       
  1627     HUI_ASSERT(!t->HasContent());
       
  1628     }
       
  1629 
       
  1630 
       
  1631 EXPORT_C TInt CHuiTextureManager::RunError( TInt /*aError*/ )
       
  1632     {
       
  1633     // Should never be called, RunL is responsible for handling all error cases
       
  1634     HUI_ASSERT(EFalse);
       
  1635     return KErrNone;
       
  1636     }
       
  1637 
       
  1638 
       
  1639 EXPORT_C void CHuiTextureManager::RunL()
       
  1640     {
       
  1641     if( iReleaseState == EReleased || 
       
  1642         iReleaseState == EPartiallyReleased ||
       
  1643         iReleaseState == EReleasing )
       
  1644         {
       
  1645         // Set the loading state to idle, but do not notify observers of this,
       
  1646         // since we are released.
       
  1647         // This has to be done so that unfinished loading can be restarted in
       
  1648         // the RestoreL().
       
  1649         iState = EIdle;        
       
  1650         // Leave the texture to the load queue and load it again after restore.
       
  1651         return;
       
  1652         }
       
  1653     
       
  1654     TInt status = iStatus.Int();
       
  1655     
       
  1656     if ( status == KErrNone )
       
  1657         {
       
  1658         status = ImageLoadingContinue();
       
  1659         if ( status > KErrNone )
       
  1660             {
       
  1661             HUI_DEBUG(_L("CHuiTextureManager::RunL() - Animation: Continue loading."));
       
  1662             return;
       
  1663             }
       
  1664         }
       
  1665     
       
  1666     // remove the loaded entry from the queue
       
  1667     SLoadQueueEntry entry = PopLoadedQueueEntry();
       
  1668 
       
  1669     // Image loading has been completed.
       
  1670     iState = EIdle;
       
  1671 
       
  1672     // check status
       
  1673     if( status == KErrNone )
       
  1674         {
       
  1675         // ok, we have a loaded image, but
       
  1676         // we still need to do texture uploads
       
  1677         // and possibly some image conversions
       
  1678         TRAPD( err, ImageLoadingCompleteL(entry) );
       
  1679 
       
  1680         if(err != KErrNone)
       
  1681             {
       
  1682             delete iAnimationWithoutGroup;
       
  1683             iAnimationWithoutGroup = NULL;
       
  1684             
       
  1685             switch (err)
       
  1686                 {
       
  1687                 case KErrNoMemory:
       
  1688                     {
       
  1689                     HUI_DEBUG3( _L("CHuiTextureManager::RunL() - ERROR! Failed to convert image to texture. Out of memory in ImageLoadingCompleteL(). Source image was  \"%S\" (id %i). Trying to continue with %i items in the queue.."),
       
  1690                                 &(entry.iLoading->iTexture->ImageFileName()), entry.iLoading->iId, iLoadQueue.Count() );
       
  1691                     break;                                
       
  1692                     }
       
  1693                 default:
       
  1694                     {
       
  1695                     HUI_DEBUG4( _L("CHuiTextureManager::RunL() - Error %i occurred during image upload/conversion to texture. Image filename was: \"%S\" (id %i). Trying to continue with %i items in the queue.."),
       
  1696                                 err, &(entry.iLoading->iTexture->ImageFileName()), entry.iLoading->iId, iLoadQueue.Count() );
       
  1697                     break;
       
  1698                     }
       
  1699                 }
       
  1700             // Notify observers about the image upload error
       
  1701             NotifyTextureLoaded(*entry.iLoading->iTexture, entry.iLoading->iId, err);
       
  1702             }
       
  1703         }
       
  1704     else
       
  1705         {
       
  1706         HUI_DEBUG2( _L("CHuiTextureManager::RunL() - Image decoding error while decoding \"%S\" (id %i). Bypassing image.."), &(entry.iLoading->iTexture->ImageFileName()), entry.iLoading->iId);
       
  1707 
       
  1708         delete iAnimationWithoutGroup;
       
  1709         iAnimationWithoutGroup = NULL;
       
  1710 
       
  1711         // notify sb of failed image load!
       
  1712         NotifyTextureLoaded(*entry.iLoading->iTexture, entry.iLoading->iId, status);
       
  1713         }
       
  1714 
       
  1715     // Continue loading entries.
       
  1716     StartLoading();
       
  1717 
       
  1718     if(iLoadQueue.Count() == 0)
       
  1719         {
       
  1720         HUI_DEBUG(_L("CHuiTextureManager::RunL() - No more images to load, exiting.."));
       
  1721         }
       
  1722     }
       
  1723 
       
  1724 
       
  1725 EXPORT_C void CHuiTextureManager::DoCancel()
       
  1726     {
       
  1727     if(iLoadQueue.Count() > 0)
       
  1728         {
       
  1729         iLoadQueue[0].iDecoder->Cancel();
       
  1730         }
       
  1731         
       
  1732     iState = EIdle;
       
  1733     }
       
  1734 
       
  1735 TInt CHuiTextureManager::ImageLoadingContinue()
       
  1736     {
       
  1737     TInt status = KErrNone;
       
  1738     
       
  1739     const SLoadQueueEntry& entry = iLoadQueue[0];
       
  1740     
       
  1741     TInt groupId = 0;
       
  1742     CHuiTextureAnimationState* state = NULL;
       
  1743     if ( iAnimationWithoutGroup )
       
  1744         {
       
  1745         state = iAnimationWithoutGroup;
       
  1746         }
       
  1747     else if ( FindGroupIdByTextureId( entry.iLoading->iId, groupId ) )
       
  1748         {
       
  1749         state = FindAnimationState( groupId );
       
  1750         }
       
  1751     else
       
  1752         {
       
  1753         // state = NULL;
       
  1754         }
       
  1755         
       
  1756     if ( state && 
       
  1757          ( state->GetNextFrameNumber() != entry.iLoading->iFrameNumber ) )
       
  1758         {
       
  1759         // Someone has asked animated frames not in sequence - 
       
  1760         // very inefficient!
       
  1761         HUI_DEBUG(_L("CHuiTextureManager::ImageLoadingContinue: Frames not requested in sequence."));
       
  1762         TRAP( status, 
       
  1763             state->ProceedWithoutNextFrameL( 
       
  1764                 iBitmap, 
       
  1765                 entry.iHasAlpha ? iMaskBitmap : NULL ) );
       
  1766 
       
  1767         if ( status == KErrNone )
       
  1768             {
       
  1769             // Image loading has been completed.
       
  1770             iState = EIdle;            
       
  1771             StartLoading();
       
  1772             status = 1; // indicate that started loading.
       
  1773             }
       
  1774         }
       
  1775     
       
  1776     return status;
       
  1777     }
       
  1778 
       
  1779 void CHuiTextureManager::ImageLoadingCompleteL(SLoadQueueEntry& aEntry)
       
  1780     {
       
  1781     CHuiTexture* tex = aEntry.iLoading->iTexture;
       
  1782     HUI_ASSERT(tex);
       
  1783     tex->iFrameNumber = aEntry.iLoading->iFrameNumber;
       
  1784     tex->iFrameCount = aEntry.iLoading->iFrameCount;
       
  1785     tex->iFrameInterval = aEntry.iLoading->iFrameInterval;
       
  1786 
       
  1787     if(iReleaseState != ENormal)
       
  1788         {
       
  1789         HUI_DEBUG1(_L("CHuiTextureManager::ImageLoadingCompleteL() - Unable to upload bitmap data for \"%S\". Texture manager has been released."), &tex->ImageFileName());
       
  1790         return;
       
  1791         }
       
  1792        
       
  1793     if ( tex->iFrameCount > 1 )
       
  1794         {
       
  1795         ProcessAnimatedFrameL( aEntry );
       
  1796         }
       
  1797     TBool hasAlpha = aEntry.iHasAlpha;
       
  1798     
       
  1799     delete iAnimationWithoutGroup;
       
  1800     iAnimationWithoutGroup = NULL;
       
  1801 
       
  1802     TSize* maxTexSize = &aEntry.iLoading->iMaxTextureSize;    
       
  1803     if(((maxTexSize->iWidth != 0) && (maxTexSize->iHeight != 0)) && iBitmap->SizeInPixels() != aEntry.iLoading->iMaxTextureSize )
       
  1804         {
       
  1805         // The decoder failed to constrain the texture dimensions properly, due to its internal limitations.
       
  1806         // So we need to scale the texture(s) down further to the correct size.      
       
  1807         
       
  1808         CFbsBitmap* dest = new (ELeave) CFbsBitmap();
       
  1809         CleanupStack::PushL( dest );
       
  1810         User::LeaveIfError( dest->Create(*maxTexSize, iBitmap->DisplayMode()) );
       
  1811         HuiUtil::ScaleFbsBitmapL(*iBitmap, *dest);
       
  1812         CleanupStack::Pop( dest );
       
  1813         delete iBitmap;
       
  1814         iBitmap = dest;
       
  1815 
       
  1816         if( hasAlpha )
       
  1817             {
       
  1818             // Scale the alpha as well.
       
  1819             dest = new (ELeave) CFbsBitmap();   
       
  1820             CleanupStack::PushL( dest );
       
  1821             User::LeaveIfError(
       
  1822                 dest->Create(*maxTexSize, iMaskBitmap->DisplayMode()) );     
       
  1823             HuiUtil::ScaleFbsBitmapL(*iMaskBitmap, *dest);
       
  1824             CleanupStack::Pop( dest );
       
  1825             delete iMaskBitmap;
       
  1826             iMaskBitmap = dest;
       
  1827             }                      
       
  1828         }        
       
  1829 
       
  1830     HUI_DEBUG3(_L("CHuiTextureManager::ImageLoadingCompleteL() - Loading complete for \"%S\". Uploading %ix%i FBS bitmap to texture.."),
       
  1831                &tex->ImageFileName(),
       
  1832                iBitmap->SizeInPixels().iWidth,
       
  1833                iBitmap->SizeInPixels().iHeight);
       
  1834 
       
  1835     // Upload without compression.
       
  1836     tex->UploadL(*iBitmap,
       
  1837                 (hasAlpha? iMaskBitmap: NULL),
       
  1838                  aEntry.iLoading->iFlags);
       
  1839 
       
  1840     // Store bits per pixel info to calculate texture memory usage
       
  1841     aEntry.iLoading->iBitDepth = TDisplayModeUtils::NumDisplayModeBitsPerPixel( iBitmap->DisplayMode() );
       
  1842     if( iMaskBitmap )
       
  1843         {
       
  1844         aEntry.iLoading->iBitDepth = aEntry.iLoading->iBitDepth + 
       
  1845         TDisplayModeUtils::NumDisplayModeBitsPerPixel( iMaskBitmap->DisplayMode() );
       
  1846         }
       
  1847     
       
  1848     // Now we're setting up the real texture, no more placeholder needed
       
  1849     tex->SetPlaceholder(NULL);
       
  1850 
       
  1851     HUI_DEBUG2(_L("CHuiTextureManager::ImageLoadingCompleteL() - ... Upload done. Setting original size of %ix%i pixels."),
       
  1852                aEntry.iOriginalSize.iWidth,
       
  1853                aEntry.iOriginalSize.iHeight);
       
  1854 
       
  1855     // (Re)set the original size of the image as the logical size
       
  1856     tex->SetSize(aEntry.iOriginalSize);
       
  1857 
       
  1858     // Notify the observers of loaded texture
       
  1859     NotifyTextureLoaded(*tex, aEntry.iLoading->iId, KErrNone);
       
  1860 
       
  1861     // Unload, if the unloading was already requested while loading!
       
  1862     if(aEntry.iUnloaded)
       
  1863         {
       
  1864         UnloadTexture(tex->ImageFileName(),tex->iFrameNumber);
       
  1865         }
       
  1866 
       
  1867     HUI_DEBUG(_L("CHuiTextureManager::ImageLoadingCompleteL() - Done. "));
       
  1868     }
       
  1869 
       
  1870 void CHuiTextureManager::ProcessAnimatedFrameL(SLoadQueueEntry& aEntry)
       
  1871     {
       
  1872     // Animated file - produce next frame.
       
  1873     CFbsBitmap* frameBitmap = NULL;
       
  1874     CFbsBitmap* frameMask = NULL;
       
  1875 
       
  1876     // ImageFileName() does not include image path
       
  1877     CHuiTextureAnimationState* state = NULL;
       
  1878     TInt groupId = 0;
       
  1879     if ( iAnimationWithoutGroup )
       
  1880         {
       
  1881         state = iAnimationWithoutGroup;
       
  1882         }
       
  1883     else if ( FindGroupIdByTextureId( aEntry.iLoading->iId, groupId ) )
       
  1884         {
       
  1885         state = FindAnimationState( groupId );
       
  1886         }
       
  1887 
       
  1888     if ( !state )
       
  1889         {
       
  1890         return;
       
  1891         }
       
  1892 
       
  1893     HUI_DEBUG1(_L("CHuiTextureManager::ProcessAnimatedFrameL: Producing next frame (%d)."), 
       
  1894         state->GetNextFrameNumber() );
       
  1895 
       
  1896     state->ProduceNextFrameL( 
       
  1897         frameBitmap, frameMask, 
       
  1898         iBitmap, aEntry.iHasAlpha ? iMaskBitmap : NULL );
       
  1899 
       
  1900     HUI_DEBUG2(_L("CHuiTextureManager::ProcessAnimatedFrameL: Next frame produced (%x, %x)."),
       
  1901         frameBitmap, frameMask );
       
  1902     
       
  1903     aEntry.iHasAlpha = ( frameMask != NULL );
       
  1904     if ( frameBitmap != iBitmap )
       
  1905         {
       
  1906         delete iBitmap;
       
  1907         iBitmap = frameBitmap;
       
  1908         }
       
  1909         
       
  1910     if ( frameMask && (frameMask != iMaskBitmap) )
       
  1911         {
       
  1912         delete iMaskBitmap;
       
  1913         iMaskBitmap = frameMask;
       
  1914         }        
       
  1915     }
       
  1916 
       
  1917 EXPORT_C TInt CHuiTextureManager::LoadQueueCount() const
       
  1918     {
       
  1919     return iLoadQueue.Count();
       
  1920     }
       
  1921 
       
  1922 
       
  1923 EXPORT_C void CHuiTextureManager::AdvanceTime(TReal32 aElapsedTime) const
       
  1924     {
       
  1925     for(TInt i = 0; i < iAnimatedTextures.Count(); ++i)
       
  1926         {
       
  1927         iAnimatedTextures[i].AdvanceTime(aElapsedTime);
       
  1928         }
       
  1929     NotifyTextureAutoSizeObservers();
       
  1930     // Write total memory consumed on rendering textures as an info message,
       
  1931     // if feature is enabled from central repository Rnd flag
       
  1932     if ( iEnableTexMemCalculation )
       
  1933     	{
       
  1934     	TextureMemUsage(); 
       
  1935     	}    
       
  1936     }
       
  1937 
       
  1938 
       
  1939 EXPORT_C void CHuiTextureManager::SetProcessor(CHuiTextureProcessor* aProcessor)
       
  1940     {
       
  1941     // Since we have ownership of the processor, delete the previous one if
       
  1942     // there is one.
       
  1943     if(iProcessor)
       
  1944         {
       
  1945         delete iProcessor;
       
  1946         iProcessor = NULL;
       
  1947         }
       
  1948 
       
  1949     iProcessor = aProcessor;
       
  1950     }
       
  1951 
       
  1952 
       
  1953 EXPORT_C CHuiTextureProcessor& CHuiTextureManager::Processor()
       
  1954     {
       
  1955     if(!iProcessor)
       
  1956         {
       
  1957         THuiPanic::Panic(THuiPanic::ETextureManagerNoProcessor);
       
  1958         }
       
  1959     return *iProcessor;
       
  1960     }
       
  1961 
       
  1962 
       
  1963 void CHuiTextureManager::CancelLoadingOfTexture(CHuiTexture& aTexture)
       
  1964     {
       
  1965     for(TInt i = 0; i < iLoadQueue.Count(); ++i)
       
  1966         {
       
  1967         if(iLoadQueue[i].iLoading->iTexture == &aTexture)
       
  1968             {
       
  1969             // Texture found from the load queue.
       
  1970             if(i == 0 && iState == ELoading)
       
  1971                 {
       
  1972                 // Texture is currently loading
       
  1973                 Cancel();
       
  1974                 PopLoadedQueueEntry();
       
  1975                 StartLoading();                
       
  1976                 }
       
  1977             else
       
  1978                 {
       
  1979                 // Delete the decoder and remove entry.
       
  1980                 delete iLoadQueue[i].iDecoder;
       
  1981                 iLoadQueue.Remove(i);
       
  1982                 }
       
  1983             break;
       
  1984             }
       
  1985         }
       
  1986     }
       
  1987 
       
  1988 
       
  1989 void CHuiTextureManager::NotifyStateChange() const
       
  1990     {
       
  1991     for(TInt index = 0; index < iStateObservers.Count(); ++index)
       
  1992         {
       
  1993         iStateObservers[index].TextureManagerStateChanged(*this);
       
  1994         }
       
  1995     }
       
  1996 
       
  1997 
       
  1998 EXPORT_C void CHuiTextureManager::NotifyTextureLoaded(CHuiTexture& aTexture,
       
  1999                              TInt aTextureId,
       
  2000                              TInt aErrorCode) const
       
  2001     {
       
  2002     aTexture.SetTextureChanged(ETrue);
       
  2003     for(TInt index = 0; index < iLoadObservers.Count(); ++index)
       
  2004         {
       
  2005         iLoadObservers[index].TextureLoadingCompleted(aTexture, aTextureId, aErrorCode);
       
  2006         }
       
  2007     }
       
  2008 
       
  2009 EXPORT_C CHuiTextureManager::CTextureEntry * CHuiTextureManager::TextureEntry(TInt aIndex)
       
  2010     {
       
  2011     // check limits
       
  2012     if ( aIndex < iTextures.Count() )
       
  2013         {
       
  2014         return iTextures[aIndex];
       
  2015         }
       
  2016     else
       
  2017         {
       
  2018         return NULL;
       
  2019         }
       
  2020     }
       
  2021 
       
  2022 EXPORT_C TInt CHuiTextureManager::TextureEntryCount() const
       
  2023     {
       
  2024     return iTextures.Count();
       
  2025     }
       
  2026 
       
  2027 EXPORT_C TBool CHuiTextureManager::Release()
       
  2028     {
       
  2029     HUI_DEBUG(_L("CHuiTextureManager::Release() - Called."));
       
  2030 
       
  2031     HUI_ASSERT(iReleaseState == ENormal);
       
  2032     iReleaseState = EReleasing;
       
  2033     
       
  2034     TBool allReleased = ETrue; // by default, all texures are released.
       
  2035 
       
  2036     // Release all textures. Use an order inverse to creation order.
       
  2037     for(TInt i = iTextures.Count() - 1; i >= 0; --i)
       
  2038         {
       
  2039         CHuiTexture * tex = iTextures[i]->iTexture;
       
  2040         if (tex)
       
  2041             {
       
  2042             // This is called when application goes into the backgrounf
       
  2043             // If release priority is set to 0, the texture should not be released.
       
  2044             if ( tex->Priority() == 0 )
       
  2045                 {
       
  2046                 HUI_DEBUG5(_L("CHuiTextureManager::Release() - Not releasing priority texture 0x%x (\"%S\", id: %i) [%i/%i]"),
       
  2047                           tex, &(tex->ImageFileName()), iTextures[i]->iId, i+1, iTextures.Count());
       
  2048                 allReleased = EFalse;
       
  2049                 }
       
  2050             else
       
  2051                 {     
       
  2052                 HUI_DEBUG5(_L("CHuiTextureManager::Release() - Releasing texture 0x%x (\"%S\", id: %i) [%i/%i]"),
       
  2053                           tex, &(tex->ImageFileName()), iTextures[i]->iId, i+1, iTextures.Count());
       
  2054                 tex->Release();
       
  2055                 }
       
  2056             }
       
  2057         else
       
  2058             {
       
  2059             HUI_DEBUG4(_L("CHuiTextureManager::Release() - Not releasing unloaded texture 0x%x, id: %i) [%i/%i]"),
       
  2060                           tex, iTextures[i]->iId, i+1, iTextures.Count());                
       
  2061             }
       
  2062         }
       
  2063 
       
  2064     HUI_DEBUG(_L("CHuiTextureManager::Release() - Release processor."));
       
  2065 
       
  2066     // Release texture processor.
       
  2067     if(iProcessor)
       
  2068         {
       
  2069         iProcessor->Release();
       
  2070         }
       
  2071 
       
  2072     HUI_ASSERT(iReleaseState == EReleasing);
       
  2073     if ( allReleased )
       
  2074         {
       
  2075         HUI_DEBUG(_L("CHuiTextureManager::Release() - Exiting (EReleased)."));
       
  2076         iReleaseState = EReleased;
       
  2077         }
       
  2078     else
       
  2079         {
       
  2080         HUI_DEBUG(_L("CHuiTextureManager::Release() - Exiting (EPartiallyReleased)."));
       
  2081         iReleaseState = EPartiallyReleased;
       
  2082         }
       
  2083     return allReleased;
       
  2084     }
       
  2085 
       
  2086 
       
  2087 EXPORT_C void CHuiTextureManager::RestoreL()
       
  2088     {
       
  2089     HUI_DEBUG(_L("CHuiTextureManager::RestoreL() - Called."));
       
  2090 
       
  2091     HUI_ASSERT(iReleaseState == EReleased || iReleaseState == EPartiallyReleased );
       
  2092     iReleaseState = ERestoring;
       
  2093 
       
  2094     // Restore texture processor.
       
  2095     if(iProcessor)
       
  2096         {
       
  2097         iProcessor->RestoreL();
       
  2098         }
       
  2099 
       
  2100     // Restore all textures. Use same order as in which the textures were created.
       
  2101     for(TInt i = 0; i < iTextures.Count(); ++i)
       
  2102         {
       
  2103         CHuiTexture * tex = iTextures[i]->iTexture;
       
  2104         if (tex)
       
  2105             {
       
  2106             if ( tex->HasContent() )
       
  2107                 {
       
  2108                 HUI_DEBUG5(_L("CHuiTextureManager::RestoreL() - Alredy has content texture 0x%x (\"%S\", id: %i) [%i/%i]"),
       
  2109                           tex, &(tex->ImageFileName()), iTextures[i]->iId, i+1, iTextures.Count());
       
  2110                 }
       
  2111             else
       
  2112                 {    
       
  2113                 HUI_DEBUG5(_L("CHuiTextureManager::RestoreL() - Restoring texture 0x%x (\"%S\", id: %i) [%i/%i]"),
       
  2114                           tex, &(tex->ImageFileName()), iTextures[i]->iId, i+1, iTextures.Count());
       
  2115                 // Restore the texture.
       
  2116                 tex->RestoreL();
       
  2117                 }
       
  2118             }
       
  2119         else
       
  2120             {
       
  2121             HUI_DEBUG4(_L("CHuiTextureManager::RestoreL() - Not restoring unloaded texture 0x%x, id: %i) [%i/%i]"),
       
  2122                           tex, iTextures[i]->iId, i+1, iTextures.Count());                
       
  2123             }
       
  2124         }
       
  2125 
       
  2126     // Restart loading of textures that still might be in the load queue.
       
  2127     StartLoading();
       
  2128 
       
  2129     HUI_ASSERT(iReleaseState == ERestoring);
       
  2130     iReleaseState = ENormal;
       
  2131     }
       
  2132 
       
  2133 EXPORT_C void CHuiTextureManager::NotifySkinChangedL()
       
  2134     {
       
  2135     for(TInt i = iTextures.Count()-1; i >= 0; i--)
       
  2136         {
       
  2137         CHuiTexture * tex = iTextures[i]->iTexture;
       
  2138         if (tex &&
       
  2139             tex->HasContent() &&
       
  2140             tex->IsSkinContent())
       
  2141             {
       
  2142             tex->Release();
       
  2143             tex->RestoreL();    
       
  2144             }
       
  2145         }            
       
  2146     }
       
  2147 
       
  2148 EXPORT_C TInt CHuiTextureManager::AddAnimatedTextureGroupL( 
       
  2149         const RArray<TInt>& aTextureIds )
       
  2150     {
       
  2151     const TInt count = aTextureIds.Count();
       
  2152     
       
  2153     // Zero ids are not allowed here
       
  2154     for ( TInt j = 0; j < count; j++ )
       
  2155         {
       
  2156         if ( !aTextureIds[ j ] ) 
       
  2157             {
       
  2158             User::Leave( KErrNotSupported );
       
  2159             }
       
  2160         }
       
  2161         
       
  2162     TInt result = 0;
       
  2163     if ( count )
       
  2164         {
       
  2165         result = aTextureIds[ 0 ]; 
       
  2166     
       
  2167         // Reserve space so next loop cannot fail.
       
  2168         iAnimatedTextureGroupItems.ReserveL( 
       
  2169             iAnimatedTextureGroupItems.Count() + aTextureIds.Count() );
       
  2170     
       
  2171         TAnimatedTextureGroupItem item;
       
  2172         item.iGroupId = result;
       
  2173         
       
  2174         for ( TInt i = 0; i < count; i++ )
       
  2175             {
       
  2176             item.iTextureId = aTextureIds[ i ];
       
  2177             
       
  2178             (void)iAnimatedTextureGroupItems.
       
  2179                 Append( item ); // ought not to fail due to Reserve.
       
  2180             }
       
  2181         }
       
  2182         
       
  2183     return result;
       
  2184     }
       
  2185     
       
  2186 EXPORT_C void CHuiTextureManager::RemoveAnimatedTextureGroup( TInt aGroupId )
       
  2187     {
       
  2188     // Remove animated texture group items.
       
  2189     const TInt count = iAnimatedTextureGroupItems.Count();
       
  2190     for ( TInt i = count - 1; i >= 0; --i )
       
  2191         {
       
  2192         if ( iAnimatedTextureGroupItems[ i ].iGroupId == aGroupId )
       
  2193             {
       
  2194             iAnimatedTextureGroupItems.Remove( i );
       
  2195             }
       
  2196         }
       
  2197     
       
  2198     RemoveAnimationState( FindAnimationState( aGroupId ) );
       
  2199     }
       
  2200 
       
  2201 // CHuiTextureManager::CTextureEntry
       
  2202 
       
  2203 CHuiTextureManager::CTextureEntry::CTextureEntry(
       
  2204     TInt aId,
       
  2205     const TFileName & aFileName,
       
  2206     const TSize& aMaxTextureSize,
       
  2207     THuiTextureUploadFlags aFlags,
       
  2208     TInt aFrameNumber )
       
  2209     : iId(aId), iFileName(NULL),
       
  2210       iTexture(NULL),
       
  2211       iMaxTextureSize(aMaxTextureSize), iFlags(aFlags),
       
  2212       iBitmapProvider(NULL),
       
  2213       iFrameNumber(aFrameNumber),
       
  2214       iFrameCount(0),
       
  2215       iFrameInterval(0)
       
  2216     {
       
  2217     SetFileName(aFileName);
       
  2218     }
       
  2219     
       
  2220 CHuiTextureManager::CTextureEntry::CTextureEntry(TInt aId, CHuiTexture * aTexture)
       
  2221                       : iId(aId),
       
  2222                         iFileName(NULL),
       
  2223                         iTexture(aTexture),
       
  2224                         iMaxTextureSize(TSize(0,0)),
       
  2225                         iFlags(EHuiTextureUploadFlagDefault),
       
  2226                         iBitmapProvider(NULL),
       
  2227                         iFrameNumber(0),
       
  2228                         iFrameCount(0),
       
  2229                         iFrameInterval(0)
       
  2230     {
       
  2231     }
       
  2232             
       
  2233 CHuiTextureManager::CTextureEntry::CTextureEntry(const CTextureEntry &aSrc)
       
  2234                       : iId(aSrc.iId),
       
  2235                         iFileName(NULL),
       
  2236                         iTexture(aSrc.iTexture),
       
  2237                         iMaxTextureSize(aSrc.iMaxTextureSize),
       
  2238                         iFlags(aSrc.iFlags),
       
  2239                         iBitmapProvider(NULL),
       
  2240                         iFrameNumber(aSrc.iFrameNumber),
       
  2241                         iFrameCount(0),
       
  2242                         iFrameInterval(0)
       
  2243     {
       
  2244     SetFileName(*aSrc.iFileName);
       
  2245     }
       
  2246             
       
  2247 CHuiTextureManager::CTextureEntry & CHuiTextureManager::CTextureEntry::operator=(const CTextureEntry &aSrc)
       
  2248     {
       
  2249     if ( this == &aSrc )
       
  2250         {
       
  2251         return *this;
       
  2252         }
       
  2253             
       
  2254     iId = aSrc.iId;
       
  2255     if (aSrc.iFileName != NULL)
       
  2256         {
       
  2257         SetFileName(*aSrc.iFileName);
       
  2258         }
       
  2259     iMaxTextureSize = aSrc.iMaxTextureSize;
       
  2260     iFlags = aSrc.iFlags;
       
  2261     iBitmapProvider = aSrc.iBitmapProvider;
       
  2262     iFrameNumber = aSrc.iFrameNumber;
       
  2263     iFrameCount = aSrc.iFrameCount;
       
  2264     iFrameInterval = aSrc.iFrameInterval;
       
  2265     return *this;
       
  2266     }
       
  2267             
       
  2268 EXPORT_C CHuiTextureManager::CTextureEntry::~CTextureEntry()
       
  2269     {
       
  2270     delete iFileName; 
       
  2271     iFileName = NULL;
       
  2272     // CHuiTextureManager deletes the iTexture
       
  2273     }
       
  2274     
       
  2275 void CHuiTextureManager::CTextureEntry::SetFileName(const TFileName & aFileName)
       
  2276     {
       
  2277     delete iFileName;
       
  2278     iFileName = NULL;
       
  2279     if (aFileName.Length()>0)
       
  2280         {
       
  2281         // this might fail and therefore the iFileName is left as NULL.
       
  2282         iFileName = aFileName.Alloc();
       
  2283         }
       
  2284     }
       
  2285 
       
  2286 void CHuiTextureManager::CTextureEntry::TextureContentUploaded(CHuiTexture& /*aTexture*/)
       
  2287     {
       
  2288     }
       
  2289 void CHuiTextureManager::CTextureEntry::TextureContentReleased(CHuiTexture& /*aTexture*/)
       
  2290     {
       
  2291     }
       
  2292 void CHuiTextureManager::CTextureEntry::RestoreTextureContentL(CHuiTexture& aTexture)
       
  2293     {
       
  2294     HUI_DEBUG(_L("CHuiTextureManager::CTextureEntry::RestoreTextureContentL() - Called for entry 0x%x (id: %i)."));
       
  2295     if (iBitmapProvider != NULL)
       
  2296         {
       
  2297         HUI_DEBUG3(_L("CHuiTextureManager::CTextureEntry::RestoreTextureContentL() - Using bitmap provider 0x%x to recreate content for texture 0x%x (id: %i).."), iBitmapProvider, &aTexture, iId);
       
  2298         CFbsBitmap* bitmap = NULL;
       
  2299         CFbsBitmap* maskBitmap = NULL;
       
  2300 
       
  2301         // call the bitmapProvider method to load the bitmaps
       
  2302         iBitmapProvider->ProvideBitmapL(iId, bitmap, maskBitmap);
       
  2303 
       
  2304         if (maskBitmap)
       
  2305             {
       
  2306             CleanupStack::PushL(maskBitmap);
       
  2307             }
       
  2308         
       
  2309         if (!bitmap)
       
  2310             {
       
  2311             User::Leave(KErrArgument);
       
  2312             }
       
  2313         else
       
  2314             {
       
  2315             CleanupStack::PushL(bitmap);
       
  2316             }
       
  2317         
       
  2318         // recreate texture content..
       
  2319 
       
  2320         // Let the texture know its size as soon as possible.
       
  2321         aTexture.SetSize(bitmap->SizeInPixels());
       
  2322 
       
  2323         // Enable texture shadow.
       
  2324         aTexture.EnableShadow((iFlags & EHuiTextureUploadFlagGenerateShadow) != 0);
       
  2325 
       
  2326         // Upload!    
       
  2327         TSize bitmapSize = bitmap->SizeInPixels();
       
  2328     	if (bitmapSize.iWidth != 0 && bitmapSize.iHeight != 0)
       
  2329     	    {
       
  2330     		if (iFlags & EHuiTextureFlagAllowDirectBitmapUsage) 
       
  2331     			{
       
  2332        			aTexture.UploadDirectL(*bitmap, maskBitmap, iFlags);		
       
  2333     			}
       
  2334     		else 
       
  2335     			{
       
  2336             	aTexture.UploadL(*bitmap, maskBitmap, iFlags);
       
  2337     			}
       
  2338     	    }
       
  2339         // Clean up owned bitmaps
       
  2340         CleanupStack::PopAndDestroy(bitmap);        
       
  2341         if (maskBitmap)
       
  2342             {
       
  2343             CleanupStack::PopAndDestroy(maskBitmap);        
       
  2344             }       
       
  2345         }
       
  2346     // check for file-based restore
       
  2347     else if (iFileName != NULL)
       
  2348         {
       
  2349         HUI_DEBUG2(_L("CHuiTextureManager::CTextureEntry::RestoreTextureContentL() - Reloading texture 0x%x from \"%S\".."), &aTexture, iFileName);
       
  2350         CHuiStatic::Env().TextureManager().LoadTextureL(*iFileName, iMaxTextureSize, iFlags, iId);
       
  2351         return;
       
  2352         }
       
  2353     else
       
  2354         {
       
  2355         // for PC lint
       
  2356         }
       
  2357     }
       
  2358 
       
  2359 void CHuiTextureManager::NotifyTextureAutoSizeObservers() const
       
  2360     {
       
  2361     if (!iTextureAutoSizingEnabled)
       
  2362         {
       
  2363         return;
       
  2364         }
       
  2365     
       
  2366     TBool somethingWasReported = EFalse;
       
  2367     TBool anyAutoSizedTexturesExist = EFalse;
       
  2368     
       
  2369     for(TInt index = iTextures.Count() - 1; index >= 0; --index)
       
  2370         {
       
  2371         CTextureEntry * entry = iTextures[index];
       
  2372         if (entry->iTexture)
       
  2373             {
       
  2374             if (entry->iTexture->IsAutoSizeCalculationEnabled())
       
  2375                 {
       
  2376                 anyAutoSizedTexturesExist = ETrue;
       
  2377                 
       
  2378                 // Calculate preferred size from the previous frame data
       
  2379                 THuiRealSize preferredSize = entry->iTexture->CalculateAutoSize();
       
  2380                 
       
  2381                 // Notify observers if preferred size has changed
       
  2382                 if (entry->iTexture->CalculatedAutoSizeChanged())
       
  2383                     {
       
  2384                     HUI_DEBUG3(_L("CHuiTextureManager::NotifyTexturePreferredSizeObservers - To be notified id: %i, width: %f , height %f"), entry->iId, preferredSize.iWidth, preferredSize.iHeight);                    
       
  2385 
       
  2386                     // Notify observers. For now ignore return values.
       
  2387                     for(TInt index = 0; index < iTextureAutoSizeObservers.Count(); ++index)
       
  2388                         {
       
  2389                         iTextureAutoSizeObservers[index].PreferredSizeChanged(*entry->iTexture, entry->iId, preferredSize);
       
  2390                         somethingWasReported = ETrue;
       
  2391                         }            
       
  2392                     }
       
  2393                 
       
  2394                 // Restart preferred size calculations for next frame   
       
  2395                 entry->iTexture->ResetAutoSizeCalculation();        
       
  2396                 }
       
  2397             }
       
  2398         }
       
  2399     
       
  2400     if (somethingWasReported)
       
  2401         {
       
  2402         for(TInt index = 0; index < iTextureAutoSizeObservers.Count(); ++index)
       
  2403             {
       
  2404             iTextureAutoSizeObservers[index].PreferredSizeReportCompleted();                
       
  2405             }                        
       
  2406         }
       
  2407 
       
  2408     // Keep checking autosized textures only if those exist. 
       
  2409     // New textures will enable flag when needed.
       
  2410     iTextureAutoSizingEnabled = anyAutoSizedTexturesExist;
       
  2411     }
       
  2412 
       
  2413 EXPORT_C void CHuiTextureManager::ClearChangedTextures()
       
  2414     {
       
  2415     if (iHasChangedTextures)
       
  2416         {
       
  2417         for(TInt index = iTextures.Count() - 1; index >= 0; --index)
       
  2418             {
       
  2419             CTextureEntry * entry = iTextures[index];
       
  2420             if (entry->iTexture)
       
  2421                 {
       
  2422                 entry->iTexture->TextureClearChanged();
       
  2423                 }
       
  2424             }
       
  2425         iHasChangedTextures = EFalse;        
       
  2426         }
       
  2427     }
       
  2428     
       
  2429 EXPORT_C void CHuiTextureManager::SetHasChangedTextures()
       
  2430     {
       
  2431     iHasChangedTextures = ETrue;    
       
  2432     }
       
  2433 
       
  2434 /*
       
  2435  * Enables/Disables memory usage calculation.
       
  2436  */
       
  2437 EXPORT_C void CHuiTextureManager::EnableTexMemoryCalculation( TBool aEnableTeMemCal )
       
  2438 	{
       
  2439 	iEnableTexMemCalculation = aEnableTeMemCal;
       
  2440 	}
       
  2441 
       
  2442 /*
       
  2443  * Calculates memory used by texturemanager to store all the textures.
       
  2444  * Texture memory is calculated as ( Texture area ) * ( bits per pixel )
       
  2445  * 
       
  2446  * This routine prints info message stating toal no of textures and memory consuption by them.
       
  2447  */
       
  2448 void CHuiTextureManager::TextureMemUsage() const
       
  2449 	{
       
  2450 	TReal32 totalMemUsage = 0;
       
  2451 	TReal32 avgBitDepth = 0;
       
  2452     for(TInt i = 0; i < iTextures.Count(); ++i)
       
  2453         {
       
  2454         if( iTextures[i]->iTexture )
       
  2455             {            
       
  2456             TSize size = iTextures[i]->iTexture->Size();         
       
  2457             totalMemUsage = totalMemUsage + size.iWidth * size.iHeight * iTextures[i]->iBitDepth;   
       
  2458             avgBitDepth = avgBitDepth + iTextures[i]->iBitDepth;
       
  2459             }        
       
  2460         }
       
  2461     
       
  2462     avgBitDepth = avgBitDepth/iTextures.Count();
       
  2463     totalMemUsage = totalMemUsage/8000000;
       
  2464     TBuf<300> buf;
       
  2465     buf.FillZ();
       
  2466     buf.AppendNum( totalMemUsage, TRealFormat( 8, 4 ) );
       
  2467     buf.Append(_L( "MB;By:" ) );
       
  2468     buf.AppendNum( iTextures.Count() );
       
  2469     buf.Append(_L( ";BD:" ) );
       
  2470     buf.AppendNum( avgBitDepth );
       
  2471     User::InfoPrint( buf );      
       
  2472 	}
       
  2473 TInt CHuiTextureManager::EstimatedTextureMemUsage(TInt aAverageBitsPerPixel) const
       
  2474     {
       
  2475     TReal32 averageBytesPerPixel =  TReal32(aAverageBitsPerPixel)/8.f;
       
  2476 	TReal32 totalMemUsage = 0;
       
  2477     TInt pixels = 0;
       
  2478     for(TInt i = 0; i < iTextures.Count(); ++i)
       
  2479         {
       
  2480         // TODO: Exclude NVG textures !
       
  2481         if( iTextures[i]->iTexture /*&& 
       
  2482             iTextures[i]->iTexture->HasContent()*/)
       
  2483             {            
       
  2484             TSize size = iTextures[i]->iTexture->Size();         
       
  2485             pixels += size.iWidth * size.iHeight;                        
       
  2486             }        
       
  2487         }
       
  2488         
       
  2489     totalMemUsage = TReal32(pixels) * averageBytesPerPixel;        
       
  2490     return totalMemUsage;
       
  2491     }
       
  2492 
       
  2493 
       
  2494 
       
  2495 EXPORT_C void CHuiTextureManager::TextureManagerExtension(const TUid& /*aExtensionUid*/, TAny** aExtensionParams)
       
  2496     {
       
  2497     // If no extension with given UID was found, indicate it by returning null
       
  2498     *aExtensionParams = NULL;
       
  2499     }
       
  2500 
       
  2501 void CHuiTextureManager::EnableAutoSizeCalculation(TBool aEnable)
       
  2502     {
       
  2503     iTextureAutoSizingEnabled = aEnable;
       
  2504     }
       
  2505