diff -r 000000000000 -r bde4ae8d615e os/graphics/windowing/windowserver/nonnga/SERVER/offscreenbitmap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/windowing/windowserver/nonnga/SERVER/offscreenbitmap.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,233 @@ +// Copyright (c) 2003-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 "offscreenbitmap.h" +#include "inifile.h" +#include "panics.h" +#include "ScrDev.H" +#include "server.h" +#include "wstop.h" +#include "rootwin.h" +#if defined(__WINS__) && defined(_DEBUG) +#include "../../debuglog/osbwin.h" +#endif + +GLREF_D TDisplayMode ParseDisplayMode(const TDesC& aModeName); + +CWsOffScreenBitmap* CWsOffScreenBitmap::NewL(CScreen* aScreen) + { + CWsOffScreenBitmap* self=new(ELeave) CWsOffScreenBitmap(aScreen); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +inline CWsOffScreenBitmap::CWsOffScreenBitmap(CScreen* aScreen) :iScreen(aScreen) + {} + +CWsOffScreenBitmap::~CWsOffScreenBitmap() + { + delete iBitmapGc; + delete iBitmap; + iObserver = NULL; +#if defined(__WINS__) && defined(_DEBUG) + delete iOsbWin; +#endif + delete iBitmapDevice; + } + +template +LOCAL_C inline void Swap(T& aLeft, T& aRight) + { T temp=aLeft;aLeft=aRight;aRight=temp;} +template +LOCAL_C inline TBool SwapIfLeftIsBigger(T& aLeft, T& aRight) + {if (aLeft>aRight) { ::Swap(aLeft, aRight); return (aRight>aLeft);} return (aLeft>aRight);} + +void CWsOffScreenBitmap::ConstructL() + { + _LIT(KFlickerBufferMode,"FLICKERBUFFERMODE"); + TPtrC flickerBufferModeName; + TDisplayMode displayMode = ENone; + if (WsIniFile->FindVar(iScreen->ScreenNumber(), KFlickerBufferMode, flickerBufferModeName)) + displayMode = ParseDisplayMode(flickerBufferModeName); + if (displayMode == ENone) + displayMode = iScreen->DisplayMode(); + + WS_ASSERT_DEBUG(displayMode!=ENone, EWsPanicNoDisplayModeFound); + iBitmap=new(ELeave) CFbsBitmap; + TSize screenSize=iScreen->ScreenDevice()->SizeInPixels(); + TBool haveSwapped=SwapIfLeftIsBigger(screenSize.iWidth, screenSize.iHeight); + User::LeaveIfError(iBitmap->Create(screenSize,displayMode)); + if (haveSwapped) + { + iBitmap->SwapWidthAndHeight(); + } + User::LeaveIfError(iBitmap->SetDisplayMode(iScreen->DisplayMode())); + iBitmapDevice=CFbsBitmapDevice::NewL(iBitmap); + User::LeaveIfError(iBitmapDevice->CreateContext(iBitmapGc)); + + TSizeMode sizeMode = iScreen->ScreenSizeModeData(iScreen->ScreenSizeMode()); + TSize osbSize(iBitmap->SizeInPixels()); + TSize osbTwips(sizeMode.iScreenTwipsSize); + if (osbSize!=sizeMode.iScreenSize) + { + // The specified screen twips size is for the specified screen pixel size, however the OSB + // is potentially larger as it needs to hold the maximum possible screen size, so we need + // to scale the twips size up correspondingly. + osbTwips.iWidth=sizeMode.iScreenTwipsSize.iWidth*osbSize.iWidth/sizeMode.iScreenSize.iWidth; + osbTwips.iHeight=sizeMode.iScreenTwipsSize.iHeight*osbSize.iHeight/sizeMode.iScreenSize.iHeight; + } + iBitmap->SetSizeInTwips(osbTwips); + +# if defined(__WINS__) && defined(_DEBUG) + _LIT(KDebugOsb,"DEBUGOSB"); + if (WsIniFile->FindVar(iScreen->ScreenNumber(),KDebugOsb)) + { + _LIT(KDebugOsbTitleFormat, "Screen %d, offscreen bitmap"); + TBuf<32> title; + title.Format(KDebugOsbTitleFormat, iScreen->ScreenNumber()); + iOsbWin = CDebugOsbWin::NewL(title, iBitmap->SizeInPixels()); + } +# endif + } + +TInt CWsOffScreenBitmap::DisplayModeChanged(TBool aSwapWidthAndHeight) + { + TInt err=KErrNone; + if (aSwapWidthAndHeight) + { + err=iBitmapDevice->SwapWidthAndHeight(); + WS_ASSERT_DEBUG(err==KErrNone, EWsCreatedOffScreenBitmapInWrongDimensions); + iBitmapGc->Activate(iBitmapDevice); + } + return err; + } + +void CWsOffScreenBitmap::SetObserver(MWsFlickerFreeBufferObserver* aObserver) + { + iObserver = aObserver; + } + +MWsFlickerFreeBufferObserver * CWsOffScreenBitmap::Observer() + { + return iObserver; + } + +CFbsBitmap* CWsOffScreenBitmap::Bitmap() + { + CFbsBitmap* bmp = iRedirectBuffer? iRedirectBuffer->GetBitmap() : iBitmap; + WS_ASSERT_DEBUG(bmp!=NULL, EWsPanicTemp); + return bmp; + } + +CFbsDevice* CWsOffScreenBitmap::BitmapDevice() + { + CFbsDevice* device = static_cast(GetBitGcCurrent()->Device()); + WS_ASSERT_DEBUG(device!=NULL, EWsPanicNullDeviceHandle); + return device; + } + +// This function updates the OffScreenBitmap and TransparencyManager's device and GC +// Note: Here the OffScreenBitmap's scale is not considered. +void CWsOffScreenBitmap::UpdateGc(const TBool aSwapWidthAndHeight) + { + if (aSwapWidthAndHeight) + { + iBitmapDevice->SwapWidthAndHeight(); + } + iBitmapDevice->SetScalingFactor(iScreen->CurrentScreenModeScaledOrigin(),1,1,1,1); + iBitmapGc->Activate(iBitmapDevice); + } + +#if defined(__WINS__) && defined(_DEBUG) +void CWsOffScreenBitmap::Update() + { + if (iOsbWin) + { + iBitmap->LockHeap(); + iOsbWin->Refresh(iBitmap->SizeInPixels(), iBitmap->DisplayMode(), iBitmap->DataAddress()); + iBitmap->UnlockHeap(); + } + } +#endif + +/** + Implementing MWsBackBuffer interface +*/ +CFbsBitmap* CWsOffScreenBitmap::GetBitmap() + { + return iBitmap; + } + +CFbsBitGc* CWsOffScreenBitmap::GetBitGc() + { + return iBitmapGc; + } + +CFbsBitGc* CWsOffScreenBitmap::GetBitGcCurrent() + { + CFbsBitGc* gc = iRedirectGc? iRedirectGc : (iRedirectBuffer? iRedirectBuffer->GetBitGc() : iBitmapGc); + WS_ASSERT_DEBUG(gc!=NULL, EWsPanicTemp); + return gc; + } + +TInt CWsOffScreenBitmap::SetBitGc(CFbsBitGc* aBitGc) + { + if (iRedirectBuffer) + return KErrInUse; + + if (aBitGc && (aBitGc==iBitmapGc || aBitGc==iRedirectGc)) + return KErrAlreadyExists; + + if (aBitGc && !aBitGc->Device()) + return KErrArgument; + + iRedirectGc = aBitGc; + return KErrNone; + } + +TInt CWsOffScreenBitmap::RedirectTo(MWsBackBuffer* aTarget) + { + if (iRedirectGc) + return KErrInUse; + + if (aTarget && aTarget==iRedirectBuffer) + return KErrAlreadyExists; + + if ( aTarget && iScreen->HasVisibleDirectOnQueue() ) + return KErrInUse; + if (aTarget && + ( + !aTarget->GetBitmap()|| + !aTarget->GetBitGc() || + (aTarget->GetBitGc() && !aTarget->GetBitGc()->Device()) + ) + ) + return KErrArgument; + + iRedirectBuffer = aTarget; + return KErrNone; + } + +TAny* CWsOffScreenBitmap::ResolveObjectInterface(TUint aTypeId) + { + switch (aTypeId) + { + case MWsBackBuffer::EWsObjectInterfaceId: + return static_cast(this); + } + return NULL; + }