diff -r 57ed406024d5 -r f6fd4830a02c uigraphics/NVGRenderStage/src/nvgrenderstage.cpp --- a/uigraphics/NVGRenderStage/src/nvgrenderstage.cpp Fri Jan 29 16:56:39 2010 +0000 +++ b/uigraphics/NVGRenderStage/src/nvgrenderstage.cpp Thu Jan 07 12:19:27 2010 +0000 @@ -20,11 +20,22 @@ #include #include +TCachedConversion::TCachedConversion() : + iLink(), iCachedResult(NULL) + {} + +TCachedConversion::~TCachedConversion() + { + delete iCachedResult; + } const TUid KUidNvgExtendedBitmap = {0x39b9273e}; CNvgRenderStage::CNvgRenderStage() : - iExtendedBitmapError(KErrNone) + iExtendedBitmapError(KErrNone), + iCache(_FOFF(TCachedConversion,iLink)), + iCacheIterator(iCache), + iCacheFree(MAX_NVG_CACHE_SIZE) { } @@ -46,8 +57,6 @@ void CNvgRenderStage::ConstructL(CWsRenderStage* aNextStage) { - iBmp = new(ELeave) CFbsBitmap; - iMaskBmp = new(ELeave) CFbsBitmap; iBrushPattern = new(ELeave) CFbsBitmap; iInternalBrushPattern = new(ELeave) CFbsBitmap; iGraphicsInterface = new(ELeave) CVGIGraphicsInterface; @@ -61,12 +70,18 @@ CNvgRenderStage::~CNvgRenderStage() { iEmptyRegion.Close(); - delete iBmp; - delete iMaskBmp; delete iBrushPattern; delete iInternalBrushPattern; delete iNvgEngine; delete iGraphicsInterface; + + iCacheIterator.SetToFirst(); + TCachedConversion* cached = iCacheIterator++; + while (cached != NULL) + { + delete cached; + cached = iCacheIterator++; + } } /** The only interface returned by this render stage is MWsGraphicsContext. @@ -156,15 +171,14 @@ { if (iGc) { + CFbsBitmap* sourceBitmap = const_cast(&aSourceBitmap); + if (aSourceBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) - { - TRect destRect(TPoint(aDestPos.iX,aDestPos.iY), aSourceBitmap.SizeInPixels()); - DrawExtendedBitmap(*iGc, destRect, aSourceBitmap); + { + sourceBitmap = GetConvertedBitmap(aSourceBitmap); } - else - { - iGc->BitBlt(aDestPos, aSourceBitmap); - } + + iGc->BitBlt(aDestPos, *sourceBitmap); } } @@ -178,15 +192,14 @@ { if (iGc) { + CFbsBitmap* sourceBitmap = const_cast(&aSourceBitmap); + if (aSourceBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) - { - TRect destRect(TPoint(aDestPos.iX,aDestPos.iY), aSourceRect.Size()); - DrawExtendedBitmap(*iGc, destRect, aSourceBitmap); + { + sourceBitmap = GetConvertedBitmap(aSourceBitmap); } - else - { - iGc->BitBlt(aDestPos, aSourceBitmap, aSourceRect); - } + + iGc->BitBlt(aDestPos, *sourceBitmap, aSourceRect); } } @@ -205,14 +218,12 @@ if (aSourceBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(aSourceBitmap, *iBmp); - sourceBitmap = iBmp; + sourceBitmap = GetConvertedBitmap(aSourceBitmap); } if (aMaskBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(aMaskBitmap, *iMaskBmp); - maskBitmap = iMaskBmp; + maskBitmap = GetConvertedBitmap(aMaskBitmap); } iGc->BitBltMasked(aDestPos, *sourceBitmap, aSourceRect, *maskBitmap, aInvertMask); @@ -234,14 +245,12 @@ if (aSourceBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(aSourceBitmap, *iBmp); - sourceBitmap = iBmp; + sourceBitmap = GetConvertedBitmap(aSourceBitmap); } if (aMaskBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(aMaskBitmap, *iMaskBmp); - maskBitmap = iMaskBmp; + maskBitmap = GetConvertedBitmap(aMaskBitmap); } iGc->BitBltMasked(aDestPos, *sourceBitmap, aSourceRect, *maskBitmap, aMaskPos); @@ -332,8 +341,7 @@ if (aSourceBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(aSourceBitmap, *iBmp); - sourceBitmap = iBmp; + sourceBitmap = GetConvertedBitmap(aSourceBitmap); } iGc->DrawBitmap(aDestRect, *sourceBitmap); @@ -354,8 +362,7 @@ if (aSourceBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(aSourceBitmap, *iBmp); - sourceBitmap = iBmp; + sourceBitmap = GetConvertedBitmap(aSourceBitmap); } iGc->DrawBitmap(aDestRect, *sourceBitmap, aSourceRect); @@ -377,13 +384,11 @@ if (aSourceBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(aSourceBitmap, *iBmp); - sourceBitmap = iBmp; + sourceBitmap = GetConvertedBitmap(aSourceBitmap); } if (aMaskBitmap.ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(aMaskBitmap, *iMaskBmp); - maskBitmap = iMaskBmp; + maskBitmap = GetConvertedBitmap(aMaskBitmap); } iGc->DrawBitmapMasked(aDestRect, *sourceBitmap, aSourceRect, *maskBitmap, aInvertMask); @@ -783,7 +788,7 @@ iBrushPattern->Duplicate(aFbsBitmapHandle); if (iBrushPattern->ExtendedBitmapType() == KUidNvgExtendedBitmap) { - CopyExtendedBitmapToNormalBitmap(*iBrushPattern, *iInternalBrushPattern); + iInternalBrushPattern = GetConvertedBitmap(*iBrushPattern); iGc->SetBrushPattern(*iInternalBrushPattern); } else @@ -984,36 +989,92 @@ } } -/** Helper method used by BitBlt() and DrawBitmap() + +/** Helper method that draws an NVG extended bitmap into a normal bitmap. -@param aGc The graphics context to draw the extended bitmap to. -@param aDestRect The rectangle that the source bitmap will be drawn to. -@param aSourceBitmap The extended bitmap of type 0x39b9273e to be drawn. +@param aExtendedBitmapSrc The extended bitmap to draw + +@pre aExtendedBitmapSrc must be an extended bitmap of extended bitmap type 0x39b9273e + */ -@pre aSourceBitmap must be an extended bitmap of type 0x39b9273e. -@post Sets an error that can be retrieved using GetError() is an error occurs. - */ -void CNvgRenderStage::DrawExtendedBitmap(MWsGraphicsContext& aGc, const TRect& aDestRect, const CFbsBitmap& aSourceBitmap) - { - CopyExtendedBitmapToNormalBitmap(aSourceBitmap, *iBmp); - aGc.BitBlt(aDestRect.iTl, *iBmp); - } +CFbsBitmap* CNvgRenderStage::GetConvertedBitmap(const CFbsBitmap& aExtendedBitmapSrc) + { + aExtendedBitmapSrc.BeginDataAccess(); + const TUint8* bmpData = (const TUint8*)aExtendedBitmapSrc.DataAddress(); + + TPtr8 IconHeaderPtr((TUint8*)bmpData, KIconHeaderLength, KIconHeaderLength); + TAknIconHeader iconheader(IconHeaderPtr); -/** Helper method used by BitBlt() and DrawBitmap() - -@param aGc The graphics context to draw the extended bitmap to. -@param aDestRect The rectangle that the source bitmap will be drawn to. -@param aSourceBitmap The extended bitmap of type 0x39b9273e to be drawn. + TUint32 bitmapid = iconheader.GetBitmapId(); + TUint32 handle = aExtendedBitmapSrc.Handle(); + aExtendedBitmapSrc.EndDataAccess(); + CFbsBitmap* error = const_cast(&aExtendedBitmapSrc); // not renderable, but better than panic! + + // look to see if we have this in the cache + iCacheIterator.SetToFirst(); + TCachedConversion* cached = iCacheIterator++; + while (cached != NULL) + { + if (cached->iBitmapID == bitmapid && cached->iDiscriminator == handle) + { + // Cache hit +#ifdef DEBUG_NVG_RENDERSTAGE + RDebug::Printf("NVG Render cache hit for id %08x, handle %d\n", bitmapid, handle); +#endif + cached->Deque(); + iCache.AddFirst(*cached); // move to front of the list, to record use + return cached->iCachedResult; + } + cached = iCacheIterator++; + } + + // missed in the cache, need to perform the conversion + TInt err = KErrNone; + if (iCacheFree > 0) + { + // just allocate a new entry, which will be added to the end + TRAP(err, cached = new(ELeave) TCachedConversion); + if (err != KErrNone) + { + return error; + } + TRAP(err, cached->iCachedResult = new(ELeave) CFbsBitmap); + if (err != KErrNone) + { + delete cached; + return error; + } + } + else + { + // Remove the least recently used item + cached = iCache.Last(); + cached->Deque(); // remove from the cache + iCacheFree++; +#ifdef DEBUG_NVG_RENDERSTAGE + RDebug::Printf("NVG Render cache removing id %08x, handle %d\n", cached->iBitmapID, cached->iDiscriminator); +#endif + } + + // cached is now available to hold the new result + cached->iBitmapID = bitmapid; + cached->iDiscriminator = handle; -@pre aSourceBitmap must be an extended bitmap of type 0x39b9273e. -@post Sets an error that can be retrieved using GetError() is an error occurs. - */ -void CNvgRenderStage::DrawExtendedBitmap(CFbsBitGc& aGc, const TRect& aDestRect, const CFbsBitmap& aSourceBitmap) - { - CopyExtendedBitmapToNormalBitmap(aSourceBitmap, *iBmp); - aGc.BitBlt(aDestRect.iTl, iBmp); - } - + CopyExtendedBitmapToNormalBitmap(aExtendedBitmapSrc, *cached->iCachedResult); + if (iExtendedBitmapError != KErrNone) + { + delete cached; + return error; + } + + // Newly cached bitmap is valid + iCache.AddFirst(*cached); + iCacheFree--; +#ifdef DEBUG_NVG_RENDERSTAGE + RDebug::Printf("NVG Render cache added id %08x, handle %d (%d free)\n", bitmapid, handle, iCacheFree); +#endif + return cached->iCachedResult; + } /** Helper method that draws an NVG extended bitmap into a normal bitmap. The normal bitmap passed is resized before the extended bitmap is drawn into it. @@ -1024,6 +1085,7 @@ @pre aExtendedBitmapSrc must be an extended bitmap of extended bitmap type 0x39b9273e @post aBitmapDest has been reset and resized and now contains a representation of the aExtendedBitmapSrc */ + void CNvgRenderStage::CopyExtendedBitmapToNormalBitmap(const CFbsBitmap& aExtendedBitmapSrc, CFbsBitmap& aBitmapDst) { TSize size = aExtendedBitmapSrc.SizeInPixels(); @@ -1053,6 +1115,10 @@ TPtr8 IconHeaderPtr((TUint8*)bmpData, KIconHeaderLength, KIconHeaderLength); TAknIconHeader iconheader(IconHeaderPtr); +#ifdef DEBUG_NVG_RENDERSTAGE + RDebug::Printf("ConvertExtendedBitmap: id=%08x size (%d x %d)\n", iconheader.GetBitmapId(), size.iWidth, size.iHeight); +#endif + TInt dataSize = aExtendedBitmapSrc.DataSize(); // skip TNVGIconHeader structure - we only know about version 0 if (bmpData[2] == 0)