diff -r 000000000000 -r 4e91876724a2 photosgallery/viewframework/tvout/src/glxhdmisurfaceupdater.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/photosgallery/viewframework/tvout/src/glxhdmisurfaceupdater.cpp Thu Dec 17 08:45:44 2009 +0200 @@ -0,0 +1,472 @@ +/* +* 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 +#include +#include +#include + +#include +#include +#include +#include + +#include "glxactivecallback.h" +#include "glxhdmisurfaceupdater.h" +#include "glxactivedecoder.h" + +// 720p image size +const TInt KHdTvWidth = 1280; +const TInt KHdTvHeight = 720; +const TInt KMulFactorToCreateBitmap = 4; +const TInt KZoomDelay = 10000; +//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; +// ----------------------------------------------------------------------------- +// NewLC +// ----------------------------------------------------------------------------- +CGlxHdmiSurfaceUpdater* CGlxHdmiSurfaceUpdater::NewL(RWindow* aWindow, const TDesC& aImageFile, + TSize aImageDimensions, TInt aFrameCount, MGlxGenCallback* aCallBack) + { + TRACER("CGlxHdmiSurfaceUpdater* CGlxHdmiSurfaceUpdater::NewL()"); + CGlxHdmiSurfaceUpdater* self = new (ELeave) CGlxHdmiSurfaceUpdater(aWindow, aImageFile, + aImageDimensions, aFrameCount, aCallBack); + CleanupStack::PushL(self); + self->ConstructL(aImageDimensions); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// destructor +// ----------------------------------------------------------------------------- +CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater() + { + TRACER("CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater()"); + ReleaseContent(); + if(iTimer->IsActive()) + { + iTimer->Cancel(); + } + delete iTimer; + if (iGlxDecoderAO) + { + delete iGlxDecoderAO; + } + iGlxDecoderAO = NULL; + iFsSession.Close(); + if (iSurfManager) + { + GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::~CGlxHdmiSurfaceUpdater() - Close"); + 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()"); + + iGlxDecoderAO->Cancel(); + if(iDecodedBitmap) + { + delete iDecodedBitmap; + iDecodedBitmap= NULL; + } + if (iSurfBufferAO->IsActive()) + { + iSurfBufferAO->Cancel(); + } + if(iImageDecoder) + { + delete iImageDecoder; + iImageDecoder = NULL; + } + iSurfUpdateSession.CancelAllUpdateNotifications(); + } + +// ----------------------------------------------------------------------------- +// CTor +// ----------------------------------------------------------------------------- +CGlxHdmiSurfaceUpdater::CGlxHdmiSurfaceUpdater(RWindow* aWindow, const TDesC& aImageFile, + TSize aOrigImageDimensions, TInt aFrameCount, MGlxGenCallback* aCallBack): + iWindow(aWindow), iImagePath(aImageFile), iOrigImageDimensions(aOrigImageDimensions), + iFrameCount(aFrameCount ),iCallBack(aCallBack) + { + TRACER("CGlxHdmiSurfaceUpdater::CGlxHdmiSurfaceUpdater()"); + // Implement nothing here + } + +// ----------------------------------------------------------------------------- +// ConstructL +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::ConstructL(TSize /*aImageDimensions*/) + { + TRACER("CGlxHdmiSurfaceUpdater::ConstructL()"); + TInt error = iFsSession.Connect (); + if ( KErrNone!= iFsSession.Connect () ) + { + User::LeaveIfError(error); + } + + // Create the active object + iGlxDecoderAO = CGlxHdmiDecoderAO::NewL(this, iFrameCount); + CreateImageDecoderL(iImagePath); + CreateBitmapL(); + CreateHdmiL(); + error = iSurfUpdateSession.Connect(); + #ifdef _DEBUG + iStartTime.HomeTime(); + #endif + //to refresh the HD screen for the first time. + iFirstTime = ETrue; + //start decoding the image + iGlxDecoderAO->ConvertImageL(*iDecodedBitmap,0,iImageDecoder); + + if (KErrNone !=error) + { + GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::ConstructL() Surface update Session Connect Failed with error = %d", error); + User::LeaveIfError(error); + } + iLeftCornerForZoom.iX = 0; + iLeftCornerForZoom.iY = 0; + iTimer = CPeriodic::NewL( CActive::EPriorityStandard ); + iZoom = ETrue; + } + +// ----------------------------------------------------------------------------- +// UpdateNewImageL +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::UpdateNewImageL(const TDesC& aImageFile, + TInt /*aFrameCount*/) + { + TRACER("CGlxHdmiSurfaceUpdater::UpdateNewImageL()"); + ReleaseContent(); + CreateImageDecoderL(aImageFile); + CreateBitmapL(); + CreateHdmiL(EFalse); + #ifdef _DEBUG + iStartTime.HomeTime(); + #endif + //start decoding the image + iGlxDecoderAO->ConvertImageL(*iDecodedBitmap,0,iImageDecoder); + } + +// ----------------------------------------------------------------------------- +// CreateHDMI +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::CreateHdmiL(TBool aCreateSurface) + { + TRACER("CGlxHdmiSurfaceUpdater::CreateHdmiL()"); + + if (aCreateSurface) + { + TSize rectSz = iDecodedBitmap->SizeInPixels(); // For animation + GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::CreateHdmiL() Size height = %d and width = %d", rectSz.iHeight, rectSz.iWidth); + CreateSurfaceL(rectSz); + } + + // Active objects for double buffered draw signalling + if(!iSurfBufferAO) + { + iSurfBufferAO = new(ELeave) CGlxActiveCallBack(TCallBack(SurfBuffer0Ready, this), + CActive::EPriorityStandard-1); + CActiveScheduler::Add(iSurfBufferAO); + } + + //Set the background Surface + iWindow->SetBackgroundSurface(iSurfId); + } + +// ----------------------------------------------------------------------------- +// CreateSurfaceL +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::CreateSurfaceL(TSize aSize) + { + TRACER("CGlxHdmiSurfaceUpdater::CreateSurfaceL()"); + + iSurfManager = new(ELeave) RSurfaceManager(); + TInt error = iSurfManager->Open(); + if (error != KErrNone) + { + GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::CreateSurfaceL Open Surface manager failed with error = %d", error); + User::LeaveIfError(error); + } + RSurfaceManager::TSurfaceCreationAttributesBuf attributes; + attributes().iPixelFormat = EUidPixelFormatARGB_8888;// EUidPixelFormatYUV_420Planar; + attributes().iSize = aSize; + + attributes().iBuffers = 1; + attributes().iStride = aSize.iWidth * KMulFactorToCreateBitmap; + attributes().iAlignment = KMulFactorToCreateBitmap; + attributes().iContiguous = EFalse; + attributes().iMappable = ETrue; + + error = iSurfManager->CreateSurface(attributes, iSurfId); + if(error) + { + GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::CreateSurfaceL, Creating surface failed with error : %d",error); + User::LeaveIfError(error); + } + //Map the surface and stire the surface info + 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); + if(error!=KErrNone) + { + GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::CreateSurfaceL(), MapSurface Failed wint error : %d",error); + } + + // Get the info from the surfaceManager + // and store pointers to the pixel data + RSurfaceManager::TInfoBuf info; + error = iSurfManager->SurfaceInfo(iSurfId, info); + iSurfaceStride = info().iStride; + User::LeaveIfError(error); + 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()"); + SwapBuffers(); + iCallBack->DoGenCallback(); + if(iFirstTime) + { + iFirstTime = EFalse; + iWindow->RemoveBackgroundSurface(ETrue); + iWindow->SetBackgroundSurface(iSurfId); + } + } + +// ----------------------------------------------------------------------------- +// 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()"); + + // Lock the heap so that subsequent call to dataaddress doesnt happen + iDecodedBitmap->LockHeap(); + + // Data stride + TUint fs = iDecodedBitmap->DataStride(); + + //Bitmap address from where the data has to be copied. + TUint8* from = (TUint8*)iDecodedBitmap->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->SizeInPixels().iWidth * KMulFactorToCreateBitmap; + + GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::SwapBuffers() - decodeSize width = %d and height %d", + iDecodedBitmap->SizeInPixels().iWidth, iDecodedBitmap->SizeInPixels().iHeight ); + + // Copy the bitmap on to the surface. + for (TInt y = iDecodedBitmap->SizeInPixels().iHeight; y >0; y--) + { + Mem::Copy(to, from, bytes); + to += ts; + from += fs; + } + iDecodedBitmap->UnlockHeap(); + } + +// ----------------------------------------------------------------------------- +// StartImageDecodeL +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::CreateBitmapL() + { + TRACER("CGlxHdmiSurfaceUpdater::StartImageDecodeL()"); + TSize decodeSize; + decodeSize.iHeight = (iOrigImageDimensions.iHeight>KHdTvHeight? KHdTvHeight: + iOrigImageDimensions.iHeight); + decodeSize.iWidth = (iOrigImageDimensions.iWidth>KHdTvWidth? KHdTvWidth: + iOrigImageDimensions.iWidth); + GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::StartImageDecodeL() - decodeSize width = %d and height %d", + decodeSize.iWidth, decodeSize.iHeight ); + + //create the bitmap for the required size + iDecodedBitmap = new(ELeave) CFbsBitmap(); + + TInt err = iDecodedBitmap->Create(decodeSize,EColor16MU ); + User::LeaveIfNull(iDecodedBitmap); + } + +// ----------------------------------------------------------------------------- +// HandleRunL +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::HandleRunL() + { + TRACER("CGlxHdmiSurfaceUpdater::HandleRunL()"); + + #ifdef _DEBUG + iStopTime.HomeTime(); + GLX_LOG_INFO1("CGlxHdmiSurfaceUpdater::HandleRunL() ConvertImageL took us %d us", + iStopTime.MicroSecondsFrom(iStartTime) ); + #endif + + iZoomRectSz = iDecodedBitmap->SizeInPixels(); + if (iSurfBufferAO->iStatus != KRequestPending && !iSurfBufferAO->IsActive()) + { + Refresh(); + iSurfBufferAO->iStatus = KRequestPending; + iSurfBufferAO->SetActive(); + iSurfUpdateSession.NotifyWhenAvailable(iSurfBufferAO->iStatus); + TInt err = iSurfUpdateSession.SubmitUpdate(1, iSurfId, 0, NULL); + } + } + +// ----------------------------------------------------------------------------- +// CreateImageDecoderL +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::CreateImageDecoderL(const TDesC& aImageFile) + { + TRACER("CGlxHdmiController::CreateImageDecoderL()"); + // Create a decoder for the image in the named file + TRAPD(error,iImageDecoder = CImageDecoder::FileNewL(iFsSession, + aImageFile, CImageDecoder::EOptionNone, KNullUid)); + if (error!=KErrNone) + { + User::Leave(error); + } + } +// ----------------------------------------------------------------------------- +// ActivateZoom +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::ActivateZoom() + { + TRACER("CGlxHdmiSurfaceUpdater::ActivateZoom()"); + iConfig.SetSurfaceId(iSurfId); + iZoom = ETrue; + if(!iTimer->IsActive()) + { + iTimer->Start(KZoomDelay,KZoomDelay,TCallBack( TimeOut,this )); + } + } +// ----------------------------------------------------------------------------- +// DeactivateZoom +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::DeactivateZoom() + { + TRACER("CGlxHdmiSurfaceUpdater::DeactivateZoom()"); + if(iDecodedBitmap) + { + TSize bitmapsize = iDecodedBitmap->SizeInPixels(); + iConfig.SetViewport(TRect(0,0,bitmapsize.iWidth,bitmapsize.iHeight)); + iConfig.SetExtent(TRect(0,0,bitmapsize.iWidth,bitmapsize.iHeight)); + iWindow->SetBackgroundSurface(iConfig, ETrue); + } + + } +// --------------------------------------------------------------------------- +// TimeOut +// --------------------------------------------------------------------------- +// +TInt CGlxHdmiSurfaceUpdater::TimeOut(TAny* aSelf) + { + TRACER("CGlxHdmiSurfaceUpdater::TimeOut"); + if(aSelf) + { + CGlxHdmiSurfaceUpdater* self = static_cast (aSelf); + if (self) + { + self->Zoom(ETrue); + } + } + return KErrNone; + } +// ----------------------------------------------------------------------------- +// Zoom +// ----------------------------------------------------------------------------- +void CGlxHdmiSurfaceUpdater::Zoom(TBool aZoom) + { + TRACER("CGlxHdmiSurfaceUpdater::Zoom()"); + if(iLeftCornerForZoom.iX == KMaxZoomLimit) + { + iZoom = EFalse; + } + if(aZoom && iZoom) + { + iZoomRectSz.iWidth = TInt(iZoomRectSz.iWidth-KSingleStepForZoom); + iZoomRectSz.iHeight = TInt(iZoomRectSz.iHeight-KSingleStepForZoom); + iLeftCornerForZoom.iX =iLeftCornerForZoom.iX+KSingleStepForZoom/2; + iLeftCornerForZoom.iY =iLeftCornerForZoom.iY+KSingleStepForZoom/2; + GLX_LOG_INFO2("CGlxHdmiSurfaceUpdater::Zoom()--- 2,iZoomRectSz.iWidth = %d, iZoomRectSz.iHeight = %d", iZoomRectSz.iWidth,iZoomRectSz.iHeight); + iConfig.SetViewport(TRect(iLeftCornerForZoom.iX,iLeftCornerForZoom.iY,iZoomRectSz.iWidth,iZoomRectSz.iHeight)); + } + else + { + iZoomRectSz.iWidth = TInt(iZoomRectSz.iWidth+KSingleStepForZoom); + iZoomRectSz.iHeight = TInt(iZoomRectSz.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,iZoomRectSz.iWidth = %d, iZoomRectSz.iHeight = %d", iZoomRectSz.iWidth,iZoomRectSz.iHeight); + iConfig.SetViewport(TRect(iLeftCornerForZoom.iX,iLeftCornerForZoom.iY,iZoomRectSz.iWidth,iZoomRectSz.iHeight)); + } + TSize bitmapsize = iDecodedBitmap->SizeInPixels(); + iConfig.SetExtent(TRect(0,0,bitmapsize.iWidth,bitmapsize.iHeight)); + iWindow->SetBackgroundSurface(iConfig, ETrue); + }