os/graphics/windowing/windowserver/nonnga/SERVER/offscreenbitmap.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200 (2012-06-15)
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "offscreenbitmap.h"
sl@0
    17
#include "inifile.h"
sl@0
    18
#include "panics.h"
sl@0
    19
#include "ScrDev.H"
sl@0
    20
#include "server.h"
sl@0
    21
#include "wstop.h"
sl@0
    22
#include "rootwin.h"
sl@0
    23
#if defined(__WINS__) && defined(_DEBUG)
sl@0
    24
#include "../../debuglog/osbwin.h"
sl@0
    25
#endif
sl@0
    26
sl@0
    27
GLREF_D TDisplayMode ParseDisplayMode(const TDesC& aModeName);
sl@0
    28
sl@0
    29
CWsOffScreenBitmap* CWsOffScreenBitmap::NewL(CScreen* aScreen)
sl@0
    30
	{
sl@0
    31
	CWsOffScreenBitmap* self=new(ELeave) CWsOffScreenBitmap(aScreen);
sl@0
    32
	CleanupStack::PushL(self);
sl@0
    33
	self->ConstructL();
sl@0
    34
	CleanupStack::Pop(self);
sl@0
    35
	return self;
sl@0
    36
	}
sl@0
    37
sl@0
    38
inline CWsOffScreenBitmap::CWsOffScreenBitmap(CScreen* aScreen) :iScreen(aScreen)
sl@0
    39
	{}
sl@0
    40
sl@0
    41
CWsOffScreenBitmap::~CWsOffScreenBitmap()
sl@0
    42
	{
sl@0
    43
	delete iBitmapGc;
sl@0
    44
	delete iBitmap;
sl@0
    45
	iObserver = NULL;
sl@0
    46
#if defined(__WINS__) && defined(_DEBUG)
sl@0
    47
	delete iOsbWin;
sl@0
    48
#endif
sl@0
    49
	delete iBitmapDevice;	
sl@0
    50
	}
sl@0
    51
sl@0
    52
template <class T> 
sl@0
    53
LOCAL_C inline void Swap(T& aLeft, T& aRight)
sl@0
    54
		{ T temp=aLeft;aLeft=aRight;aRight=temp;}
sl@0
    55
template <class T> 
sl@0
    56
LOCAL_C inline TBool SwapIfLeftIsBigger(T& aLeft, T& aRight)
sl@0
    57
		{if (aLeft>aRight) { ::Swap(aLeft, aRight); return (aRight>aLeft);} return (aLeft>aRight);}
sl@0
    58
sl@0
    59
void CWsOffScreenBitmap::ConstructL()
sl@0
    60
	{
sl@0
    61
	_LIT(KFlickerBufferMode,"FLICKERBUFFERMODE");
sl@0
    62
	TPtrC flickerBufferModeName;
sl@0
    63
	TDisplayMode displayMode = ENone;
sl@0
    64
	if (WsIniFile->FindVar(iScreen->ScreenNumber(), KFlickerBufferMode, flickerBufferModeName))
sl@0
    65
		displayMode = ParseDisplayMode(flickerBufferModeName);
sl@0
    66
	if (displayMode == ENone)
sl@0
    67
		displayMode = iScreen->DisplayMode();
sl@0
    68
	
sl@0
    69
	WS_ASSERT_DEBUG(displayMode!=ENone, EWsPanicNoDisplayModeFound);
sl@0
    70
	iBitmap=new(ELeave) CFbsBitmap;
sl@0
    71
	TSize screenSize=iScreen->ScreenDevice()->SizeInPixels();
sl@0
    72
	TBool haveSwapped=SwapIfLeftIsBigger(screenSize.iWidth, screenSize.iHeight);
sl@0
    73
	User::LeaveIfError(iBitmap->Create(screenSize,displayMode));
sl@0
    74
	if (haveSwapped)
sl@0
    75
		{
sl@0
    76
		iBitmap->SwapWidthAndHeight();
sl@0
    77
		}
sl@0
    78
	User::LeaveIfError(iBitmap->SetDisplayMode(iScreen->DisplayMode()));
sl@0
    79
	iBitmapDevice=CFbsBitmapDevice::NewL(iBitmap);
sl@0
    80
	User::LeaveIfError(iBitmapDevice->CreateContext(iBitmapGc));
sl@0
    81
	
sl@0
    82
	TSizeMode sizeMode = iScreen->ScreenSizeModeData(iScreen->ScreenSizeMode());
sl@0
    83
	TSize osbSize(iBitmap->SizeInPixels());
sl@0
    84
	TSize osbTwips(sizeMode.iScreenTwipsSize);
sl@0
    85
	if (osbSize!=sizeMode.iScreenSize)
sl@0
    86
		{
sl@0
    87
		// The specified screen twips size is for the specified screen pixel size, however the OSB
sl@0
    88
		// is potentially larger as it needs to hold the maximum possible screen size, so we need
sl@0
    89
		// to scale the twips size up correspondingly.
sl@0
    90
		osbTwips.iWidth=sizeMode.iScreenTwipsSize.iWidth*osbSize.iWidth/sizeMode.iScreenSize.iWidth;
sl@0
    91
		osbTwips.iHeight=sizeMode.iScreenTwipsSize.iHeight*osbSize.iHeight/sizeMode.iScreenSize.iHeight;
sl@0
    92
		}
sl@0
    93
	iBitmap->SetSizeInTwips(osbTwips);
sl@0
    94
	
sl@0
    95
#	if defined(__WINS__) && defined(_DEBUG)
sl@0
    96
	_LIT(KDebugOsb,"DEBUGOSB");
sl@0
    97
	if (WsIniFile->FindVar(iScreen->ScreenNumber(),KDebugOsb))
sl@0
    98
		{
sl@0
    99
		_LIT(KDebugOsbTitleFormat, "Screen %d, offscreen bitmap");
sl@0
   100
		TBuf<32> title;
sl@0
   101
		title.Format(KDebugOsbTitleFormat, iScreen->ScreenNumber());
sl@0
   102
		iOsbWin = CDebugOsbWin::NewL(title, iBitmap->SizeInPixels());
sl@0
   103
		}
sl@0
   104
#	endif
sl@0
   105
	}
sl@0
   106
sl@0
   107
TInt CWsOffScreenBitmap::DisplayModeChanged(TBool aSwapWidthAndHeight)
sl@0
   108
	{
sl@0
   109
	TInt err=KErrNone;
sl@0
   110
	if (aSwapWidthAndHeight)
sl@0
   111
		{
sl@0
   112
		err=iBitmapDevice->SwapWidthAndHeight();
sl@0
   113
		WS_ASSERT_DEBUG(err==KErrNone, EWsCreatedOffScreenBitmapInWrongDimensions);
sl@0
   114
		iBitmapGc->Activate(iBitmapDevice);
sl@0
   115
		}
sl@0
   116
	return err;
sl@0
   117
	}
sl@0
   118
sl@0
   119
void CWsOffScreenBitmap::SetObserver(MWsFlickerFreeBufferObserver* aObserver)
sl@0
   120
	{
sl@0
   121
	iObserver = aObserver;
sl@0
   122
	}
sl@0
   123
sl@0
   124
MWsFlickerFreeBufferObserver * CWsOffScreenBitmap::Observer()
sl@0
   125
	{
sl@0
   126
	return iObserver;
sl@0
   127
	}
sl@0
   128
sl@0
   129
CFbsBitmap* CWsOffScreenBitmap::Bitmap()
sl@0
   130
	{
sl@0
   131
	CFbsBitmap* bmp = iRedirectBuffer? iRedirectBuffer->GetBitmap() : iBitmap;
sl@0
   132
	WS_ASSERT_DEBUG(bmp!=NULL, EWsPanicTemp);
sl@0
   133
	return bmp;
sl@0
   134
	}
sl@0
   135
sl@0
   136
CFbsDevice* CWsOffScreenBitmap::BitmapDevice()
sl@0
   137
	{
sl@0
   138
	CFbsDevice* device = static_cast<CFbsDevice*>(GetBitGcCurrent()->Device());
sl@0
   139
	WS_ASSERT_DEBUG(device!=NULL, EWsPanicNullDeviceHandle);
sl@0
   140
	return device;
sl@0
   141
	}
sl@0
   142
sl@0
   143
// This function updates the OffScreenBitmap and TransparencyManager's device and GC
sl@0
   144
// Note: Here the OffScreenBitmap's scale is not considered.
sl@0
   145
void CWsOffScreenBitmap::UpdateGc(const TBool aSwapWidthAndHeight)
sl@0
   146
	{
sl@0
   147
	if (aSwapWidthAndHeight)
sl@0
   148
		{
sl@0
   149
		iBitmapDevice->SwapWidthAndHeight();
sl@0
   150
		}
sl@0
   151
	iBitmapDevice->SetScalingFactor(iScreen->CurrentScreenModeScaledOrigin(),1,1,1,1);
sl@0
   152
	iBitmapGc->Activate(iBitmapDevice);
sl@0
   153
	}
sl@0
   154
sl@0
   155
#if defined(__WINS__) && defined(_DEBUG)
sl@0
   156
void CWsOffScreenBitmap::Update()
sl@0
   157
	{
sl@0
   158
	if (iOsbWin)
sl@0
   159
		{
sl@0
   160
		iBitmap->LockHeap();
sl@0
   161
		iOsbWin->Refresh(iBitmap->SizeInPixels(), iBitmap->DisplayMode(), iBitmap->DataAddress());
sl@0
   162
		iBitmap->UnlockHeap();
sl@0
   163
		}
sl@0
   164
	}
sl@0
   165
#endif
sl@0
   166
sl@0
   167
/**
sl@0
   168
 Implementing MWsBackBuffer interface
sl@0
   169
*/
sl@0
   170
CFbsBitmap* CWsOffScreenBitmap::GetBitmap()
sl@0
   171
	{
sl@0
   172
	return iBitmap;
sl@0
   173
	}
sl@0
   174
sl@0
   175
CFbsBitGc* CWsOffScreenBitmap::GetBitGc()
sl@0
   176
	{
sl@0
   177
	return iBitmapGc;
sl@0
   178
	}
sl@0
   179
sl@0
   180
CFbsBitGc* CWsOffScreenBitmap::GetBitGcCurrent()
sl@0
   181
	{
sl@0
   182
	CFbsBitGc* gc = iRedirectGc? iRedirectGc : (iRedirectBuffer? iRedirectBuffer->GetBitGc() : iBitmapGc);
sl@0
   183
	WS_ASSERT_DEBUG(gc!=NULL, EWsPanicTemp);
sl@0
   184
	return gc;
sl@0
   185
	}
sl@0
   186
	
sl@0
   187
TInt CWsOffScreenBitmap::SetBitGc(CFbsBitGc* aBitGc)
sl@0
   188
	{
sl@0
   189
	if (iRedirectBuffer)
sl@0
   190
		return KErrInUse;
sl@0
   191
sl@0
   192
	if (aBitGc && (aBitGc==iBitmapGc || aBitGc==iRedirectGc))
sl@0
   193
		return KErrAlreadyExists;
sl@0
   194
	
sl@0
   195
	if (aBitGc && !aBitGc->Device())
sl@0
   196
		return KErrArgument;
sl@0
   197
	
sl@0
   198
	iRedirectGc = aBitGc;
sl@0
   199
	return KErrNone;
sl@0
   200
	}
sl@0
   201
sl@0
   202
TInt CWsOffScreenBitmap::RedirectTo(MWsBackBuffer* aTarget)
sl@0
   203
	{
sl@0
   204
	if (iRedirectGc)
sl@0
   205
		return KErrInUse;
sl@0
   206
sl@0
   207
	if (aTarget && aTarget==iRedirectBuffer)
sl@0
   208
		return KErrAlreadyExists;
sl@0
   209
	
sl@0
   210
	if ( aTarget && iScreen->HasVisibleDirectOnQueue() )
sl@0
   211
		return KErrInUse;	
sl@0
   212
	if (aTarget && 
sl@0
   213
			(
sl@0
   214
			!aTarget->GetBitmap()|| 
sl@0
   215
			!aTarget->GetBitGc() || 
sl@0
   216
			(aTarget->GetBitGc() && !aTarget->GetBitGc()->Device())
sl@0
   217
			)
sl@0
   218
		)
sl@0
   219
		return KErrArgument;
sl@0
   220
sl@0
   221
	iRedirectBuffer = aTarget;
sl@0
   222
	return KErrNone;
sl@0
   223
	}
sl@0
   224
sl@0
   225
TAny* CWsOffScreenBitmap::ResolveObjectInterface(TUint aTypeId)
sl@0
   226
	{
sl@0
   227
	switch (aTypeId)
sl@0
   228
		{
sl@0
   229
		case MWsBackBuffer::EWsObjectInterfaceId:
sl@0
   230
			return static_cast<MWsBackBuffer *>(this);
sl@0
   231
		}
sl@0
   232
	return NULL;
sl@0
   233
	}