windowing/windowserver/nonnga/SERVER/offscreenbitmap.cpp
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nonnga/SERVER/offscreenbitmap.cpp	Tue Feb 02 01:47:50 2010 +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 <class T> 
+LOCAL_C inline void Swap(T& aLeft, T& aRight)
+		{ T temp=aLeft;aLeft=aRight;aRight=temp;}
+template <class T> 
+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<CFbsDevice*>(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<MWsBackBuffer *>(this);
+		}
+	return NULL;
+	}