uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiVg10Texture.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2006-2008 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 for CHuiVg10Texture, OpenVG 1.0 Texture.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <e32def.h>
       
    21 #include <e32math.h>
       
    22 
       
    23 #include "HuiVg10RenderPlugin.h"
       
    24 #include "HuiVg10Texture.h"
       
    25 #include "HuiVg10TextureManager.h"
       
    26 #include "uiacceltk/HuiTextureHandle.h"
       
    27 #include "uiacceltk/HuiEnv.h"
       
    28 #include "uiacceltk/HuiTextureManager.h"
       
    29 #include "uiacceltk/HuiTextureProcessor.h"
       
    30 #include "uiacceltk/HuiUtil.h"
       
    31 #include "uiacceltk/HuiPanic.h"
       
    32 
       
    33 // temporary hack until the openvg headers are fixed..
       
    34 #ifndef OPENVG_VERSION_1_0_1
       
    35     #warning using temporary hack to define OPENVG_VERSION_1_0_1, see TSW: SKYA-7QQB8
       
    36     #define OPENVG_VERSION_1_0_1
       
    37 #endif
       
    38 
       
    39 #ifdef __NVG
       
    40     #include <EGL/egl.h>
       
    41     #include <nvg.h>
       
    42     #include <AknIconUtils.h>
       
    43     #include "HuiRenderSurface.h"
       
    44     #include "NVGIcon.h"
       
    45 #endif
       
    46 
       
    47 
       
    48 /**
       
    49  *  Bitmap color mode conversion.
       
    50  *
       
    51  *  @param aBitmap      Source bitmap to convert.
       
    52  *  @param aDisplayMode Target display mode.
       
    53  *  @param aCopyMode    Desired copy behavior.
       
    54  *  @returns a new bitmap with the desired display mode.
       
    55  */
       
    56 static CFbsBitmap& ConvertBitmapL(const CFbsBitmap& aBitmap, TDisplayMode aDisplayMode, TBitmapCopyMode aCopyMode = EAllowDuplication, TSize aNewSize = TSize(0,0))
       
    57     {
       
    58     // Functionality moved to Texture Manager 
       
    59     // (to avoid recreating the bitmaps & bmpDevices every time)
       
    60     CHuiTextureManager& tmpMgr = CHuiStatic::Env().TextureManager();
       
    61     CHuiVg10TextureManager& textureMgr = static_cast<CHuiVg10TextureManager&>(tmpMgr);
       
    62     
       
    63     return textureMgr.ConvertBitmapL(aBitmap, aDisplayMode, aCopyMode, aNewSize);
       
    64     }
       
    65 
       
    66 /**
       
    67  *  Replace the alpha channel of an EColor16MA bitmap (in-place).
       
    68  * 
       
    69  *  @param aBitmap      Destination bitmap.
       
    70  *  @param aMaskBitmap  Alpha channel source bitmap.
       
    71  */
       
    72 static void ReplaceAlphaChannelL(CFbsBitmap& aBitmap, const CFbsBitmap& aMaskBitmap)
       
    73     {
       
    74     ASSERT(aBitmap.DisplayMode() == EColor16MA);
       
    75     ASSERT(aBitmap.SizeInPixels() == aMaskBitmap.SizeInPixels());
       
    76     
       
    77     CFbsBitmap& convMask = ConvertBitmapL(aMaskBitmap, EGray256);
       
    78     
       
    79     aBitmap.BeginDataAccess();
       
    80     convMask.BeginDataAccess();
       
    81     TSize size           = aBitmap.SizeInPixels();
       
    82     TUint32* dest32      = (TUint32*)aBitmap.DataAddress();
       
    83     const TUint8* src8   = (const TUint8*)convMask.DataAddress();
       
    84     TInt destStride      = CFbsBitmap::ScanLineLength(size.iWidth, aBitmap.DisplayMode()) >> 2;
       
    85     TInt srcStride       = CFbsBitmap::ScanLineLength(size.iWidth, convMask.DisplayMode());
       
    86     
       
    87     for (TInt y = 0; y < size.iHeight; y++)
       
    88         {
       
    89         TUint32* d      = dest32;
       
    90         const TUint8* s = src8;
       
    91 
       
    92         for (TInt x = 0; x < size.iWidth; x++)
       
    93             {
       
    94             *d   &= ~0xff000000;
       
    95             *d++ |= (*s++) << 24;
       
    96             }
       
    97         
       
    98         dest32 += destStride;
       
    99         src8   += srcStride;
       
   100         }
       
   101 
       
   102     aBitmap.EndDataAccess();
       
   103     convMask.EndDataAccess(ETrue);
       
   104     }
       
   105 
       
   106 #if !defined(OPENVG_VERSION_1_0_1)
       
   107 /**
       
   108  *  Convert a native Symbian EColor16MU/A bitmap to an OpenVG 1.0 equivalent (in-place).
       
   109  * 
       
   110  *  @param aBitmap      Bitmap to convert.
       
   111  */
       
   112 static void ConvertPixelComponentOrdering(CFbsBitmap& aBitmap)
       
   113     {
       
   114     ASSERT(aBitmap.DisplayMode() == EColor16MA || aBitmap.DisplayMode() == EColor16MU);
       
   115     
       
   116     aBitmap.BeginDataAccess();
       
   117     TSize size           = aBitmap.SizeInPixels();
       
   118     TUint32* dest32      = (TUint32*)aBitmap.DataAddress();
       
   119     TInt destStride      = CFbsBitmap::ScanLineLength(size.iWidth, aBitmap.DisplayMode()) >> 2;
       
   120     
       
   121     for (TInt y = 0; y < size.iHeight; y++)
       
   122         {
       
   123         TUint32* d = dest32;
       
   124 
       
   125         for (TInt x = 0; x < size.iWidth; x++)
       
   126             {
       
   127             *d++ = (*d << 8) | ((*d & 0xff000000) >> 24);
       
   128             }
       
   129         
       
   130         dest32 += destStride;
       
   131         }
       
   132     aBitmap.EndDataAccess();
       
   133     }
       
   134 #endif
       
   135 
       
   136 /* Vg10Texture internal flags. */
       
   137 enum
       
   138     {
       
   139     /** Content has been uploaded. */
       
   140     EFlagHasContent = 0x1,
       
   141 
       
   142     /** The texture has an alpha channel. */
       
   143     EFlagHasAlpha = 0x2
       
   144     };
       
   145 
       
   146 
       
   147 CHuiVg10Texture* CHuiVg10Texture::NewL(CHuiVg10RenderPlugin& aRenderPlugin, const THuiTextureHandle* aExistingTexture)
       
   148     {
       
   149     CHuiVg10Texture* self = CHuiVg10Texture::NewLC(aRenderPlugin, aExistingTexture);
       
   150     CleanupStack::Pop(self);
       
   151     return self;
       
   152     }
       
   153 
       
   154 
       
   155 CHuiVg10Texture* CHuiVg10Texture::NewLC(CHuiVg10RenderPlugin& aRenderPlugin, const THuiTextureHandle* aExistingTexture)
       
   156     {
       
   157     CHuiVg10Texture* self = new (ELeave) CHuiVg10Texture(aRenderPlugin);
       
   158     CleanupStack::PushL(self);
       
   159     self->ConstructL(aExistingTexture);
       
   160     return self;
       
   161     }
       
   162 
       
   163 
       
   164 CHuiVg10Texture::CHuiVg10Texture(CHuiVg10RenderPlugin& aRenderPlugin)
       
   165     : iRenderPlugin(aRenderPlugin),
       
   166       iInternalFlags(0),
       
   167       iShadowEnabled(EFalse)
       
   168     {
       
   169     }
       
   170 
       
   171 
       
   172 void CHuiVg10Texture::ConstructL(const THuiTextureHandle* aExistingTexture)
       
   173     {
       
   174     CHuiTexture::BaseConstructL();
       
   175     
       
   176     SetSegmentCountL(1);
       
   177     SetSegmentName(0, 0);
       
   178     SetSegmentSize(0, TSize(0, 0));
       
   179     SetSegmentTextureSize(0, TSize(0, 0));
       
   180 
       
   181     if(aExistingTexture)
       
   182         {
       
   183         // Take over the existing texture (single named texture object).
       
   184         ASSERT(aExistingTexture->SegmentCount() == 1);
       
   185         ASSERT(SegmentCount() == 1);
       
   186         SetSegmentName(0, aExistingTexture->Name());
       
   187         SetSegmentSize(0, aExistingTexture->SegmentSize(0));
       
   188         SetSegmentTextureSize(0, aExistingTexture->SegmentTextureSize(0));
       
   189         SetSize(aExistingTexture->Size());
       
   190         
       
   191         // Copy attributes
       
   192         const CHuiVg10Texture* vgTex = reinterpret_cast<const CHuiVg10Texture*>(aExistingTexture);
       
   193         iInternalFlags = vgTex->iInternalFlags;
       
   194         // Note: shared shadows not supported
       
   195         }
       
   196     }
       
   197 
       
   198 
       
   199 CHuiVg10Texture::~CHuiVg10Texture()
       
   200     {
       
   201     Reset();
       
   202     }
       
   203 
       
   204 
       
   205 TBool CHuiVg10Texture::HasAlpha() const
       
   206     {
       
   207     return (iInternalFlags & EFlagHasAlpha) != 0;
       
   208     }
       
   209     
       
   210     
       
   211 TBool CHuiVg10Texture::HasContent() const
       
   212     {
       
   213     if(!CHuiTexture::HasContent())
       
   214         {
       
   215         return EFalse;
       
   216         }
       
   217         
       
   218     return (iInternalFlags & EFlagHasContent) != 0;
       
   219     }    
       
   220 
       
   221 
       
   222 TSize CHuiVg10Texture::MaxTextureSize() const
       
   223     {
       
   224     if (iRenderPlugin.IsReleased())
       
   225         {
       
   226         HUI_DEBUG(_L("CHuiVg10Texture::MaxTextureSize() - Vg10 context not available, cannot get maximum texture size, returning (0,0)."));
       
   227         return TSize(0,0);
       
   228         }
       
   229     
       
   230     int maxWidth  = vgGeti(VG_MAX_IMAGE_WIDTH)-1;
       
   231     int maxHeight = vgGeti(VG_MAX_IMAGE_HEIGHT)-1;
       
   232     HUI_VG_INVARIANT();
       
   233     ASSERT(maxWidth > 0 && maxHeight > 0);
       
   234     
       
   235     return TSize(maxWidth, maxHeight);
       
   236     }
       
   237 
       
   238 void CHuiVg10Texture::UploadL(const CFbsBitmap& aBitmap,
       
   239                               const CFbsBitmap* aMaskBitmap,
       
   240                               THuiTextureUploadFlags aTextureFlags)
       
   241     {
       
   242     Reset(); // Must delete old content before calling SetupSegmentsL
       
   243     
       
   244     TBool invalidMaskSize = (aMaskBitmap && (aBitmap.SizeInPixels() != aMaskBitmap->SizeInPixels()));
       
   245     
       
   246     CFbsBitmap* maskBitmap = (CFbsBitmap*)aMaskBitmap;
       
   247 
       
   248     if (invalidMaskSize)
       
   249         {
       
   250         maskBitmap = &ConvertBitmapL(*aMaskBitmap, aMaskBitmap->DisplayMode(), EAlwaysCopy, aBitmap.SizeInPixels());
       
   251         }
       
   252     
       
   253     SetupSegmentsL(aBitmap.SizeInPixels(), aBitmap.SizeInPixels(), aTextureFlags);
       
   254     SegmentUploadL(0, aBitmap, maskBitmap, aTextureFlags);
       
   255     }
       
   256 
       
   257 void CHuiVg10Texture::UploadL(THuiTextureFormat aTextureFormat,
       
   258                               const TSize& aTextureSize,
       
   259                               const TUint8* aTextureBuffer,
       
   260                               THuiTextureUploadFlags aTextureFlags,
       
   261                               TUint aTextureBufferSize)
       
   262     {
       
   263     Reset(); // Must delete old content before calling SetupSegmentsL
       
   264     SetupSegmentsL(aTextureSize, aTextureSize, aTextureFlags);
       
   265     SegmentUploadL(0, aTextureFormat, aTextureSize, aTextureBuffer, aTextureBufferSize);
       
   266     }
       
   267     
       
   268 
       
   269 void CHuiVg10Texture::PartialUploadL(THuiTextureFormat aFormat,
       
   270                                      const TPoint& aOrigin,
       
   271                                      const TSize& aSize,
       
   272                                      const TUint8* aBuffer)
       
   273     {
       
   274     ASSERT(SegmentCount() == 1);
       
   275     SegmentPartialUpload(0, aFormat, aOrigin, aSize, aBuffer);
       
   276     }
       
   277 
       
   278 
       
   279 void CHuiVg10Texture::SegmentUploadL(TInt aSegment,
       
   280                                      const CFbsBitmap& aBitmap,
       
   281                                      const CFbsBitmap* aMaskBitmap,
       
   282                                      THuiTextureUploadFlags aFlags)
       
   283     {
       
   284     ASSERT(aSegment >= 0 && aSegment < SegmentCount());
       
   285     ASSERT(aBitmap.SizeInPixels() == Size());
       
   286     ASSERT(aMaskBitmap && aBitmap.SizeInPixels() == aMaskBitmap->SizeInPixels() || !aMaskBitmap);
       
   287 
       
   288     PushEGLContext();
       
   289     if(aSegment < 0 || aSegment >= SegmentCount())
       
   290         {
       
   291         User::Leave(KErrArgument);
       
   292         }
       
   293     
       
   294     // Clear any previous image data
       
   295     ResetSegment(aSegment);
       
   296     
       
   297 #ifdef __NVG
       
   298     // Check if the bitmap is extended and has NVG data
       
   299     TUid bitmaptype = aBitmap.ExtendedBitmapType();
       
   300     TUid masktype = KNullUid;
       
   301     if (aMaskBitmap)
       
   302         {
       
   303         masktype = aMaskBitmap->ExtendedBitmapType();
       
   304         // extended bitmap and mask
       
   305         if (bitmaptype == masktype && bitmaptype != KNullUid)
       
   306             {
       
   307             SegmentUploadNvgL(aBitmap, aMaskBitmap, aFlags);
       
   308             // We now have working texture data, no need to do anything else
       
   309             PopEGLContext();
       
   310             return;
       
   311             }
       
   312         }
       
   313     else if (bitmaptype != KNullUid)
       
   314         {
       
   315         SegmentUploadNvgL(aBitmap, aMaskBitmap, aFlags);
       
   316         // We now have working texture data, no need to do anything else
       
   317         PopEGLContext();
       
   318         return;
       
   319         }
       
   320 #endif
       
   321     
       
   322     VGImageFormat imageSourceFormat = (VGImageFormat)(-1);
       
   323     VGImageFormat imageInternalFormat = VG_sXRGB_8888; // TODO: get the most optimal image format from the renderer
       
   324     VGbitfield qualityFlags = VG_IMAGE_QUALITY_BETTER | VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_NONANTIALIASED;
       
   325     TBool hasAlpha = (aMaskBitmap != NULL);
       
   326     TBool conversionRequired = ETrue;
       
   327     TSize size = Size();
       
   328     TSize textureSize = MaxTextureSize();
       
   329     textureSize.iWidth = Min(size.iWidth, textureSize.iWidth);
       
   330     textureSize.iHeight = Min(size.iHeight, textureSize.iHeight);
       
   331 
       
   332     // See if there is a native color mode we could use without conversion
       
   333     switch (aBitmap.DisplayMode())
       
   334         {
       
   335         case EGray256:
       
   336             imageSourceFormat = VG_A_8;
       
   337             conversionRequired = EFalse;
       
   338             break;
       
   339         case EColor64K:
       
   340             imageSourceFormat = VG_sRGB_565;
       
   341             conversionRequired = EFalse;
       
   342             break;
       
   343         case EColor4K:
       
   344             imageSourceFormat = VG_sRGB_565;
       
   345             conversionRequired = ETrue;
       
   346             break;    
       
   347 #if defined(OPENVG_VERSION_1_0_1)
       
   348         case EColor16MU:
       
   349             imageSourceFormat = VG_sXRGB_8888;
       
   350             conversionRequired = EFalse;
       
   351             break;
       
   352 		case EColor16M:
       
   353             imageSourceFormat = VG_sXRGB_8888;
       
   354             conversionRequired = ETrue;
       
   355             break;
       
   356         case EColor16MA:
       
   357             imageSourceFormat = VG_sARGB_8888;
       
   358             hasAlpha = ETrue;
       
   359             conversionRequired = EFalse;
       
   360             break;
       
   361         case EColor16MAP:
       
   362             imageSourceFormat = VG_sARGB_8888_PRE;
       
   363             hasAlpha = ETrue;
       
   364             conversionRequired = EFalse;
       
   365             break;
       
   366 #else // defined(OPENVG_VERSION_1_0_1)
       
   367         case EColor16MU:
       
   368 		case EColor16M:
       
   369             imageSourceFormat = VG_sRGBX_8888;
       
   370             break;
       
   371         case EColor16MA:
       
   372             imageSourceFormat = VG_sRGBA_8888;
       
   373             hasAlpha = ETrue;
       
   374             break;
       
   375         case EColor16MAP:
       
   376             imageSourceFormat = VG_sRGBA_8888_PRE;
       
   377             hasAlpha = ETrue;
       
   378             break;
       
   379 #endif // defined(OPENVG_VERSION_1_0_1)
       
   380         default:
       
   381 #ifdef _DEBUG
       
   382             RDebug::Printf("CHuiVg10Texture::SegmentUploadL - unknown display mode %d", aBitmap.DisplayMode());
       
   383 #endif
       
   384             conversionRequired = ETrue;
       
   385             imageSourceFormat = VG_sXRGB_8888;
       
   386         }
       
   387     
       
   388     if (aBitmap.IsCompressedInRAM() || aMaskBitmap)
       
   389         {
       
   390         conversionRequired = ETrue;
       
   391         }
       
   392 
       
   393     if (hasAlpha)
       
   394         {
       
   395         imageInternalFormat = VG_sRGBA_8888_PRE;
       
   396         }
       
   397     else
       
   398         {
       
   399         imageInternalFormat = imageSourceFormat;
       
   400         }
       
   401 
       
   402     // Create the actual image
       
   403     VGImage image = vgCreateImage(imageInternalFormat, textureSize.iWidth, textureSize.iHeight, qualityFlags);
       
   404 
       
   405     if (image == VG_INVALID_HANDLE)
       
   406         {
       
   407         User::Leave(KErrNoMemory);
       
   408         }
       
   409     
       
   410     if (!conversionRequired)
       
   411         {
       
   412         // No data conversion is required and we can upload the pixels as such
       
   413         aBitmap.BeginDataAccess();
       
   414         const void* data = aBitmap.DataAddress();
       
   415         TInt stride      = CFbsBitmap::ScanLineLength(size.iWidth, aBitmap.DisplayMode());
       
   416         vgImageSubData(image, data, stride, imageSourceFormat, 0, 0, textureSize.iWidth, textureSize.iHeight);
       
   417         aBitmap.EndDataAccess( ETrue );
       
   418         }
       
   419     else
       
   420         {
       
   421         // One or more conversion steps are needed
       
   422         if (hasAlpha)
       
   423             {
       
   424             // Alpha channel needs to be accounted for
       
   425 #if defined(OPENVG_VERSION_1_0_1)
       
   426             imageSourceFormat = VG_sARGB_8888;
       
   427             CFbsBitmap& convBitmap = ConvertBitmapL(aBitmap, EColor16MA);
       
   428 #else // defined(OPENVG_VERSION_1_0_1)
       
   429             imageSourceFormat = VG_sRGBA_8888;
       
   430             CFbsBitmap& convBitmap = ConvertBitmapL(aBitmap, EColor16MA);
       
   431 #endif // defined(OPENVG_VERSION_1_0_1)
       
   432             
       
   433             // Bake the alpha channel into the converted bitmap
       
   434             if (aMaskBitmap)
       
   435                 {
       
   436                 if (aMaskBitmap->IsCompressedInRAM() || masktype != KNullUid)
       
   437                     {
       
   438                     CFbsBitmap& noncompressedMask = ConvertBitmapL(*aMaskBitmap, EGray256, EAlwaysCopy);
       
   439                     ReplaceAlphaChannelL(convBitmap, noncompressedMask);                                                
       
   440                     }
       
   441                  else
       
   442                     {
       
   443                     ReplaceAlphaChannelL(convBitmap, *aMaskBitmap);
       
   444                     }
       
   445                 }
       
   446             #if !defined(OPENVG_VERSION_1_0_1)
       
   447                     // Match the native OpenVG 1.0 pixel component ordering
       
   448                     ASSERT(convBitmap.Handle() != aBitmap.Handle());
       
   449                     ConvertPixelComponentOrdering(convBitmap);
       
   450             #endif 
       
   451             convBitmap.BeginDataAccess();
       
   452             const void* data = convBitmap.DataAddress();
       
   453             TInt stride      = CFbsBitmap::ScanLineLength(size.iWidth, convBitmap.DisplayMode());
       
   454             vgImageSubData(image, data, stride, imageSourceFormat, 0, 0, textureSize.iWidth, textureSize.iHeight);
       
   455             convBitmap.EndDataAccess( ETrue );
       
   456             }
       
   457         else
       
   458             {
       
   459             // No alpha channel -- just opaque pixel data
       
   460 #if defined(OPENVG_VERSION_1_0_1)
       
   461             TDisplayMode mode = EColor16MU;
       
   462             if (imageSourceFormat == VG_sRGB_565)
       
   463                 {
       
   464                 mode = EColor64K;
       
   465                 }
       
   466             else if (imageSourceFormat == VG_A_8)
       
   467                 {
       
   468                 mode = EGray256;
       
   469                 }
       
   470             else
       
   471                 {
       
   472                 imageSourceFormat = VG_sXRGB_8888;
       
   473                 }
       
   474             CFbsBitmap& convBitmap = ConvertBitmapL(aBitmap, mode);
       
   475 #else // defined(OPENVG_VERSION_1_0_1)
       
   476             imageSourceFormat = VG_sRGBX_8888;
       
   477             CFbsBitmap& convBitmap = ConvertBitmapL(aBitmap, EColor16MU);
       
   478             
       
   479             // Match the native OpenVG 1.0 pixel component ordering
       
   480             ASSERT(convBitmap.Handle() != aBitmap.Handle());
       
   481             ConvertPixelComponentOrdering(convBitmap);
       
   482 #endif // defined(OPENVG_VERSION_1_0_1)
       
   483             
       
   484             convBitmap.BeginDataAccess();
       
   485             const void* data = convBitmap.DataAddress();
       
   486             TInt stride      = CFbsBitmap::ScanLineLength(size.iWidth, convBitmap.DisplayMode());
       
   487             vgImageSubData(image, data, stride, imageSourceFormat, 0, 0, textureSize.iWidth, textureSize.iHeight);
       
   488             convBitmap.EndDataAccess( ETrue );
       
   489             }
       
   490         }
       
   491     
       
   492     // Save the image handle
       
   493     SetSegmentName(0, (TUint)image);
       
   494     
       
   495     // The texture now has content.
       
   496     iInternalFlags |= EFlagHasContent;
       
   497 
       
   498     if (hasAlpha)
       
   499         {
       
   500         iInternalFlags |= EFlagHasAlpha;
       
   501         }
       
   502     
       
   503     // Keep the shadow in sync with the image contents
       
   504     if (IsShadowEnabled())
       
   505         {
       
   506         // if this fails there is nothing we can do
       
   507         // There will be no shadow if something goes wrong here
       
   508         TRAP_IGNORE( GenerateShadowL() );
       
   509         }
       
   510     PopEGLContext();
       
   511     // Wake up refresh. It is likely that the new texture will be visible on
       
   512     // the screen.
       
   513     CHuiStatic::ContinueRefresh();
       
   514     }
       
   515 
       
   516 static void ConvertBufferRgb888TosRGBX8888(const TUint8* aSrc, TUint8* aDest, TInt aCount)
       
   517 {
       
   518     while (aCount--)
       
   519         {
       
   520         *aDest++ = *aSrc++;
       
   521         *aDest++ = *aSrc++;
       
   522         *aDest++ = *aSrc++;
       
   523         *aDest++ = 0xff;
       
   524         }
       
   525 }
       
   526 
       
   527 static void ConvertBufferLa88TosRGBA8888(const TUint8* aSrc, TUint8* aDest, TInt aCount)
       
   528 {
       
   529     while (aCount--)
       
   530         {
       
   531         TUint8 l = *aSrc++;
       
   532         TUint8 a = *aSrc++;
       
   533         *aDest++ = l;
       
   534         *aDest++ = l;
       
   535         *aDest++ = l;
       
   536         *aDest++ = a;
       
   537         }
       
   538 }
       
   539 
       
   540 #if !defined(OPENVG_VERSION_1_0_1)
       
   541 static void ConvertBufferRgba8888TosRGBA8888(const TUint8* aSrc, TUint8* aDest, TInt aCount)
       
   542 {
       
   543     while (aCount--)
       
   544         {
       
   545         TUint8 r = *aSrc++;
       
   546         TUint8 g = *aSrc++;
       
   547         TUint8 b = *aSrc++;
       
   548         TUint8 a = *aSrc++;
       
   549         *aDest++ = a;
       
   550         *aDest++ = r;
       
   551         *aDest++ = g;
       
   552         *aDest++ = b;
       
   553         }
       
   554 }
       
   555 #endif
       
   556 
       
   557 void CHuiVg10Texture::SegmentClearL(TInt aSegment,
       
   558                                     TBool aWithAlpha,
       
   559                                     const TRgb& aColor,
       
   560                                     TUint8 aAlpha)
       
   561     {
       
   562     ASSERT(aSegment >= 0 && aSegment < SegmentCount());
       
   563 
       
   564     if(aSegment < 0 || aSegment >= SegmentCount())
       
   565         {
       
   566         User::Leave(KErrArgument);
       
   567         }
       
   568 
       
   569     // Clear any previous image data
       
   570     TSize size = Size();
       
   571     ResetSegment(aSegment);
       
   572 
       
   573     // Create the actual image
       
   574     VGImageFormat imageInternalFormat = aWithAlpha ? VG_sRGBA_8888 : VG_sRGBX_8888;
       
   575     VGbitfield qualityFlags = VG_IMAGE_QUALITY_BETTER | VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_NONANTIALIASED;
       
   576     VGImage image = vgCreateImage(imageInternalFormat, size.iWidth, size.iHeight, qualityFlags);
       
   577     
       
   578     if (image == VG_INVALID_HANDLE)
       
   579         {
       
   580         User::Leave(KErrNoMemory);
       
   581         }
       
   582 
       
   583     // Set the clear color
       
   584     VGfloat scale = 1.0f / 255.0f;
       
   585     VGfloat color[] = {
       
   586         aColor.Red()   * scale,
       
   587         aColor.Green() * scale,
       
   588         aColor.Blue()  * scale,
       
   589         aWithAlpha ? (aAlpha * scale) : 1.0f
       
   590     };
       
   591     
       
   592     vgSetfv(VG_CLEAR_COLOR, 4, color);
       
   593     vgClearImage(image, 0, 0, size.iWidth, size.iHeight);
       
   594 
       
   595     // The texture now has content.
       
   596     iInternalFlags |= EFlagHasContent;
       
   597 
       
   598     if (aWithAlpha)
       
   599         {
       
   600         iInternalFlags |= EFlagHasAlpha;
       
   601         }
       
   602 
       
   603     // Keep the shadow in sync with the image contents
       
   604     if (IsShadowEnabled())
       
   605         {
       
   606         GenerateShadowL();
       
   607         }
       
   608     
       
   609     HUI_VG_INVARIANT();
       
   610     }
       
   611 
       
   612 void CHuiVg10Texture::SegmentUploadL(TInt aSegment,
       
   613                                      THuiTextureFormat aFormat,
       
   614                                      const TSize& aSize,
       
   615                                      const TUint8* aBuffer,
       
   616                                      TUint /*aBufferSize*/)
       
   617     {
       
   618     ASSERT(aSegment >= 0 && aSegment < SegmentCount());
       
   619     ASSERT(aSize == Size());
       
   620     
       
   621     SegmentPartialUploadInternal(aSegment, aFormat, TPoint(0, 0), aSize, aBuffer, ETrue);
       
   622     }
       
   623 
       
   624 void CHuiVg10Texture::SegmentPartialUpload(
       
   625         TInt aSegment,
       
   626         THuiTextureFormat aFormat,
       
   627         const TPoint& aOrigin,
       
   628         const TSize& aSize,
       
   629         const TUint8* aBuffer)
       
   630     {
       
   631     SegmentPartialUploadInternal(aSegment, aFormat, aOrigin, aSize, aBuffer, EFalse);
       
   632     }
       
   633 
       
   634 void CHuiVg10Texture::SegmentPartialUploadInternal(
       
   635         TInt aSegment,
       
   636         THuiTextureFormat aFormat,
       
   637         const TPoint& aOrigin,
       
   638         const TSize& aSize,
       
   639         const TUint8* aBuffer,
       
   640         TBool aCreateImage)
       
   641     {
       
   642     ASSERT(aSegment >= 0 && aSegment < SegmentCount());
       
   643 
       
   644     if (aSegment < 0 || aSegment >= SegmentCount())
       
   645         {
       
   646         // we return without doing anything because we are called by a non-leaving function
       
   647         return;
       
   648         }
       
   649 
       
   650     if (aOrigin.iX < 0 || aOrigin.iY < 0)
       
   651         {
       
   652         // we return without doing anything because we are called by a non-leaving function
       
   653         return;
       
   654         }
       
   655     
       
   656     HUI_DEBUG4(_L("CHuiVg10Texture::SegmentPartialUploadInternal() - Uploading partial image (%ix%i pixels, offset x: %i y: %i)."),
       
   657                aSize.iWidth, aSize.iHeight, aOrigin.iX, aOrigin.iY);
       
   658     
       
   659     VGImageFormat imageSourceFormat = (VGImageFormat)(-1);
       
   660     VGImageFormat imageInternalFormat = VG_sRGBX_8888; // TODO: get the most optimal image format from the renderer
       
   661     VGbitfield qualityFlags = VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_BETTER; // TODO: get this from hitchcock
       
   662     TBool hasAlpha = EFalse;
       
   663     TBool conversionRequired = ETrue;
       
   664     TInt sourceStride = 0;
       
   665     
       
   666     switch (aFormat)
       
   667         {
       
   668         case EHuiTextureFormatRgb565:
       
   669             imageSourceFormat = VG_sRGB_565;
       
   670             conversionRequired = EFalse;
       
   671             sourceStride = aSize.iWidth * 2;
       
   672             break;
       
   673         case EHuiTextureFormatRgb888:
       
   674             imageSourceFormat = VG_sRGBX_8888;
       
   675             sourceStride = aSize.iWidth * 4;
       
   676             break;
       
   677         case EHuiTextureFormatLa88:
       
   678             // We have to expand this format to RGBA, since there is no luminance-alpha format in OpenVG 1.0.1
       
   679             imageSourceFormat = VG_sRGBA_8888;
       
   680             sourceStride = aSize.iWidth * 4;
       
   681             hasAlpha = ETrue;
       
   682             break;
       
   683 #if defined(OPENVG_VERSION_1_0_1)
       
   684         case EHuiTextureFormatRgba8888:
       
   685             imageSourceFormat = VG_sARGB_8888;
       
   686             conversionRequired = EFalse;
       
   687             hasAlpha = ETrue;
       
   688             sourceStride = aSize.iWidth * 4;
       
   689             break;
       
   690 #else // defined(OPENVG_VERSION_1_0_1)
       
   691         case EHuiTextureFormatRgba8888:
       
   692             imageSourceFormat = VG_sRGBA_8888;
       
   693             sourceStride = aSize.iWidth * 4;
       
   694             hasAlpha = ETrue;
       
   695             break;
       
   696 #endif // defined(OPENVG_VERSION_1_0_1)
       
   697         
       
   698         // Compressed formats are not supported
       
   699         default:
       
   700             // we return without doing anything because we are called by a non-leaving function
       
   701             return;
       
   702         }
       
   703     
       
   704     // Use a matching internal format
       
   705     imageInternalFormat = imageSourceFormat;
       
   706 
       
   707     // Create the actual image if required
       
   708     VGImage image = VG_INVALID_HANDLE;
       
   709     
       
   710     if (aCreateImage)
       
   711         {
       
   712         image = vgCreateImage(imageInternalFormat, aSize.iWidth, aSize.iHeight, qualityFlags);
       
   713         }
       
   714     else
       
   715         {
       
   716         image = (VGImage)SegmentName(0);
       
   717         
       
   718         // Verify the dimensions
       
   719         if (aOrigin.iX + aSize.iWidth  >= Size().iWidth || 
       
   720             aOrigin.iY + aSize.iHeight >= Size().iHeight)
       
   721             {
       
   722             // we return without doing anything because we are called by a non-leaving function
       
   723             return;
       
   724             }
       
   725         }
       
   726 
       
   727     if (image == VG_INVALID_HANDLE)
       
   728         {
       
   729         // we return without doing anything because we are called by a non-leaving function
       
   730         return;
       
   731         }
       
   732     
       
   733     if (!conversionRequired)
       
   734         {
       
   735         // No data conversion is required and we can upload the pixels as such
       
   736         vgImageSubData(image, aBuffer, sourceStride, imageSourceFormat, aOrigin.iX, aOrigin.iY, aSize.iWidth, aSize.iHeight);
       
   737         HUI_VG_INVARIANT();
       
   738         }
       
   739     else
       
   740         {
       
   741         // One or more conversion steps are needed
       
   742         TInt pixels = aSize.iWidth * aSize.iHeight;
       
   743         TUint8* convBuffer = NULL;
       
   744         convBuffer = new TUint8[sourceStride * aSize.iHeight];
       
   745         // there are no leaving functions until our buffer is deleted
       
   746         // We cannot put convBuffer onto cleanup stack because we cannot leave.
       
   747         
       
   748         if ( !convBuffer )
       
   749             {
       
   750             // we return without doing anything because we are called by a non-leaving function
       
   751             return;
       
   752             }
       
   753         
       
   754         switch (aFormat)
       
   755             {
       
   756             case EHuiTextureFormatRgb888:
       
   757                 ConvertBufferRgb888TosRGBX8888(aBuffer, convBuffer, pixels);
       
   758                 break;
       
   759             case EHuiTextureFormatLa88:
       
   760                 ConvertBufferLa88TosRGBA8888(aBuffer, convBuffer, pixels);
       
   761                 break;
       
   762 #if !defined(OPENVG_VERSION_1_0_1)
       
   763             case EHuiTextureFormatRgba8888:
       
   764                 ConvertBufferRgba8888TosRGBA8888(aBuffer, convBuffer, pixels);
       
   765                 break;
       
   766 #endif // defined(OPENVG_VERSION_1_0_1)
       
   767             default:
       
   768                 ASSERT(0);
       
   769             }
       
   770         
       
   771         vgImageSubData(image, convBuffer, sourceStride, imageSourceFormat, aOrigin.iX, aOrigin.iY, aSize.iWidth, aSize.iHeight);
       
   772         delete[] convBuffer;
       
   773         HUI_VG_INVARIANT();
       
   774         }
       
   775 
       
   776     // Save the image handle
       
   777     SetSegmentName(0, (TUint)image);
       
   778     
       
   779     // The texture now has content.
       
   780     iInternalFlags |= EFlagHasContent;
       
   781 
       
   782     if (hasAlpha)
       
   783         {
       
   784         iInternalFlags |= EFlagHasAlpha;
       
   785         }
       
   786     
       
   787     // Keep the shadow in sync with the image contents
       
   788     if (IsShadowEnabled())
       
   789         {
       
   790         // We cannot leave, we just try our best.
       
   791         // If this fails, we have no shadow
       
   792         TRAP_IGNORE( GenerateShadowL() );
       
   793         }
       
   794     
       
   795     HUI_VG_INVARIANT();
       
   796     }
       
   797 
       
   798 void CHuiVg10Texture::Reset()
       
   799     {
       
   800     CHuiTexture::Reset();
       
   801     
       
   802     if (iShadow.Name())
       
   803         {
       
   804         vgDestroyImage((VGImage)iShadow.Name());
       
   805         iShadow.SetName(0);
       
   806         }
       
   807     
       
   808     iShadowEnabled = EFalse;
       
   809     
       
   810 #ifdef __NVG
       
   811     CHuiTexture::SetNvgContent(EFalse);
       
   812     iIsExtended = EFalse;
       
   813     
       
   814     delete iNVGData;
       
   815     iNVGData = NULL;
       
   816     delete iIconCommands;
       
   817     iIconCommands = NULL;
       
   818 #endif
       
   819     }
       
   820 
       
   821 void CHuiVg10Texture::ResetSegment(TInt aSegment)
       
   822     {
       
   823     HUI_DEBUG1(_L("CHuiVg10Texture::ResetSegment() - Trying to delete image for segment %i."), aSegment);
       
   824     HUI_VG_INVARIANT();
       
   825     ASSERT(aSegment>=0 && aSegment < SegmentCount());
       
   826 
       
   827     VGImage image = (VGImage)SegmentName(aSegment);
       
   828     if (image != VG_INVALID_HANDLE)
       
   829         {
       
   830         vgDestroyImage(image);
       
   831         }
       
   832 
       
   833     SetSegmentName(aSegment, VG_INVALID_HANDLE);
       
   834     SetSegmentTextureSize(aSegment, TSize(0, 0));
       
   835     SetSegmentSize(aSegment, TSize(0, 0));
       
   836     SetSegmentOffset(aSegment, TPoint(0, 0));
       
   837 
       
   838     // There is no content anymore
       
   839     iInternalFlags &= ~(EFlagHasContent | EFlagHasAlpha);
       
   840     
       
   841     HUI_VG_INVARIANT();
       
   842     }
       
   843 
       
   844 
       
   845 void CHuiVg10Texture::InitSegmentL(TInt /*aSegment*/)
       
   846     {
       
   847     // Nothing to do
       
   848     }
       
   849 
       
   850 
       
   851 void CHuiVg10Texture::SetupSegmentsL(const TSize& aLogicalSize,
       
   852                                      const TSize& aTextureSize,
       
   853                                      THuiTextureUploadFlags aFlags)
       
   854     {
       
   855     // Assert that the sizes are valid.
       
   856     ASSERT(aTextureSize.iWidth > 0 && aTextureSize.iHeight > 0);
       
   857     ASSERT(aLogicalSize.iWidth > 0 && aLogicalSize.iHeight > 0);
       
   858 
       
   859     HUI_DEBUG4(_L("CHuiVg10Texture::SetupSegments() - Configuring a single %ix%i texture segment for %ix%i bitmap."),
       
   860                aTextureSize.iWidth, aTextureSize.iHeight,
       
   861                aTextureSize.iWidth, aTextureSize.iHeight);
       
   862 
       
   863     // All textures use only a single segment with OpenVG.
       
   864     SetSegmentCountL(1);
       
   865     
       
   866     SetSegment(0, aLogicalSize, TPoint(0, 0), aTextureSize);
       
   867     SetSegmentName(0, (TUint)VG_INVALID_HANDLE);
       
   868     
       
   869     // The logical size always matches the texture size
       
   870     SetSize(aLogicalSize);
       
   871     
       
   872     // Enable shadow generation if requested
       
   873     if (aFlags & EHuiTextureUploadFlagGenerateShadow)
       
   874         {
       
   875         EnableShadow(ETrue);
       
   876         }
       
   877     }
       
   878     
       
   879 void CHuiVg10Texture::TextureExtension(const TUid& aExtensionUid, TAny** aExtensionParameters)
       
   880     {
       
   881 	CHuiTexture::TextureExtension(aExtensionUid, aExtensionParameters);    	
       
   882     }
       
   883 
       
   884 void CHuiVg10Texture::EnableShadow(TBool aEnable)
       
   885     {
       
   886     CHuiTexture::EnableShadow(aEnable);
       
   887     iShadowEnabled = aEnable;
       
   888 
       
   889     if (!aEnable && iShadow.Name())
       
   890         {
       
   891         vgDestroyImage((VGImage)iShadow.Name());
       
   892         iShadow.SetName(0);
       
   893         HUI_VG_INVARIANT();
       
   894         }
       
   895     
       
   896     if (aEnable)
       
   897         {
       
   898         // We cannot leave, we just try our best.
       
   899         // If this fails, we have no shadow
       
   900         TRAP_IGNORE( GenerateShadowL() ); 
       
   901         }
       
   902 
       
   903     HUI_VG_INVARIANT();
       
   904     }
       
   905 
       
   906 TBool CHuiVg10Texture::IsShadowEnabled() const
       
   907     {
       
   908     return iShadowEnabled;
       
   909     }
       
   910 
       
   911 TBool CHuiVg10Texture::GetShadowTexture(THuiTextureHandle& aHandle) const
       
   912     {
       
   913     if (iShadowEnabled && iShadow.SegmentName(0))
       
   914         {
       
   915         aHandle = iShadow;
       
   916         return ETrue;
       
   917         }
       
   918     return EFalse;
       
   919     }
       
   920 
       
   921 void CHuiVg10Texture::UpdateShadowSizeL(const TSize& aSize)
       
   922     {
       
   923     VGImage shadow = VG_INVALID_HANDLE;
       
   924 
       
   925     if (iShadow.Name())
       
   926         {
       
   927         shadow = (VGImage)(iShadow.Name());
       
   928         TInt w = vgGetParameteri(shadow, VG_IMAGE_WIDTH);
       
   929         TInt h = vgGetParameteri(shadow, VG_IMAGE_HEIGHT);
       
   930         
       
   931         if (w != aSize.iWidth || h != aSize.iHeight)
       
   932             {
       
   933             // Destroy the old shadow image -- a new one will be created below
       
   934             vgDestroyImage(shadow);
       
   935             iShadow.SetName(0);
       
   936             }
       
   937         else
       
   938             {
       
   939             return;
       
   940             }
       
   941         }
       
   942     
       
   943     ASSERT(!iShadow.Name());
       
   944     
       
   945     shadow = vgCreateImage(VG_sRGBA_8888_PRE, aSize.iWidth, aSize.iHeight, 
       
   946                            VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_NONANTIALIASED);
       
   947 
       
   948     if (shadow == VG_INVALID_HANDLE)
       
   949         {
       
   950         return;
       
   951         }
       
   952     iShadow.SetName(shadow);
       
   953     iShadow.SetSize(aSize);
       
   954     
       
   955     HUI_VG_INVARIANT();
       
   956     }
       
   957 
       
   958 void CHuiVg10Texture::GenerateShadowL()
       
   959     {
       
   960     if (iRenderPlugin.IsReleased())
       
   961         {
       
   962         HUI_DEBUG(_L("CHuiVg10Texture::GenerateShadowL - VG context not available, cannot generate texture object."));
       
   963         return;
       
   964         }
       
   965     
       
   966     if (!IsShadowEnabled() || !(iInternalFlags & EFlagHasContent))
       
   967         {
       
   968         return;
       
   969         }
       
   970 
       
   971     CHuiTextureProcessor& proc = CHuiStatic::Env().TextureManager().Processor();
       
   972     TSize size = Size();
       
   973 
       
   974     switch(ShadowStyle())
       
   975         {
       
   976         case EHuiTextureShadowStyleIcon:
       
   977             {
       
   978             // TODO: Allow for smaller shadow images as an optimization
       
   979             TSize shadowSize(size.iWidth, size.iHeight);
       
   980             UpdateShadowSizeL(shadowSize);
       
   981             proc.BlurL(Handle(), iShadow, shadowSize, 4,
       
   982                 CHuiTextureProcessor::EBlurFlagWhite |
       
   983                 CHuiTextureProcessor::EBlurFlagAlpha |
       
   984                 CHuiTextureProcessor::EBlurFlagExpandEdges);
       
   985             break;
       
   986             }
       
   987 
       
   988         case EHuiTextureShadowStyleRasterizedText:
       
   989             {
       
   990             TSize shadowSize(size.iWidth, size.iHeight);
       
   991             UpdateShadowSizeL(shadowSize);
       
   992             proc.BlurL(Handle(), iShadow, shadowSize, 4,
       
   993                 CHuiTextureProcessor::EBlurFlagWhite |
       
   994                 CHuiTextureProcessor::EBlurFlagAlpha |
       
   995                 CHuiTextureProcessor::EBlurFlagExpandEdges);
       
   996             break;
       
   997             }
       
   998 
       
   999         default:
       
  1000             break;
       
  1001         }
       
  1002 
       
  1003     HUI_VG_INVARIANT();
       
  1004     }
       
  1005 
       
  1006 #ifdef __NVG
       
  1007 HBufC8* CHuiVg10Texture::ReadNVGDataL(const CFbsBitmap& aBitmap)
       
  1008     {
       
  1009     // Fetch the extended data
       
  1010     aBitmap.BeginDataAccess();
       
  1011     const TUint32* data = aBitmap.DataAddress();
       
  1012     TInt dataSize = aBitmap.DataSize();
       
  1013     TUint8* compressedData = new (ELeave) TUint8[dataSize];
       
  1014     CleanupStack::PushL(compressedData);
       
  1015     Mem::Copy(compressedData, data, dataSize);
       
  1016     aBitmap.EndDataAccess(ETrue);
       
  1017     
       
  1018     // Create a descriptor out of the extended bitmap data. The iNVGData
       
  1019     // will now contain the direct OpenVG commands
       
  1020     TPtr8 nvgDataPtr(compressedData, dataSize, dataSize);
       
  1021     HBufC8* dataBuf = nvgDataPtr.AllocL();
       
  1022     
       
  1023     CleanupStack::PopAndDestroy(compressedData);
       
  1024     return dataBuf;
       
  1025     }
       
  1026 
       
  1027 void CHuiVg10Texture::SegmentUploadNvgL(const CFbsBitmap& aBitmap, const CFbsBitmap* aMaskBitmap, THuiTextureUploadFlags aFlags)
       
  1028     {
       
  1029     HUI_VG_INVARIANT();
       
  1030     
       
  1031     VGImage image = VG_INVALID_HANDLE;
       
  1032     HBufC8* dataBuf = ReadNVGDataL(aBitmap);
       
  1033     CleanupStack::PushL(dataBuf);
       
  1034     HBufC8* maskDataBuf = NULL;
       
  1035     TAknIconHeader header = GetNvgIconHeader(dataBuf);
       
  1036     TAknIconHeader maskHeader(header);  // DUMMY Creation, since default constructor is missing!
       
  1037     
       
  1038     if (aMaskBitmap)
       
  1039         {
       
  1040         maskDataBuf = ReadNVGDataL(*aMaskBitmap);
       
  1041         CleanupStack::PushL(maskDataBuf);
       
  1042         maskHeader = GetNvgIconHeader(maskDataBuf);
       
  1043         }
       
  1044     
       
  1045     // The trick here is to check the texture upload flags, and determine
       
  1046     // whether we want to draw from NVG object cache directly or raster
       
  1047     // the NVG data to a PBuffer
       
  1048     if (aFlags & EHuiTextureUploadFlagUsePureNvg)
       
  1049         {
       
  1050         // Save the NVG data for future use
       
  1051         if (iNVGData)
       
  1052             {
       
  1053             delete iNVGData;
       
  1054             iNVGData = NULL;
       
  1055             }
       
  1056         iNVGData = dataBuf;
       
  1057         
       
  1058         // TODO: If the NVG ObjectCache is still up-to-date, we could possibly
       
  1059         // create the object cached NVG icon for faster drawing, and maybe
       
  1060         // discard the iNVGData completely (to save RAM?)
       
  1061         CreateObjCachedNVGIconL();  // NOTE: The OPENVG_OBJECT_CACHING has to be defined in NVG!
       
  1062         
       
  1063         // Mark the texture as an NVG texture
       
  1064         CHuiTexture::SetNvgContent(ETrue);
       
  1065         iIsExtended = ETrue;
       
  1066         }
       
  1067     else    // By default, use the "OPTION C" -way!
       
  1068         {
       
  1069         // Use the same way to create the rendered image as in OPTION_C (see below)
       
  1070         CNvgEngine& nvgEngine = iRenderPlugin.NvgEngine();
       
  1071         iIsExtended = ETrue;    // I'm an NVG texture yet..
       
  1072     
       
  1073         // Make sure we don't leak memory
       
  1074         if (iNVGData)
       
  1075             {
       
  1076             delete iNVGData;
       
  1077             iNVGData = NULL;
       
  1078             }
       
  1079         
       
  1080         // Create the real image from NVG databuf
       
  1081         iNVGData = dataBuf;
       
  1082         image = CreateRenderedImage(&nvgEngine, dataBuf, Size());
       
  1083         
       
  1084         // New functionality for checking the mask
       
  1085         if (header.GetBitmapId() != maskHeader.GetBitmapId() &&
       
  1086             CompareNvgData(dataBuf, maskDataBuf) != 0)
       
  1087             {
       
  1088             VGImage maskImg = VG_INVALID_HANDLE;
       
  1089             // The mask is from different bitmap => we have to create
       
  1090             // a separate mask image for masking the NVG icon
       
  1091             maskImg = CreateRenderedImage(&nvgEngine, maskDataBuf, Size());
       
  1092             ReplaceVGImageAlphaChannelL(image, maskImg, Size());
       
  1093             vgDestroyImage(maskImg);
       
  1094             }
       
  1095         
       
  1096         // Save the image handle
       
  1097         SetSegmentName(0, (TUint)image);
       
  1098         
       
  1099         // No need for object cached cmds, if any did exist
       
  1100         delete iIconCommands; // No effect, if iIconCommands aren't created
       
  1101         iIconCommands = NULL;
       
  1102         
       
  1103         // If the VGImage texture creation was successful, we are no longer "NVG 
       
  1104         // texture" in a sense. If not, we will use the NVG data directly for drawing
       
  1105         if (image != VG_INVALID_HANDLE)
       
  1106             {
       
  1107             CHuiTexture::SetNvgContent(EFalse);
       
  1108             iIsExtended = EFalse;
       
  1109             }
       
  1110         }
       
  1111     
       
  1112     if (aMaskBitmap)
       
  1113         {
       
  1114         CleanupStack::PopAndDestroy(maskDataBuf);
       
  1115         }
       
  1116     CleanupStack::Pop(dataBuf);
       
  1117     
       
  1118     // The texture now has content.
       
  1119     iInternalFlags |= EFlagHasContent;
       
  1120     iInternalFlags |= EFlagHasAlpha;
       
  1121     
       
  1122     HUI_VG_INVARIANT();
       
  1123     }
       
  1124 
       
  1125 TInt CHuiVg10Texture::CompareNvgData(HBufC8* aNVGData1, HBufC8* aNVGData2)
       
  1126     {
       
  1127     TInt lengthAfterHeader1 = aNVGData1->Length() - KIconHeaderLength;
       
  1128     TInt lengthAfterHeader2 = aNVGData2->Length() - KIconHeaderLength;
       
  1129     
       
  1130     TPtr8 firstNoHeader((TUint8 *)aNVGData1->Des().Ptr() + KIconHeaderLength, lengthAfterHeader1, lengthAfterHeader1);
       
  1131     TPtr8 secondNoHeader((TUint8 *)aNVGData2->Des().Ptr() + KIconHeaderLength, lengthAfterHeader2, lengthAfterHeader2);
       
  1132     
       
  1133     TInt returnValue = firstNoHeader.Compare(secondNoHeader);
       
  1134     return returnValue;
       
  1135     }
       
  1136 
       
  1137 VGImage CHuiVg10Texture::CreateRenderedImage(CNvgEngine* aNvgEngine, HBufC8* aNVGData, const TSize& aDestSize)
       
  1138     {
       
  1139     HUI_VG_INVARIANT();
       
  1140     
       
  1141     // Image placeholder
       
  1142     VGImage image = VG_INVALID_HANDLE;
       
  1143 
       
  1144     if ( !iIsExtended )
       
  1145         {
       
  1146         // If called outside of the context, do nothing.
       
  1147         // Image will be VG_INVALID_HANDLE
       
  1148         HUI_DEBUG(_L("CHuiVg10Texture::CreateRenderedImage() - Texture not extended, can't create rendered image"));
       
  1149         return image;
       
  1150         }
       
  1151     
       
  1152     // Check if we already have an existing image.
       
  1153     if (SegmentCount() == 1)
       
  1154         {
       
  1155         image = (VGImage)SegmentName(0);
       
  1156         if( image != VG_INVALID_HANDLE )
       
  1157             {
       
  1158             HUI_DEBUG1(_L("CHuiVg10Texture::CreateRenderedImage() - Image already exists: %d"), image);
       
  1159             return image;
       
  1160             }
       
  1161         }
       
  1162     
       
  1163     // NVGEngine is needed to do the drawing of the extended bitmap to VGImage
       
  1164     if (!aNvgEngine || !aNVGData)
       
  1165         {
       
  1166         HUI_DEBUG(_L("CHuiVg10Texture::CreateRenderedImage() - No NvgEngine / NVGData!"));
       
  1167         return image;
       
  1168         }
       
  1169     
       
  1170     // Get the needed egl contexts & stuff for creating the proper eglSurface
       
  1171     EGLContext context = iRenderPlugin.EglSharedContext();
       
  1172     MHuiRenderSurface* oldSurface = CHuiStatic::CurrentRenderSurface();
       
  1173 
       
  1174 #ifndef __WINS__ // Should possibly query the supported mode instead?
       
  1175     VGImageFormat imageInternalFormat = VG_sARGB_8888_PRE;
       
  1176 #else
       
  1177     VGImageFormat imageInternalFormat = VG_sARGB_8888;
       
  1178 #endif
       
  1179     
       
  1180     VGbitfield qualityFlags = VG_IMAGE_QUALITY_NONANTIALIASED; // | VG_IMAGE_QUALITY_BETTER | VG_IMAGE_QUALITY_FASTER;
       
  1181     image = vgCreateImage(imageInternalFormat, aDestSize.iWidth, aDestSize.iHeight, qualityFlags);
       
  1182     
       
  1183     // Get the configs and displays etc. needed for creating the surface
       
  1184     EGLDisplay display = iRenderPlugin.EglDisplay();
       
  1185 
       
  1186 #if 1
       
  1187     // Returns the same config, as below!
       
  1188     // The config used with the current renderer surface has the same parameters
       
  1189     // that are needed with the PBufferSurface from vgImage
       
  1190     EGLConfig config = iRenderPlugin.EglConfig(0);
       
  1191 #else
       
  1192     // This structure can be used, if surface config params have to be changed
       
  1193     // Better way though might be to change the vgImage VGImageFormat accordingly..
       
  1194     const TInt BITS_PER_CHANNEL = 8;
       
  1195     // Choose an EGL config
       
  1196     const EGLint attrs[] =
       
  1197         {
       
  1198         EGL_RENDERABLE_TYPE,    EGL_OPENVG_BIT,
       
  1199         EGL_SURFACE_TYPE,       EGL_PBUFFER_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT,
       
  1200         EGL_RED_SIZE,           BITS_PER_CHANNEL,
       
  1201         EGL_GREEN_SIZE,         BITS_PER_CHANNEL,
       
  1202         EGL_BLUE_SIZE,          BITS_PER_CHANNEL,
       
  1203         EGL_ALPHA_SIZE,         BITS_PER_CHANNEL,
       
  1204         EGL_NONE
       
  1205         };
       
  1206     TInt configCount = iRenderPlugin.EglChooseConfig(attrs);
       
  1207     ASSERT(configCount > 0);
       
  1208     EGLConfig config = iRenderPlugin.EglConfig(0);
       
  1209 #endif
       
  1210     
       
  1211     // The VGImage will act as the surface, so the drawing will go directly to the VGImage
       
  1212     EGLSurface newSurface = eglCreatePbufferFromClientBuffer(
       
  1213         display, EGL_OPENVG_IMAGE,
       
  1214         static_cast<EGLClientBuffer>(image),    // Use the image as buffer
       
  1215         config, NULL);
       
  1216     
       
  1217     // Report error in debug mode, if failed creating the surface
       
  1218     if ( newSurface == EGL_NO_SURFACE )
       
  1219         {
       
  1220         HUI_DEBUG1(_L("CHuiVg10Texture::CreateRenderedImage() - EGL Surface could not be created, eglErr: %04x"), eglGetError() );
       
  1221         if ( image != VG_INVALID_HANDLE )
       
  1222             {
       
  1223             vgDestroyImage( image );
       
  1224             image = VG_INVALID_HANDLE;
       
  1225             }
       
  1226         
       
  1227         HUI_VG_INVARIANT();
       
  1228         return image;
       
  1229         }
       
  1230     
       
  1231     // Set the new VGImage related eglSurface as current, and start drawing onto it!  
       
  1232     // We use the old context, our surface should be compatible with it          
       
  1233     if ( eglMakeCurrent( display, newSurface, newSurface, context ) == EGL_FALSE )
       
  1234         {
       
  1235         // Report error in debug mode
       
  1236         HUI_DEBUG1(_L("CHuiVg10Texture::CreateRenderedImage() - EGL Surface could not be made current, eglErr: %04x"), eglGetError());
       
  1237         if ( image != VG_INVALID_HANDLE )
       
  1238             {
       
  1239             vgDestroyImage( image );
       
  1240             image = VG_INVALID_HANDLE;
       
  1241             }
       
  1242         
       
  1243         eglDestroySurface( display, newSurface );
       
  1244         HUI_VG_INVARIANT();
       
  1245         return image;
       
  1246         }
       
  1247     CHuiStatic::SetCurrentRenderSurface( NULL );
       
  1248     
       
  1249     
       
  1250     // VKN TODO: It would be better, if the GC could somehow spot that openVg
       
  1251     // state has changed, and would restore it's own state. Could use the same
       
  1252     // AddRestoreStateFlags as the paint is currently using..
       
  1253     //
       
  1254     // Get the current statematrix and store it for the duration of NVG drawing
       
  1255     TReal32 matrix[9];
       
  1256     vgGetMatrix(matrix);
       
  1257     vgLoadIdentity();
       
  1258     
       
  1259     // Render the NVGtexture into the image buffer. No transformations are done for this.
       
  1260     SetNvgParamsFromIconHeader(*aNvgEngine, aNVGData);
       
  1261     
       
  1262     if (iIconCommands)
       
  1263         {
       
  1264         //HUI_DEBUG(_L("CHuiVg10Texture::CreateRenderedImage() - Drawing iIconCommands"));
       
  1265         iIconCommands->Draw(aDestSize, aNvgEngine);
       
  1266         }
       
  1267     else
       
  1268         {
       
  1269         // If ObjectCached version failed, try to use the old way
       
  1270         //HUI_DEBUG(_L("CHuiVg10Texture::CreateRenderedImage() - Drawing with DrawNvg"));
       
  1271         VGint blendMode = vgGeti(VG_BLEND_MODE);
       
  1272         vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
       
  1273         aNvgEngine->DrawNvg(GetNvgDataWithoutHeader(aNVGData), aDestSize, NULL, NULL);
       
  1274         vgSeti(VG_BLEND_MODE, blendMode);
       
  1275         }
       
  1276     
       
  1277     // NVG-TLV icon margin special case check:
       
  1278     // Check, if the icon has to be margin corrected
       
  1279     TAknIconHeader iconheader = GetNvgIconHeader(aNVGData);
       
  1280     TSize size = aDestSize; // For using the correct size also later on
       
  1281     if (iconheader.IsMarginCorrection())
       
  1282         {
       
  1283         size = ApplyMargin(image, aDestSize, display, newSurface, context);
       
  1284         if( size != aDestSize)
       
  1285             {
       
  1286             // Redo the drawing, this time to the correct size
       
  1287             if (iIconCommands)
       
  1288                 iIconCommands->Draw(size, aNvgEngine);
       
  1289             else
       
  1290                 aNvgEngine->DrawNvg(GetNvgDataWithoutHeader(aNVGData), size, NULL, NULL);
       
  1291             }
       
  1292         }
       
  1293     
       
  1294     // The NVG draw messes up the paint, scissoring & rects, so mark them as dirty
       
  1295     TInt dirtyFlags = EHuiVg10GcStateFlagDirtyPaint |
       
  1296                     EHuiVg10GcStateFlagDirtyScissor | 
       
  1297                     EHuiVg10GcStateFlagDirtyScissorRects;
       
  1298     iRenderPlugin.AddRestoreStateFlags(dirtyFlags);
       
  1299     
       
  1300 #ifdef _DEBUG
       
  1301     // TODO: There's something in the DrawNvg() code, which causes OpenVg to set
       
  1302     // error code => PANIC, if not for this temp check here. REMOVE ONCE THE TSW ERROR IS FIXED!
       
  1303     VGErrorCode err = vgGetError();
       
  1304     if (err)
       
  1305         {
       
  1306         RDebug::Print(_L("CHuiVG10Texture::CreateRenderedImage - Error in NVG draw: %04x"), err);
       
  1307         }
       
  1308 #endif
       
  1309     
       
  1310     HUI_VG_INVARIANT();
       
  1311     
       
  1312     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
  1313     vgLoadMatrix(matrix);
       
  1314     oldSurface->MakeCurrent();  // This will also call the SetCurrentRenderSurface
       
  1315     
       
  1316     // Now we should have a rendered image in the image variable!
       
  1317     // Release the surface, but not the context because we used a shared context
       
  1318     if ( newSurface != EGL_NO_SURFACE )
       
  1319         {
       
  1320         eglDestroySurface( display, newSurface );
       
  1321         }
       
  1322     
       
  1323     // NVG-TLV color correction special case check: If the icon has 
       
  1324     // some color specified in the icon header, set the new icon color
       
  1325     TUint32 iconColor = iconheader.GetIconColor();
       
  1326     if (iconColor & 0x00FFFFFF)
       
  1327         {
       
  1328         SetIconColor(image, size, iconColor);
       
  1329         }
       
  1330     
       
  1331     HUI_VG_INVARIANT();
       
  1332     
       
  1333     return image;
       
  1334     }
       
  1335 
       
  1336 TBool CHuiVg10Texture::IsExtended() const
       
  1337     {
       
  1338     return iIsExtended;
       
  1339     }
       
  1340 
       
  1341 HBufC8* CHuiVg10Texture::GetExtendedTextureData() const
       
  1342     {
       
  1343     return iNVGData;
       
  1344     }
       
  1345 
       
  1346 MNVGIcon* CHuiVg10Texture::GetIconCommandsData() const
       
  1347     {
       
  1348     return iIconCommands;
       
  1349     }
       
  1350 
       
  1351 void CHuiVg10Texture::CreateObjCachedNVGIconL()
       
  1352     {
       
  1353     HUI_VG_INVARIANT();
       
  1354     // Just to be sure that we don't leak memory
       
  1355     if (iIconCommands)
       
  1356         {
       
  1357         HUI_DEBUG(_L("CHuiVg10Texture::CreateObjCachedNVGIconL() - deleting old iIconCommands. Should never come here"));
       
  1358         delete iIconCommands;
       
  1359         iIconCommands = NULL;
       
  1360         }
       
  1361 
       
  1362     // Fetch the NvgDecoder engine for creating the obj cached icon
       
  1363     CNvgEngine& nvgEngine = iRenderPlugin.NvgEngine();
       
  1364     
       
  1365     //Set Parameters from Icon Header
       
  1366     SetNvgParamsFromIconHeader(nvgEngine, iNVGData);
       
  1367     
       
  1368     // Parse the header info out of the nvg data 
       
  1369     TPtr8 nvgDataVoidIC = GetNvgDataWithoutHeader(iNVGData);
       
  1370     
       
  1371 	iIconCommands = nvgEngine.CreateNVGIcon(nvgDataVoidIC, Size());
       
  1372 	
       
  1373 	HUI_VG_INVARIANT();
       
  1374     }
       
  1375 
       
  1376 TAknIconHeader CHuiVg10Texture::GetNvgIconHeader(HBufC8* aNVGData)
       
  1377     {
       
  1378     // Parse the icon header info from the extended data
       
  1379     TPtr8 IconHeaderPtr((TUint8*)aNVGData->Des().Ptr(), KIconHeaderLength, KIconHeaderLength);
       
  1380     TAknIconHeader iconheader(IconHeaderPtr);
       
  1381     
       
  1382     return iconheader;
       
  1383     }
       
  1384 
       
  1385 TPtr8 CHuiVg10Texture::GetNvgDataWithoutHeader(HBufC8* aNVGData)
       
  1386     {
       
  1387     // The rest of the data (after the iconheader) are the OVG drawing instructions
       
  1388     TInt lengthAfterHeader = aNVGData->Length() - KIconHeaderLength;
       
  1389     TPtr8 nvgDataVoidIC((TUint8 *)aNVGData->Des().Ptr() + KIconHeaderLength, lengthAfterHeader, lengthAfterHeader);
       
  1390     
       
  1391     return nvgDataVoidIC;
       
  1392     }
       
  1393 
       
  1394 void CHuiVg10Texture::SetNvgParamsFromIconHeader(CNvgEngine& aNvgEngine, HBufC8* aNVGData)
       
  1395     {
       
  1396     TAknIconHeader iconheader = GetNvgIconHeader(aNVGData);
       
  1397     
       
  1398     // Set preserve aspect ratio according to the header info
       
  1399     TNvgAlignStatusType alignTypeValue = ENvgPreserveAspectRatio_XmidYmid;
       
  1400     TNvgMeetOrSliceType meetOrSliceTypeValue = ENvgMeet;
       
  1401     
       
  1402     switch ( iconheader.GetScaleMode() )
       
  1403         {
       
  1404         case EAspectRatioPreserved: // Fall through
       
  1405             {
       
  1406             // Use default
       
  1407             break;
       
  1408             }
       
  1409             
       
  1410         // Ensures NVG content fully covers
       
  1411         // the area of the icon whilst preserving aspect ratio.
       
  1412         case EAspectRatioPreservedSlice:
       
  1413             {
       
  1414             // alignTypeValue use default
       
  1415             meetOrSliceTypeValue = ENvgSlice;
       
  1416             break;
       
  1417             } 
       
  1418             
       
  1419         // EAspectRatioPreservedAndUnusedSpaceRemoved is mapped to the same
       
  1420         // values as EAspectRatioNotPreserved because we already have a 
       
  1421         // frame buffer with the dimensions that preserves the aspect ratio.
       
  1422         // This mapping ensures that NVG engine does not calculate aspect
       
  1423         // ratio twice and potentially resulting in precision loss.
       
  1424         case EAspectRatioPreservedAndUnusedSpaceRemoved:
       
  1425         case EAspectRatioNotPreserved:
       
  1426             {            
       
  1427             alignTypeValue = ENvgPreserveAspectRatio_None;
       
  1428             // meetOrSliceTypeValue used default
       
  1429             break;
       
  1430             }
       
  1431         }
       
  1432     aNvgEngine.SetPreserveAspectRatio(alignTypeValue, meetOrSliceTypeValue);
       
  1433     aNvgEngine.Rotate(iconheader.GetRotation(),Size().iWidth >>1, Size().iHeight >>1);
       
  1434     }
       
  1435 
       
  1436 TSize CHuiVg10Texture::ApplyMargin(VGImage aImage, TSize aSize, EGLDisplay aDisplay, EGLSurface aSurface, EGLContext aContext)
       
  1437     {
       
  1438     HUI_VG_INVARIANT();
       
  1439     // If the icon is also a current EGL surface, the getImageSubData
       
  1440     // won't succeed and return "image in use" -error..
       
  1441     if ( eglMakeCurrent( aDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ) == EGL_FALSE )
       
  1442         {
       
  1443         HUI_DEBUG1(_L("CHuiVg10Texture::ApplyMargin() - EGL NO_Surface could not be made current, eglErr: %04x"), eglGetError());
       
  1444         return aSize;
       
  1445         }
       
  1446     
       
  1447 #ifndef __WINS__ // Should possibly query the supported mode instead?
       
  1448     VGImageFormat imageInternalFormat = VG_sARGB_8888_PRE;
       
  1449 #else
       
  1450     // This doesn't work in the Emulator anyways.. => remove?
       
  1451     VGImageFormat imageInternalFormat = VG_sARGB_8888;
       
  1452 #endif
       
  1453     
       
  1454     TInt stride = aSize.iWidth * 4; // VG_sARGB_8888(_PRE) is four bytes long (8888)
       
  1455     HBufC8* buf = HBufC8::New(stride);
       
  1456     if (!buf)
       
  1457         {
       
  1458         HUI_DEBUG(_L("CHuiVg10Texture::ApplyMargin() - Ran out of memory!"));
       
  1459         return aSize;        
       
  1460         }
       
  1461     TUint32* ptr = (TUint32*)(buf->Des()).Ptr();
       
  1462     
       
  1463     const TInt lValidMargin = aSize.iHeight * 12 / 100;
       
  1464     
       
  1465     const TInt Ha = aSize.iHeight;
       
  1466     TInt hTa = 0;
       
  1467     TInt hNT = 0;
       
  1468     TInt C = 0;
       
  1469     TInt hNTN = Ha - 2.0 * 0.12 * Ha;
       
  1470     TReal R = 1.0;
       
  1471     TInt HaN = Ha;
       
  1472     
       
  1473     const TInt lastColumn = aSize.iHeight - 1;
       
  1474     for (TInt curRow = 0; curRow < lValidMargin; curRow++)
       
  1475         {
       
  1476         const TInt y = (aSize.iHeight - 1) - curRow; // h - 1 is the last line
       
  1477         // Get just one stride at a time (iWidth wide, 1 pixel high)
       
  1478         vgGetImageSubData(aImage, ptr, stride, imageInternalFormat, 0, y, aSize.iWidth, 1);
       
  1479         for (TInt s = lastColumn; s >= 0; --s)
       
  1480             {
       
  1481             if (ptr[s] & 0xFF000000)
       
  1482                 {
       
  1483                 hTa = curRow;
       
  1484                 hNT = Ha - 2 * hTa;
       
  1485                 C = 2 * hTa;
       
  1486                 R = ( ( (TReal)hNTN / (TReal)hNT ) > 1.0 ) ? 1 : (TReal)hNTN / (TReal)hNT;
       
  1487                 HaN = Ha * R - C * R + C;
       
  1488                 curRow = lValidMargin; // to exit the outer loop
       
  1489                 break; // to exit the inner
       
  1490                 }
       
  1491             }
       
  1492         }
       
  1493     delete buf;
       
  1494     HUI_VG_INVARIANT();
       
  1495     
       
  1496     // Make the PBuffer surface current again 
       
  1497     if ( eglMakeCurrent(aDisplay, aSurface, aSurface, aContext) == EGL_FALSE )
       
  1498         {
       
  1499         HUI_DEBUG1(_L("CHuiVg10Texture::ApplyMargin() - EGL aSurface could not be made current, eglErr: %04x"), eglGetError());
       
  1500         return aSize;
       
  1501         }
       
  1502     
       
  1503     // If icon size has to be changed, clear out old area for new DrawNVG round!
       
  1504     if(aSize.iHeight > HaN)
       
  1505         {
       
  1506         vgLoadIdentity();
       
  1507         
       
  1508         VGfloat color[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
       
  1509         vgSetfv(VG_CLEAR_COLOR, 4, color);
       
  1510         vgClear(0, 0, aSize.iWidth, aSize.iHeight);
       
  1511         // Or should it be clearImage instead?
       
  1512         //vgClearImage(aImage, 0, 0, aSize.iWidth, aSize.iHeight);
       
  1513         
       
  1514         VGfloat Hr = (VGfloat)HaN/(aSize.iHeight);        
       
  1515         TInt WaN = aSize.iWidth*Hr;
       
  1516         
       
  1517         VGfloat Tx = (aSize.iHeight-HaN)/2;
       
  1518         VGfloat Ty = (aSize.iWidth-WaN)/2;
       
  1519         vgTranslate(Tx,Ty);
       
  1520         
       
  1521         HUI_VG_INVARIANT();
       
  1522         return(TSize(HaN,WaN));
       
  1523         }
       
  1524     
       
  1525     HUI_VG_INVARIANT();
       
  1526     return aSize;
       
  1527     }
       
  1528 
       
  1529 void CHuiVg10Texture::SetIconColor(VGImage& aSrcImage, TSize aSize, TUint32 aColor)
       
  1530     {
       
  1531     // TODO: DOESN'T WORK IN EMULATOR FOR SOME REASON! Figure out why!
       
  1532     HUI_VG_INVARIANT();
       
  1533     
       
  1534     vgSeti(VG_FILTER_FORMAT_LINEAR, VG_FALSE);
       
  1535     
       
  1536 #ifndef __WINS__ // Should possibly query the supported mode instead?
       
  1537     VGImageFormat imageInternalFormat = VG_sARGB_8888_PRE;
       
  1538     // TODO: !!! SHOULD FORMAT_PREMULTIPLIED BE APPLIED?? !!!
       
  1539     //vgSeti(VG_FILTER_FORMAT_PREMULTIPLIED, VG_TRUE);
       
  1540 #else
       
  1541     // This doesn't work in the Emulator anyways.. => remove?
       
  1542     VGImageFormat imageInternalFormat = VG_sARGB_8888;
       
  1543 #endif
       
  1544     
       
  1545     // Rip the RGB components from the aColor param & scale to [0..1]
       
  1546     VGfloat red      = (aColor&0xff)/255.0f;
       
  1547     VGfloat green    = ((aColor>>8)&0xff)/255.0f;
       
  1548     VGfloat blue     = ((aColor>>16)&0xff)/255.0f;
       
  1549     
       
  1550     //vgSeti(VG_FILTER_CHANNEL_MASK, VG_ALPHA );
       
  1551     // This matrix will set all color components in the source image to 0,
       
  1552     // and replaces the RGB with the values from the iconheader 
       
  1553     VGfloat matrix[20] = {
       
  1554             0,0,0,0,
       
  1555             0,0,0,0,
       
  1556             0,0,0,0,
       
  1557             0,0,0,1, // <- Preserves the original alpha value
       
  1558             red, green, blue, 0};
       
  1559     
       
  1560     // Create the destination image & start modifying colors
       
  1561     VGImage dstImg = vgCreateImage(imageInternalFormat, aSize.iWidth, aSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
       
  1562     vgColorMatrix(dstImg, aSrcImage, matrix);
       
  1563     HUI_VG_INVARIANT();
       
  1564     
       
  1565     // Destroy the old source image and return the new image with changed colors
       
  1566     vgDestroyImage(aSrcImage);
       
  1567     aSrcImage = dstImg;
       
  1568     
       
  1569     HUI_VG_INVARIANT();
       
  1570     }
       
  1571 
       
  1572 void CHuiVg10Texture::ReplaceVGImageAlphaChannelL(VGImage aImage, VGImage aMaskImage, TSize aSize)
       
  1573     {
       
  1574     HUI_VG_INVARIANT();
       
  1575     
       
  1576 #ifndef __WINS__ // Should possibly query the supported mode instead?
       
  1577     VGImageFormat imageInternalFormat = VG_sARGB_8888_PRE;
       
  1578 #else
       
  1579     VGImageFormat imageInternalFormat = VG_sARGB_8888;
       
  1580 #endif
       
  1581     TInt height = aSize.iHeight;
       
  1582     TInt width = aSize.iWidth;
       
  1583     const TInt colorDepth = 4;  // VG_sARGB_8888(_PRE) 4 bytes long
       
  1584     TInt stride = width * colorDepth;
       
  1585     
       
  1586     // Create the pointers to RAM in which the image data will be saved temporarily
       
  1587     HBufC8* imgBuf = HBufC8::NewL(width * height * colorDepth);
       
  1588     CleanupStack::PushL(imgBuf);
       
  1589     TUint32* imgPtr = (TUint32*)(imgBuf->Des()).Ptr();
       
  1590     const TUint32* imgSavePtr = (TUint32*)(imgBuf->Des()).Ptr(); 
       
  1591     
       
  1592     HBufC8* maskBuf = HBufC8::NewL(width * height * colorDepth);
       
  1593     CleanupStack::PushL(maskBuf);
       
  1594     TUint32* maskPtr = (TUint32*)(maskBuf->Des()).Ptr();
       
  1595     
       
  1596     // Get the image pixel data
       
  1597     vgGetImageSubData(aImage, imgPtr, stride, imageInternalFormat, 0, 0, width, height);
       
  1598     vgGetImageSubData(aMaskImage, maskPtr, stride, imageInternalFormat, 0, 0, width, height);
       
  1599     
       
  1600     // Replace destination image's alpha values with mask image
       
  1601     for (TInt y = 0; y < height; y++)
       
  1602         {
       
  1603         for (TInt x = 0; x < width; x++)
       
  1604             {
       
  1605             *maskPtr    &= 0xff000000;      // Remove other than alpha component from source pixel
       
  1606             *imgPtr     &= ~0xff000000;     // Remove alpha channel value from destination pixel
       
  1607             *imgPtr++   |= *maskPtr++;      // Bitwise OR the maskImg alpha info to destination image pixel 
       
  1608             }
       
  1609         }
       
  1610 
       
  1611     // Replace the destination image with combined alpha information from src image
       
  1612     vgImageSubData(aImage, imgSavePtr, stride, imageInternalFormat, 0, 0, width, height);
       
  1613 
       
  1614     CleanupStack::PopAndDestroy(maskBuf);
       
  1615     CleanupStack::PopAndDestroy(imgBuf);
       
  1616     
       
  1617     HUI_VG_INVARIANT();
       
  1618     }
       
  1619 #endif
       
  1620 
       
  1621 
       
  1622 void CHuiVg10Texture::PushEGLContext()
       
  1623     {
       
  1624     iPreviousEGLState.iContext= eglGetCurrentContext(); 
       
  1625     TEGLState& state = iRenderPlugin.GetUploadState();
       
  1626     if (state.iContext == KErrNotFound)
       
  1627         {
       
  1628 		TEGLState& state = iRenderPlugin.GetUploadState();
       
  1629         // the first context used for uploading will be used for all texture uploads
       
  1630         state.iContext      = iPreviousEGLState.iContext; 
       
  1631         state.iDrawSurface  = eglGetCurrentSurface(EGL_DRAW);
       
  1632         state.iReadSurface  = eglGetCurrentSurface(EGL_READ);
       
  1633         state.iDisplay      = eglGetCurrentDisplay();
       
  1634         }
       
  1635     else
       
  1636         {
       
  1637         // change context only if necessary
       
  1638         if (iPreviousEGLState.iContext != state.iContext)
       
  1639             {
       
  1640             iPreviousEGLState.iDrawSurface  = eglGetCurrentSurface(EGL_DRAW);
       
  1641             iPreviousEGLState.iReadSurface  = eglGetCurrentSurface(EGL_READ);
       
  1642             iPreviousEGLState.iDisplay      = eglGetCurrentDisplay();
       
  1643             eglMakeCurrent(state.iDisplay, state.iDrawSurface, state.iReadSurface, state.iContext);
       
  1644             }
       
  1645         }
       
  1646     }
       
  1647 
       
  1648 void CHuiVg10Texture::PopEGLContext()
       
  1649     {
       
  1650     if (iPreviousEGLState.iContext != iRenderPlugin.GetUploadState().iContext)
       
  1651         {
       
  1652         eglMakeCurrent(iPreviousEGLState.iDisplay,  iPreviousEGLState.iDrawSurface, iPreviousEGLState.iReadSurface,iPreviousEGLState.iContext);
       
  1653         }
       
  1654     }
       
  1655 // End of file
       
  1656