tvout/tvoutengine/src/glxhdmisurfaceupdater.cpp
branchRCL_3
changeset 59 8e5f6eea9c9f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvout/tvoutengine/src/glxhdmisurfaceupdater.cpp	Tue Aug 31 15:14:51 2010 +0300
@@ -0,0 +1,981 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:    
+*
+*/
+
+#include <graphics/surface.h>
+#include <graphics/surfacemanager.h>
+#include <graphics/surfaceupdateclient.h>
+#include <graphics/surface_hints.h>
+#include <e32math.h>
+#include <apgcli.h>
+#include "alf/alfcompositionclient.h" 
+
+#include <imageconversion.h> 
+#include <fbs.h>
+#include <glxtracer.h>
+#include <glxlog.h>
+
+#include "glxactivecallback.h"
+#include "glxhdmisurfaceupdater.h"
+#include "glxactivedecoder.h"
+#include <bitdev.h> 
+
+const TInt KMulFactorToCreateBitmap = 4;
+const TInt KZoomDelay = 10000;
+const TInt KAnimationTicker = 26000;
+const TInt KAnimationTickerFadeIn = 45000; 
+//100 , is decide for 20 steps of zooming , with each step being 5 pixels.
+const TInt KMaxZoomLimit = 100;
+//evey time we zoom , there is a increase in the ht amd width by 10 pixels.
+const TInt KSingleStepForZoom = 10;
+
+// constants for fade effect
+const TInt KFadeSteps = 19;
+const TReal32 KFadeEachStep = 0.05f;
+const TReal32 KFullTransparent = 0.0f;
+const TReal32 KFullOpaque = 1.0f;
+
+_LIT(KMimeJpeg,"image/jpeg");
+_LIT(KMimeJpg,"image/jpg");
+
+// -----------------------------------------------------------------------------
+// NewLC
+// -----------------------------------------------------------------------------
+CGlxHdmiSurfaceUpdater* CGlxHdmiSurfaceUpdater::NewL(RWindow* aWindow, const TDesC& aImageFile, 
+                                                      CFbsBitmap* aFsBitmap, 
+                                                      MGlxGenCallback* aCallBack,
+                                                      TBool aEffectsOn)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater* CGlxHdmiSurfaceUpdater::NewL()");
+    CGlxHdmiSurfaceUpdater* self = new (ELeave) CGlxHdmiSurfaceUpdater(aWindow, aCallBack, aEffectsOn);
+    CleanupStack::PushL(self);
+    self->ConstructL(aFsBitmap,aImageFile);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// destructor 
+// -----------------------------------------------------------------------------
+CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater()");
+    ReleaseContent();
+    if(iAnimTimer && iAnimTimer->IsActive())             // Check for a CPeriodic Instance
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater() - cancel iAnimTimer");
+        iAnimTimer->Cancel();
+        }
+    GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater() - deleteing ialfCompositionSurface");
+    delete ialfCompositionSurface;
+    if(iWindow)
+        {
+        iWindow->RemoveBackgroundSurface(ETrue);
+        }
+	if(iTimer && iTimer->IsActive())	 	 	 // Check for a CPeriodic Instance
+        {
+        iTimer->Cancel();
+        }
+    delete iTimer;   
+    delete iGlxDecoderAO;
+    iFsSession.Close();
+    if (iSurfManager)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater() - Close"); 
+        if(iSurfSessionConnected)
+            {
+            iSurfUpdateSession.Close();
+            }
+        if (iSurfChunk)
+            {
+            iSurfChunk->Close();
+            }            
+        delete iSurfChunk;
+        iSurfChunk = NULL;        
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater(). iSurfManager->CloseSurface()"); 
+        iSurfManager->CloseSurface(iSurfId);
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater(). iSurfManager->Close()"); 
+        iSurfManager->Close();
+        delete iSurfManager;
+        iSurfManager = NULL;       
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// ReleaseContent 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ReleaseContent()
+    {
+    TRACER("void CGlxHdmiSurfaceUpdater::ReleaseContent()"); 
+    if ( iGlxDecoderAO )
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -1");
+        iGlxDecoderAO->Cancel();
+        }
+    if (iFsBitmap)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -2");
+        delete iFsBitmap;
+        iFsBitmap = NULL;
+        }
+    for (TInt i=0; i<=2 ; i++)
+        {
+        GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ReleaseContent() -3, %d", i);
+        delete iDecodedBitmap[i];
+        iDecodedBitmap[i]= NULL;
+        }
+    GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -4");
+    if(iSurfBufferAO && iSurfBufferAO->IsActive())
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -5");
+		iSurfBufferAO->Cancel();
+        }
+    if ( iImageDecoder )
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -6");
+        delete iImageDecoder;
+        iImageDecoder = NULL;    
+        }
+    if (iSurfSessionConnected &&  iSurfManager)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ReleaseContent() -7");
+        iSurfUpdateSession.CancelAllUpdateNotifications();
+        }
+    if (iImagePath)
+        {
+        delete iImagePath;
+        iImagePath = NULL;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CTor 
+// -----------------------------------------------------------------------------
+CGlxHdmiSurfaceUpdater::CGlxHdmiSurfaceUpdater(RWindow* aWindow,
+                          MGlxGenCallback* aCallBack,TBool aEffectsOn): 
+                          iWindow(aWindow), iCallBack(aCallBack), 
+                          iEffectsOn(aEffectsOn),
+                          iShwFsThumbnail(ETrue), iIsNonJpeg(EFalse),
+                          iAnimCounter(0)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::CGlxHdmiSurfaceUpdater()");
+    // Implement nothing here
+    }
+
+// -----------------------------------------------------------------------------
+// ConstructL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ConstructL(CFbsBitmap* aFsBitmap, const TDesC& aImageFile)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ConstructL()");
+    // Initiate the HDMI by assigning the necessary values
+    InitiateHdmiL(aFsBitmap,aImageFile);
+    if (iEffectsOn)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ConstructL() Creating iAnimTimer");
+        iAnimTimer = CPeriodic::NewL( CActive::EPriorityStandard-1 );
+        }
+
+    TInt error = iFsSession.Connect ();
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ConstructL() FsSession Connect error = %d", error);
+    User::LeaveIfError(error);
+    iShiftToCloning = EFalse;
+    // Create the active object
+    iGlxDecoderAO = CGlxHdmiDecoderAO::NewL(this);
+
+    // Create the HDMI Decoder
+    CreateImageDecoderL();
+
+    // Create the Bitmap
+    CreateBitmapL();
+
+    // Create the surface and AO for updating the surface
+    TRAP_IGNORE(CreateHdmiL());
+
+    if(iSurfManager)
+        {
+        error = iSurfUpdateSession.Connect();
+        GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ConstructL() Surface update Session Connect error = %d", error);
+        User::LeaveIfError(error);
+        iSurfSessionConnected = ETrue;
+
+        ShowFsThumbnailL();
+#ifdef _DEBUG
+        iStartTime.HomeTime();
+#endif
+        //start decoding the image    
+        iGlxDecoderAO->ConvertImageL(*iDecodedBitmap[EJpgDecodedBitmapIndex],iImageDecoder);   
+        }
+    iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+    }
+
+// -----------------------------------------------------------------------------
+// UpdateNewImageL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::UpdateNewImageL(const TDesC& aImageFile,CFbsBitmap* aFsBitmap)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::UpdateNewImageL()");
+    ReleaseContent();   
+    // Initiate the HDMI by assigning the necessary values
+    InitiateHdmiL(aFsBitmap,aImageFile);
+    //Cancel the zoom timers if any
+    if(iTimer->IsActive())
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::UpdateNewImageL() - Cancel Zoom Timer");
+        iTimer->Cancel();
+        }
+
+    // Create the HDMI Decoder
+    CreateImageDecoderL();
+
+    // Create the Bitmap
+    CreateBitmapL();
+    if(iSurfManager)
+        {
+        // Create the surface and AO for updating the surface
+        CreateHdmiL(EFalse);
+        }
+    else
+        {
+        TRAP_IGNORE(CreateHdmiL(ETrue));
+        }
+
+#ifdef _DEBUG
+    iStartTime.HomeTime();
+#endif
+    if(iSurfManager)
+        {
+        // Show FS Thumbnail
+        ShowFsThumbnailL();
+        //start decoding the image
+        iGlxDecoderAO->ConvertImageL(*iDecodedBitmap[EJpgDecodedBitmapIndex],iImageDecoder);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// InitiateHdmiL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::InitiateHdmiL(CFbsBitmap* aFsBitmap,const TDesC& aImageFile)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::InitiateHdmiL()");
+    iImagePath = aImageFile.Alloc();
+    iFsBitmap = new (ELeave) CFbsBitmap;
+    iFsBitmap->Duplicate(aFsBitmap->Handle());
+    iIsNonJpeg = EFalse;
+    iTvScreenSize = iWindow->Size();
+
+    iBitmapReady = EFalse;
+    iLeftCornerForZoom.iX = 0; 
+    iLeftCornerForZoom.iY = 0;
+
+    iZoom = ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CreateHDMI 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::CreateHdmiL(TBool aCreateSurface)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::CreateHdmiL()");
+    
+    if (aCreateSurface)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::CreateHdmiL() Create Surface");
+        CreateSurfaceL();        
+        }
+    
+    // Active objects for double buffered draw signalling
+    if(!iSurfBufferAO)
+        {
+        iSurfBufferAO = new(ELeave) CGlxActiveCallBack(TCallBack(SurfBuffer0Ready, this),
+                    CActive::EPriorityStandard-1);
+        CActiveScheduler::Add(iSurfBufferAO);    
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CreateSurfaceL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::CreateSurfaceL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::CreateSurfaceL()");
+    iSurfManager = new(ELeave) RSurfaceManager();
+    TInt error = iSurfManager->Open();
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::CreateSurfaceL Open Surface manager error = %d", error);
+    User::LeaveIfError(error);
+    
+    //Need to set the surface Hint for the surface to indicate
+    //that photos do not need overscan compensation and the image will
+    //be displayed in 720p resolution. 
+    //Refer error: HJVA-85DD25 for more info.
+    RSurfaceManager::THintPair surfHint;
+    TUid uid(KNullUid);
+    uid.iUid = surfaceHints::KSurfaceContent;
+    surfHint.Set(uid, surfaceHints::EStillImage, EFalse);
+    
+    RSurfaceManager::TSurfaceCreationAttributesBuf attributes;
+    attributes().iPixelFormat           = EUidPixelFormatARGB_8888;// EUidPixelFormatYUV_420Planar;
+    attributes().iSize                  = iTvScreenSize;
+    
+    attributes().iBuffers               = 1;
+    attributes().iStride                = iTvScreenSize.iWidth * KMulFactorToCreateBitmap;  
+    attributes().iAlignment             = KMulFactorToCreateBitmap;
+    attributes().iContiguous            = EFalse;
+    attributes().iMappable              = ETrue;
+    attributes().iSurfaceHints          = &surfHint;
+    attributes().iHintCount             = 1;
+            
+    error = iSurfManager->CreateSurface(attributes, iSurfId);
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::CreateSurfaceL, Creating surface error : %d",error);
+    if(error == KErrNoMemory)
+    	{
+    	GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::CreateSurfaceL(). iSurfManager->Close()"); 
+		iSurfManager->Close();
+		delete iSurfManager;
+		iSurfManager = NULL;
+    	if(iShiftToCloning == EFalse)
+    		{
+    		// Show Error Note
+    		iShiftToCloning = ETrue;
+    		}
+    	ShiftToCloningMode();	 	 	 	 	 	 	  // Shift from Posting Mode to Cloning Mode
+    	}
+    User::LeaveIfError(error);
+        
+    //Map the surface and stride the surface info
+    MapSurfaceL();
+    // Set the Configuration to the surface ID when creating a surface
+    iConfig.SetSurfaceId(iSurfId);
+    }
+
+// -----------------------------------------------------------------------------
+// MapSurfaceL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::MapSurfaceL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::MapSurfaceL()");
+    
+    //Create chunk to map it to the surface ID.
+    iSurfChunk = new(ELeave) RChunk();
+    User::LeaveIfNull(iSurfChunk);    
+    TInt error = iSurfManager->MapSurface(iSurfId, *iSurfChunk);
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::MapSurfaceL(), MapSurface error : %d",error);
+    User::LeaveIfError(error);
+    
+    // Get the info from the surfaceManager
+    // and store pointers to the pixel data
+    RSurfaceManager::TInfoBuf info;
+    error = iSurfManager->SurfaceInfo(iSurfId, info);
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::MapSurfaceL(), SurfaceInfo error : %d",error);
+    User::LeaveIfError(error);  
+    
+    iSurfaceStride = info().iStride;    
+    TInt offset = 0;
+    iSurfManager->GetBufferOffset( iSurfId, 0,offset);
+    iSurfBuffer = iSurfChunk->Base()+offset;
+    }
+
+// -----------------------------------------------------------------------------
+// SurfBuffer0Ready 
+// -----------------------------------------------------------------------------
+TInt CGlxHdmiSurfaceUpdater::SurfBuffer0Ready(TAny* /*aObject*/)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::SurfBuffer0Ready()");
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// Refresh 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::Refresh()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::Refresh()");
+    // copy the decoded bitmap on to the surface
+    SwapBuffers();     
+
+    // refresh the window
+    iCallBack->DoGenCallback();       
+    }
+
+// -----------------------------------------------------------------------------
+// SwapBuffers
+// This is used to sawp the buffers shown and to be shown 
+// After this is done, a refresh to the window should be done to refresh the TV
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::SwapBuffers()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::SwapBuffers()"); 
+    TInt bitmapIndex = KErrNotFound;
+    
+    if (iShwFsThumbnail) // show FS thumbnail
+        {
+        bitmapIndex = EFSBitmapIndex;
+        }
+    else if(iIsNonJpeg && !iShwFsThumbnail) // this indicates it is non jpeg image and decoding finished
+        {
+        bitmapIndex = ENonJpgDecodedBitmapIndex;
+        }
+    else                // if none of the above state means it is jpeg image and decoding finished
+        {
+        bitmapIndex = EJpgDecodedBitmapIndex;
+        }
+        
+    // Lock the heap so that subsequent call to dataaddress doesnt happen
+    iDecodedBitmap[bitmapIndex]->LockHeap();    
+
+    // Data stride
+    TUint fs = iDecodedBitmap[bitmapIndex]->DataStride();    
+
+    //Bitmap address from where the data has to be copied.
+    TUint8* from = (TUint8*)iDecodedBitmap[bitmapIndex]->DataAddress();
+
+    //surface chunk address to where the bitmap data has to be copied.
+    TUint8* to = (TUint8*)iSurfBuffer;    
+
+    // To buffer (32 bit colors)
+    TUint ts = iSurfaceStride;
+    //No of bytes to be copied on to the surface.
+    TUint bytes = iDecodedBitmap[bitmapIndex]->SizeInPixels().iWidth * KMulFactorToCreateBitmap;
+
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::SwapBuffers() - decodeSize width = %d and height %d",
+            iDecodedBitmap[bitmapIndex]->SizeInPixels().iWidth, 
+            iDecodedBitmap[bitmapIndex]->SizeInPixels().iHeight );
+
+    // Copy the bitmap on to the surface.
+    for (TInt y = iDecodedBitmap[bitmapIndex]->SizeInPixels().iHeight; y >0; y--)
+        {
+        Mem::Copy(to, from, bytes);        
+        to += ts;        
+        from += fs;        
+        }            
+    iDecodedBitmap[bitmapIndex]->UnlockHeap();
+    }
+
+// -----------------------------------------------------------------------------
+// CreateBitmapL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::CreateBitmapL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::CreateBitmapL()");
+    TSize imageSize = iImageDecoder->FrameInfo().iOverallSizeInPixels;
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - bitmapsize=%d, %d",
+            imageSize.iWidth,imageSize.iHeight);
+    TReal32 scaleFactor = 0.0f;
+    if (iTvScreenSize.iWidth * imageSize.iHeight > iTvScreenSize.iHeight
+            * imageSize.iWidth)
+        {
+        scaleFactor = (TReal32) iTvScreenSize.iHeight
+                / (TReal32) imageSize.iHeight;
+        }
+    else
+        {
+        scaleFactor = (TReal32) iTvScreenSize.iWidth
+                / (TReal32) imageSize.iWidth;
+        }
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - scaleFactor=%f",scaleFactor);
+    iTargetBitmapSize.iHeight = imageSize.iHeight * scaleFactor;
+    iTargetBitmapSize.iWidth = imageSize.iWidth * scaleFactor;
+	GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - targetBitmapSize=%d, %d",
+	        iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+    //create the bitmap for the required size
+    iDecodedBitmap[EJpgDecodedBitmapIndex] = new (ELeave) CFbsBitmap();
+    // to check if the Mimetype is supported by the decoder to to arbitary scaling
+    // if not then we recalculate the size
+    TInt err = iDecodedBitmap[EJpgDecodedBitmapIndex]->Create(ReCalculateSizeL(), EColor16MU);
+    User::LeaveIfNull(iDecodedBitmap[EJpgDecodedBitmapIndex]);
+    }
+
+// -----------------------------------------------------------------------------
+// DoesMimeTypeNeedsRecalculateL()
+// -----------------------------------------------------------------------------
+//
+TBool CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL");
+    RApaLsSession session;
+    TDataType mimeType;
+    TUid uid;
+    
+    User::LeaveIfError( session.Connect() );
+    CleanupClosePushL( session );
+    User::LeaveIfError( session.AppForDocument( iImagePath->Des(), uid, mimeType ) );
+    CleanupStack::PopAndDestroy(&session);
+    
+    if (mimeType.Des().Compare(KMimeJpeg)==0 ||
+            mimeType.Des().Compare(KMimeJpg)==0)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL - jpeg");
+        return EFalse;
+        }
+    else
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL - non jpeg");
+        return ETrue; 
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// ReCalculateSize 
+// -----------------------------------------------------------------------------
+TSize CGlxHdmiSurfaceUpdater::ReCalculateSizeL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ReCalculateSizeL()");
+    if(DoesMimeTypeNeedsRecalculateL())
+        {
+        iIsNonJpeg = ETrue;
+        TSize fullFrameSize = iImageDecoder->FrameInfo().iOverallSizeInPixels;
+        // calculate the reduction factor on what size we need
+        TInt reductionFactor = iImageDecoder->ReductionFactor(fullFrameSize, iTargetBitmapSize);
+        // get the reduced size onto destination size
+        TSize destSize;
+        User::LeaveIfError(iImageDecoder->ReducedSize(fullFrameSize, reductionFactor, destSize));
+        GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ReCalculateSizeL() - destSize=%d, %d",destSize.iWidth,destSize.iHeight);
+        return destSize;
+        }
+    else
+        {
+        return iTargetBitmapSize;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// HandleRunL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::HandleRunL(TRequestStatus& aStatus)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::HandleRunL()");
+
+#ifdef _DEBUG
+    iStopTime.HomeTime();
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::HandleRunL() ConvertImageL took"
+            " <%d> us", (TInt)iStopTime.MicroSecondsFrom(iStartTime).Int64());
+#endif
+    if(aStatus.Int() !=KErrNone)
+        {
+        GLX_LOG_INFO("HandleRunL - Convert failed");
+        ShiftToCloningMode();
+        }
+    else if(iSurfManager)
+        {        
+        iShwFsThumbnail = EFalse;
+        if (iIsNonJpeg)
+            {
+            // if this is non jpeg image, make sure we scale the bitmap
+            ScaleDecodedBitmapL(ENonJpgDecodedBitmapIndex);
+            }
+        ProcessTvImage();
+		iBitmapReady = ETrue;
+        }
+	//release imagedecoder after the conversion is over		
+    if(iImageDecoder)
+        {
+        delete iImageDecoder;
+        iImageDecoder = NULL;    
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CreateImageDecoderL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::CreateImageDecoderL()
+    {
+    TRACER("CGlxHdmiController::CreateImageDecoderL()");
+     // Create a decoder for the image in the named file
+    TRAPD(error,iImageDecoder = CImageDecoder::FileNewL(iFsSession, 
+            iImagePath->Des(), CImageDecoder::EOptionAlwaysThread, KNullUid));
+    GLX_LOG_INFO1("CreateImageDecoderL CImageDecoder:FileNewL error %d",error);
+    User::LeaveIfError(error);
+    }
+
+// -----------------------------------------------------------------------------
+// ActivateZoom 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ActivateZoom(TBool aAutoZoomOut)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ActivateZoom()");
+    iZoom = ETrue;
+    iAutoZoomOut = aAutoZoomOut;
+    if(iTimer->IsActive())
+        {
+		GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ActivateZoom() - Cancel Timer");
+        iTimer->Cancel();
+        }
+    
+    if(!iTimer->IsActive() && iBitmapReady)
+       {
+	   GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ActivateZoom() - Start Timer");
+       iTimer->Start(KZoomDelay,KZoomDelay,TCallBack( TimeOut,this ));
+       }
+    }
+
+// -----------------------------------------------------------------------------
+// DeactivateZoom 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::DeactivateZoom()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::DeactivateZoom()");
+    
+    if(iTimer->IsActive())
+        {
+		GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::DeactivateZoom() - Cancel Timer");
+        iTimer->Cancel();
+        }
+    if(!iTimer->IsActive() && iBitmapReady && iLeftCornerForZoom.iX)
+       {
+	   GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::DeactivateZoom() - Start Timer");
+	   iZoom = EFalse;
+       iTimer->Start(KZoomDelay,KZoomDelay,TCallBack( TimeOut,this ));
+       }
+    }
+
+// ---------------------------------------------------------------------------
+// TimeOut
+// ---------------------------------------------------------------------------
+//  
+TInt CGlxHdmiSurfaceUpdater::TimeOut(TAny* aSelf)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::TimeOut");
+    if(aSelf)
+        {
+        CGlxHdmiSurfaceUpdater* self = static_cast <CGlxHdmiSurfaceUpdater*> (aSelf);
+        if (self)
+            {            
+             self->Zoom(ETrue);
+            }
+        }
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// Zoom 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::Zoom(TBool aZoom)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::Zoom()");
+	
+	if(!iBitmapReady)
+		{
+		return;
+		}
+		
+    if(iLeftCornerForZoom.iX == KMaxZoomLimit)
+        {
+        iZoom = EFalse;
+        //If autozoomout is not set then cancel the timer and do
+        //the zoom out on DeactivateZoom.
+        if(!iAutoZoomOut)
+            {
+            iTimer->Cancel();			
+            }
+        }    
+    if(aZoom && iZoom)
+        {
+        iTargetBitmapSize.iWidth = TInt(iTargetBitmapSize.iWidth-KSingleStepForZoom);
+        iTargetBitmapSize.iHeight = TInt(iTargetBitmapSize.iHeight-KSingleStepForZoom);
+        iLeftCornerForZoom.iX =iLeftCornerForZoom.iX+KSingleStepForZoom/2;
+        iLeftCornerForZoom.iY =iLeftCornerForZoom.iY+KSingleStepForZoom/2;           
+        GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::Zoom()--- 2,iTargetBitmapSize.iWidth = %d, iTargetBitmapSize.iHeight = %d", iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+        iConfig.SetViewport(TRect(iLeftCornerForZoom.iX,iLeftCornerForZoom.iY,
+                iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight));
+        }
+    else
+        {
+        iTargetBitmapSize.iWidth = TInt(iTargetBitmapSize.iWidth+KSingleStepForZoom);
+        iTargetBitmapSize.iHeight = TInt(iTargetBitmapSize.iHeight+KSingleStepForZoom);
+        iLeftCornerForZoom.iX =iLeftCornerForZoom.iX-KSingleStepForZoom/2;
+        iLeftCornerForZoom.iY =iLeftCornerForZoom.iY-KSingleStepForZoom/2; 
+        if(iLeftCornerForZoom.iX == 0)
+            {
+            iTimer->Cancel();
+            iZoom = ETrue;
+            }
+        GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::Zoom()--- 4,iTargetBitmapSize.iWidth = %d, iTargetBitmapSize.iHeight = %d", iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+        iConfig.SetViewport(TRect(iLeftCornerForZoom.iX,iLeftCornerForZoom.iY,
+                iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight));
+        }
+    iWindow->SetBackgroundSurface(iConfig, ETrue);   
+    }
+
+// -----------------------------------------------------------------------------
+// ModifySurfacePostion 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ModifySurfacePostion()
+	{
+	TRACER("CGlxHdmiSurfaceUpdater::ModifySurfacePostion()");
+	TPoint startPoint(0,0);
+	if (iTargetBitmapSize.iWidth <iTvScreenSize.iWidth)
+	    {
+	    startPoint.iX = (iTvScreenSize.iWidth - iTargetBitmapSize.iWidth)/2; 
+	    }
+	if (iTargetBitmapSize.iHeight <iTvScreenSize.iHeight)
+	    {
+	    startPoint.iY = (iTvScreenSize.iHeight - iTargetBitmapSize.iHeight)/2;
+	    }
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - target iTargetBitmapSize=%d, %d",
+            iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - startPoint =%d, %d",
+            startPoint.iX,startPoint.iY);
+
+    // target
+    iConfig.SetExtent(TRect(startPoint.iX,startPoint.iY,(iTvScreenSize.iWidth-startPoint.iX),
+            (iTvScreenSize.iHeight-startPoint.iY)));
+    // source
+    iConfig.SetViewport(TRect(TPoint(0,0),TSize(iTargetBitmapSize.iWidth,
+            iTargetBitmapSize.iHeight)));
+#ifdef _DEBUG
+    TRect ex, vp;
+    iConfig.GetExtent(ex);
+    iConfig.GetViewport(vp);
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - vp - TL=%d, %d",vp.iTl.iX,vp.iTl.iY);
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - vp - BR=%d, %d",vp.iBr.iX,vp.iBr.iY);
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - ex - TL=%d, %d",ex.iTl.iX,ex.iTl.iY);
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ModifySurfacePostion() - ex - BR=%d, %d",ex.iBr.iX,ex.iBr.iY);
+#endif
+    }
+
+// -----------------------------------------------------------------------------
+// ShiftToCloningMode 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ShiftToCloningMode()
+	{
+	TRACER("CGlxHdmiSurfaceUpdater::ShiftToCloningMode()");
+	if (iAnimTimer)
+	    {
+	    GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ShiftToCloningMode() - cancel iAnimTimer");
+	    iAnimTimer->Cancel();
+	    delete iAnimTimer;
+	    iAnimTimer = NULL;
+	    }
+	if (ialfCompositionSurface)
+	    {
+	    GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ShiftToCloningMode() - deleteing ialfCompositionSurface");
+	    delete ialfCompositionSurface;
+	    ialfCompositionSurface= NULL;
+	    }
+    if (iWindow)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ShiftToCloningMode() - window present");
+        iWindow->RemoveBackgroundSurface(ETrue);
+        }
+	}
+	
+// -----------------------------------------------------------------------------
+// ShiftToPostingMode 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ShiftToPostingMode()
+	{
+	TRACER("CGlxHdmiSurfaceUpdater::ShiftToPostingMode()");
+    if (iEffectsOn && !iAnimTimer)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ShiftToPostingMode() Creating iAnimTimer");
+        iAnimTimer = CPeriodic::NewL( CActive::EPriorityStandard-1 );
+        }
+	if(iSurfManager)
+		{
+#ifdef _DEBUG
+		TRect ex, vp;
+		iConfig.GetExtent(ex);
+		iConfig.GetViewport(vp);
+		GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ShiftToPostingMode() - vp - TL=%d, %d",vp.iTl.iX,vp.iTl.iY);
+		GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ShiftToPostingMode() - vp - BR=%d, %d",vp.iBr.iX,vp.iBr.iY);
+		GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ShiftToPostingMode() - ex - TL=%d, %d",ex.iTl.iX,ex.iTl.iY);
+		GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ShiftToPostingMode() - ex - BR=%d, %d",ex.iBr.iX,ex.iBr.iY);
+#endif
+		iWindow->SetBackgroundSurface(iConfig, ETrue);
+		iShiftToCloning = EFalse;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// ShowFsThumbnailL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ShowFsThumbnailL()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ShowFsThumbnailL()");
+    iShwFsThumbnail = ETrue;
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ShowFsThumbnailL() iTargetBitmapSize Width=%d, Height=%d",
+            iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+    // Modify the surface position with respect to the buffer size 
+    ModifySurfacePostion();
+    // this is for FS thumbnail stored in array pointer 0
+    ScaleDecodedBitmapL(EFSBitmapIndex);
+    // Process the Image to TV
+    ProcessTvImage();
+    // set the surface onto background
+    iWindow->SetBackgroundSurface(iConfig, ETrue); 
+    if (iEffectsOn)
+        {
+        //Cancel the Animation timer if any
+        if(!iAnimTimer->IsActive())
+            {
+            iAnimCounter = 0;
+            GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ShowFsThumbnailL() - Cancel iAnimTimer Timer");
+            iAnimTimer->Cancel();
+            }
+
+        FadeTheSurface(ETrue);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// ScaleDecodedBitmapL 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ScaleDecodedBitmapL(TInt aBitmapIndex)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ScaleDecodedBitmapL()");
+    GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::ScaleDecodedBitmapL() iTargetBitmapSize Width=%d, Height=%d",
+            iTargetBitmapSize.iWidth,iTargetBitmapSize.iHeight);
+
+    if (iDecodedBitmap[aBitmapIndex])
+        {
+        delete iDecodedBitmap[aBitmapIndex];
+        iDecodedBitmap[aBitmapIndex] = NULL;
+        }
+    iDecodedBitmap[aBitmapIndex] = new (ELeave) CFbsBitmap();
+    // create destination with size
+    TInt err = iDecodedBitmap[aBitmapIndex]->Create(iTargetBitmapSize, EColor16MU);
+    GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ScaleDecodedBitmapL() creating bitmap error, err=%d",err);
+    User::LeaveIfNull(iDecodedBitmap[aBitmapIndex]);
+
+    // Create bitmap device for destination bitmap
+    CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(iDecodedBitmap[aBitmapIndex]);
+    CleanupStack::PushL(bitmapDevice);
+    
+    CFbsBitGc* bitmapGc = CFbsBitGc::NewL();
+    CleanupStack::PushL(bitmapGc);
+    bitmapGc->Activate(bitmapDevice);
+    if (aBitmapIndex==EFSBitmapIndex)
+        {
+        // scale the source bitmap which is a FS bitmap
+        bitmapGc->DrawBitmap(TRect(iTargetBitmapSize), iFsBitmap);
+        }
+    else
+        {
+        // scale the source bitmap which is a decoded bitmap
+        bitmapGc->DrawBitmap(TRect(iTargetBitmapSize), iDecodedBitmap[EJpgDecodedBitmapIndex]);
+        }
+    
+    CleanupStack::PopAndDestroy(bitmapGc);
+    CleanupStack::PopAndDestroy(bitmapDevice);
+
+    }
+
+// -----------------------------------------------------------------------------
+// ProcessTvImage 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::ProcessTvImage()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::ProcessTvImage()");
+    if (iSurfBufferAO->iStatus != KRequestPending
+            && !iSurfBufferAO->IsActive())
+        {
+        Refresh();
+        iSurfBufferAO->iStatus = KRequestPending;
+        iSurfBufferAO->SetActive();
+        iSurfUpdateSession.NotifyWhenAvailable(iSurfBufferAO->iStatus);
+        TInt err = iSurfUpdateSession.SubmitUpdate(KAllScreens, iSurfId, 0, NULL);
+        GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ProcessTvImage() Surfaceupdatesession error %d",err);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// FadeTheSurface 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::FadeTheSurface(TBool aFadeInOut)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::FadeTheSurface()");
+    iFadeIn = aFadeInOut;
+    if (iEffectsOn && !iAnimTimer)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::FadeTheSurface() Creating iAnimTimer");
+        iAnimTimer = CPeriodic::NewL( CActive::EPriorityStandard-1 );
+        }
+    if (!ialfCompositionSurface)
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::ShowFsThumbnailL() - Creating alfcompositionsurface");
+        ialfCompositionSurface = CAlfCompositionSource::NewL(*iWindow);
+        }
+    if(!iAnimTimer->IsActive())
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::FadeTheSurface() - Start Timer");
+        if (iFadeIn)
+            iAnimTimer->Start(0,KAnimationTickerFadeIn,TCallBack( AnimationTimeOut,this ));
+        else
+            {
+            for (TInt i=0;i<=KFadeSteps;i++)
+                {
+                GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::Animate - Fading Out %d",i);
+                ialfCompositionSurface->SetOpacity(KFullOpaque -(i*KFadeEachStep));
+                User::After(KAnimationTicker);
+                }
+            }
+        }
+    else
+        {
+        iAnimCounter = 0;
+        // this case can be when fast swipe in Slideshow
+        ialfCompositionSurface->SetOpacity(KFullOpaque);       // set the opacity to maximum when fast swipe
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::FadeTheSurface() - cancel iAnimTimer");
+        iAnimTimer->Cancel();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// AnimationTimeOut
+// ---------------------------------------------------------------------------
+//  
+TInt CGlxHdmiSurfaceUpdater::AnimationTimeOut(TAny* aSelf)
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::AnimationTimeOut");
+    if(aSelf)
+        {
+        CGlxHdmiSurfaceUpdater* self = static_cast <CGlxHdmiSurfaceUpdater*> (aSelf);
+        if (self)
+            {            
+            self->Animate();
+            }
+        }
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// Animate 
+// -----------------------------------------------------------------------------
+void CGlxHdmiSurfaceUpdater::Animate()
+    {
+    TRACER("CGlxHdmiSurfaceUpdater::Animate");
+    iAnimCounter++;
+    if (!ialfCompositionSurface)
+        {
+        // createing alfcompositiosource
+        ialfCompositionSurface = CAlfCompositionSource::NewL(*iWindow);
+        }
+    if (iAnimCounter <=KFadeSteps && iFadeIn)
+        {
+        GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::Animate - iAnimCounter=%d",iAnimCounter);
+        // gaining brightness
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::Animate - Fading In");
+        ialfCompositionSurface->SetOpacity( KFullTransparent +(iAnimCounter*KFadeEachStep));
+        }
+    else
+        {
+        GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::Animate() - cancel iAnimTimer");
+        iAnimCounter = 0;
+        // end the timer , as animation of fade in/out is complete
+        iAnimTimer->Cancel();
+        }
+    }
+